datapath: Initialize unmasked key and uid len.
[cascardo/ovs.git] / utilities / ovs-docker
1 #!/bin/bash
2 # Copyright (C) 2014 Nicira, Inc.
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at:
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 # Check for programs we'll need.
17 search_path () {
18     save_IFS=$IFS
19     IFS=:
20     for dir in $PATH; do
21         IFS=$save_IFS
22         if test -x "$dir/$1"; then
23             return 0
24         fi
25     done
26     IFS=$save_IFS
27     echo >&2 "$0: $1 not found in \$PATH, please install and try again"
28     exit 1
29 }
30
31 ovs_vsctl () {
32     ovs-vsctl --timeout=60 "$@"
33 }
34
35 create_netns_link () {
36     mkdir -p /var/run/netns
37     if [ ! -e /var/run/netns/"$PID" ]; then
38         ln -s /proc/"$PID"/ns/net /var/run/netns/"$PID"
39         trap 'delete_netns_link' 0
40         for signal in 1 2 3 13 14 15; do
41             trap 'delete_netns_link; trap - $signal; kill -$signal $$' $signal
42         done
43     fi
44 }
45
46 delete_netns_link () {
47     rm -f /var/run/netns/"$PID"
48 }
49
50 get_port_for_container_interface () {
51     CONTAINER="$1"
52     INTERFACE="$2"
53
54     PORT=`ovs_vsctl --data=bare --no-heading --columns=name find interface \
55              external_ids:container_id="$CONTAINER"  \
56              external_ids:container_iface="$INTERFACE"`
57     if [ -z "$PORT" ]; then
58         echo >&2 "$UTIL: Failed to find any attached port" \
59                  "for CONTAINER=$CONTAINER and INTERFACE=$INTERFACE"
60     fi
61     echo "$PORT"
62 }
63
64 add_port () {
65     BRIDGE="$1"
66     INTERFACE="$2"
67     CONTAINER="$3"
68     ADDRESS="$4"
69     GATEWAY="$5"
70
71     if [ "$#" -lt 3 ]; then
72         usage
73         exit 1
74     fi
75
76     if ovs_vsctl br-exists "$BRIDGE" || \
77         ovs_vsctl add-br "$BRIDGE"; then :; else
78         echo >&2 "$UTIL: Failed to create bridge $BRIDGE"
79         exit 1
80     fi
81
82     if PID=`docker inspect -f '{{.State.Pid}}' "$CONTAINER"`; then :; else
83         echo >&2 "$UTIL: Failed to get the PID of the container"
84         exit 1
85     fi
86
87     create_netns_link
88
89     # Create a veth pair.
90     ID=`uuidgen | sed 's/-//g'`
91     PORTNAME="${ID:0:13}"
92     ip link add "${PORTNAME}_l" type veth peer name "${PORTNAME}_c"
93
94     # Add one end of veth to OVS bridge.
95     if ovs_vsctl --may-exist add-port "$BRIDGE" "${PORTNAME}_l" \
96        -- set interface "${PORTNAME}_l" \
97        external_ids:container_id="$CONTAINER" \
98        external_ids:container_iface="$INTERFACE"; then :; else
99         echo >&2 "$UTIL: Failed to add "${PORTNAME}_l" port to bridge $BRIDGE"
100         ip link delete "${PORTNAME}_l"
101         exit 1
102     fi
103
104     ip link set "${PORTNAME}_l" up
105
106     # Move "${PORTNAME}_c" inside the container and changes its name.
107     ip link set "${PORTNAME}_c" netns "$PID"
108     ip netns exec "$PID" ip link set dev "${PORTNAME}_c" name "$INTERFACE"
109     ip netns exec "$PID" ip link set "$INTERFACE" up
110
111     if [ -n "$ADDRESS" ]; then
112         ip netns exec "$PID" ip addr add "$ADDRESS" dev "$INTERFACE"
113     fi
114
115     if [ -n "$GATEWAY" ]; then
116         ip netns exec "$PID" ip route add default via "$GATEWAY"
117     fi
118 }
119
120 del_port () {
121     BRIDGE="$1"
122     INTERFACE="$2"
123     CONTAINER="$3"
124
125     if [ "$#" -lt 3 ]; then
126         usage
127         exit 1
128     fi
129
130     PORT=`get_port_for_container_interface "$CONTAINER" "$INTERFACE"`
131     if [ -z "$PORT" ]; then
132         exit 1
133     fi
134
135     ovs_vsctl --if-exists del-port "$PORT"
136
137     ip link delete "$PORT"
138 }
139
140 del_ports () {
141     BRIDGE="$1"
142     CONTAINER="$2"
143     if [ "$#" -lt 2 ]; then
144         usage
145         exit 1
146     fi
147
148     PORTS=`ovs_vsctl --data=bare --no-heading --columns=name find interface \
149              external_ids:container_id="$CONTAINER"`
150     if [ -z "$PORTS" ]; then
151         exit 0
152     fi
153
154     for PORT in $PORTS; do
155         ovs_vsctl --if-exists del-port "$PORT"
156         ip link delete "$PORT"
157     done
158 }
159
160 set_vlan () {
161     BRIDGE="$1"
162     INTERFACE="$2"
163     CONTAINER_ID="$3"
164     VLAN="$4"
165
166     if [ "$#" -lt 4 ]; then
167         usage
168         exit 1
169     fi
170
171     PORT=`get_port_for_container_interface "$CONTAINER_ID" "$INTERFACE"`
172     if [ -z "$PORT" ]; then
173         exit 1
174     fi
175     ovs_vsctl set port "$PORT" tag="$VLAN"
176 }
177
178 usage() {
179     cat << EOF
180 ${UTIL}: Performs integration of Open vSwitch with Docker.
181 usage: ${UTIL} COMMAND
182
183 Commands:
184   add-port BRIDGE INTERFACE CONTAINER [ADDRESS [GATEWAY]]
185                     Adds INTERFACE inside CONTAINER and connects it as a port
186                     in Open vSwitch BRIDGE. Optionally, sets ADDRESS on
187                     INTERFACE. ADDRESS can include a '/' to represent network
188                     prefix length. Along with ADDRESS, optionally set the
189                     default gateway for the container. e.g.:
190                     ${UTIL} add-port br-int eth1 c474a0e2830e 192.168.1.2/24 \
191                         192.168.1.1
192   del-port BRIDGE INTERFACE CONTAINER
193                     Deletes INTERFACE inside CONTAINER and removes its
194                     connection to Open vSwitch BRIDGE. e.g.:
195                     ${UTIL} del-port br-int eth1 c474a0e2830e
196   del-ports BRIDGE CONTAINER
197                     Removes all Open vSwitch interfaces from CONTAINER. e.g.:
198                     ${UTIL} del-ports br-int c474a0e2830e
199   set-vlan BRIDGE INTERFACE CONTAINER VLAN
200                     Configures the INTERFACE of CONTAINER attached to BRIDGE
201                     to become an access port of VLAN. e.g.:
202                     ${UTIL} set-vlan br-int eth1 c474a0e2830e 5
203 Options:
204   -h, --help        display this help message.
205 EOF
206 }
207
208 UTIL=$(basename $0)
209 search_path ovs-vsctl
210 search_path docker
211 search_path uuidgen
212
213 if (ip netns) > /dev/null 2>&1; then :; else
214     echo >&2 "$UTIL: ip utility not found (or it does not support netns),"\
215              "cannot proceed"
216     exit 1
217 fi
218
219 if [ $# -eq 0 ]; then
220     usage
221     exit 0
222 fi
223
224 case $1 in
225     "add-port")
226         shift
227         add_port "$@"
228         exit 0
229         ;;
230     "del-port")
231         shift
232         del_port "$@"
233         exit 0
234         ;;
235     "del-ports")
236         shift
237         del_ports "$@"
238         exit 0
239         ;;
240     "set-vlan")
241         shift
242         set_vlan "$@"
243         exit 0
244         ;;
245     -h | --help)
246         usage
247         exit 0
248         ;;
249     *)
250         echo >&2 "$UTIL: unknown command \"$1\" (use --help for help)"
251         exit 1
252         ;;
253 esac