]> git.proxmox.com Git - mirror_ovs.git/blame - utilities/ovs-docker
ovs-vsctl: Add datapath_type column to show command.
[mirror_ovs.git] / utilities / ovs-docker
CommitLineData
ec8f0f0c
GS
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
a8353802
GS
16# Check for programs we'll need.
17search_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
ec8f0f0c 24 fi
ec8f0f0c 25 done
a8353802
GS
26 IFS=$save_IFS
27 echo >&2 "$0: $1 not found in \$PATH, please install and try again"
28 exit 1
ec8f0f0c
GS
29}
30
31ovs_vsctl () {
32 ovs-vsctl --timeout=60 "$@"
33}
34
35create_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
46delete_netns_link () {
47 rm -f /var/run/netns/"$PID"
48}
49
348efd04
GS
50get_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
ec8f0f0c
GS
64add_port () {
65 BRIDGE="$1"
66 INTERFACE="$2"
67 CONTAINER="$3"
ec8f0f0c 68
05444f07
GS
69 if [ -z "$BRIDGE" ] || [ -z "$INTERFACE" ] || [ -z "$CONTAINER" ]; then
70 echo >&2 "$UTIL add-port: not enough arguments (use --help for help)"
ec8f0f0c
GS
71 exit 1
72 fi
73
05444f07
GS
74 shift 3
75 while [ $# -ne 0 ]; do
76 case $1 in
77 --ipaddress=*)
78 ADDRESS=`expr X"$1" : 'X[^=]*=\(.*\)'`
79 shift
80 ;;
81 --macaddress=*)
82 MACADDRESS=`expr X"$1" : 'X[^=]*=\(.*\)'`
83 shift
84 ;;
85 --gateway=*)
86 GATEWAY=`expr X"$1" : 'X[^=]*=\(.*\)'`
87 shift
88 ;;
6dd3cc39
GS
89 --mtu=*)
90 MTU=`expr X"$1" : 'X[^=]*=\(.*\)'`
91 shift
92 ;;
05444f07
GS
93 *)
94 echo >&2 "$UTIL add-port: unknown option \"$1\""
95 exit 1
96 ;;
97 esac
98 done
99
70934438
GM
100 # Check if a port is already attached for the given container and interface
101 PORT=`get_port_for_container_interface "$CONTAINER" "$INTERFACE" \
102 2>/dev/null`
103 if [ -n "$PORT" ]; then
104 echo >&2 "$UTIL: Port already attached" \
105 "for CONTAINER=$CONTAINER and INTERFACE=$INTERFACE"
106 exit 1
107 fi
108
8a856a63
PER
109 if ovs_vsctl br-exists "$BRIDGE" || \
110 ovs_vsctl add-br "$BRIDGE"; then :; else
ec8f0f0c
GS
111 echo >&2 "$UTIL: Failed to create bridge $BRIDGE"
112 exit 1
113 fi
114
115 if PID=`docker inspect -f '{{.State.Pid}}' "$CONTAINER"`; then :; else
116 echo >&2 "$UTIL: Failed to get the PID of the container"
117 exit 1
118 fi
119
120 create_netns_link
121
122 # Create a veth pair.
123 ID=`uuidgen | sed 's/-//g'`
124 PORTNAME="${ID:0:13}"
125 ip link add "${PORTNAME}_l" type veth peer name "${PORTNAME}_c"
126
127 # Add one end of veth to OVS bridge.
128 if ovs_vsctl --may-exist add-port "$BRIDGE" "${PORTNAME}_l" \
129 -- set interface "${PORTNAME}_l" \
130 external_ids:container_id="$CONTAINER" \
131 external_ids:container_iface="$INTERFACE"; then :; else
132 echo >&2 "$UTIL: Failed to add "${PORTNAME}_l" port to bridge $BRIDGE"
133 ip link delete "${PORTNAME}_l"
134 exit 1
135 fi
136
137 ip link set "${PORTNAME}_l" up
138
139 # Move "${PORTNAME}_c" inside the container and changes its name.
140 ip link set "${PORTNAME}_c" netns "$PID"
141 ip netns exec "$PID" ip link set dev "${PORTNAME}_c" name "$INTERFACE"
142 ip netns exec "$PID" ip link set "$INTERFACE" up
143
6dd3cc39
GS
144 if [ -n "$MTU" ]; then
145 ip netns exec "$PID" ip link set dev "$INTERFACE" mtu "$MTU"
146 fi
147
ec8f0f0c
GS
148 if [ -n "$ADDRESS" ]; then
149 ip netns exec "$PID" ip addr add "$ADDRESS" dev "$INTERFACE"
150 fi
a14bf25a 151
05444f07
GS
152 if [ -n "$MACADDRESS" ]; then
153 ip netns exec "$PID" ip link set dev "$INTERFACE" address "$MACADDRESS"
154 fi
155
a14bf25a
GS
156 if [ -n "$GATEWAY" ]; then
157 ip netns exec "$PID" ip route add default via "$GATEWAY"
158 fi
ec8f0f0c
GS
159}
160
161del_port () {
162 BRIDGE="$1"
163 INTERFACE="$2"
164 CONTAINER="$3"
165
166 if [ "$#" -lt 3 ]; then
167 usage
168 exit 1
169 fi
170
348efd04 171 PORT=`get_port_for_container_interface "$CONTAINER" "$INTERFACE"`
ec8f0f0c 172 if [ -z "$PORT" ]; then
ec8f0f0c
GS
173 exit 1
174 fi
175
176 ovs_vsctl --if-exists del-port "$PORT"
177
178 ip link delete "$PORT"
179}
180
181del_ports () {
182 BRIDGE="$1"
183 CONTAINER="$2"
184 if [ "$#" -lt 2 ]; then
185 usage
186 exit 1
187 fi
188
189 PORTS=`ovs_vsctl --data=bare --no-heading --columns=name find interface \
190 external_ids:container_id="$CONTAINER"`
191 if [ -z "$PORTS" ]; then
192 exit 0
193 fi
194
195 for PORT in $PORTS; do
196 ovs_vsctl --if-exists del-port "$PORT"
197 ip link delete "$PORT"
198 done
199}
200
348efd04
GS
201set_vlan () {
202 BRIDGE="$1"
203 INTERFACE="$2"
204 CONTAINER_ID="$3"
205 VLAN="$4"
206
207 if [ "$#" -lt 4 ]; then
208 usage
209 exit 1
210 fi
211
212 PORT=`get_port_for_container_interface "$CONTAINER_ID" "$INTERFACE"`
213 if [ -z "$PORT" ]; then
214 exit 1
215 fi
216 ovs_vsctl set port "$PORT" tag="$VLAN"
217}
218
ec8f0f0c
GS
219usage() {
220 cat << EOF
221${UTIL}: Performs integration of Open vSwitch with Docker.
222usage: ${UTIL} COMMAND
223
224Commands:
05444f07
GS
225 add-port BRIDGE INTERFACE CONTAINER [--ipaddress="ADDRESS"]
226 [--gateway=GATEWAY] [--macaddress="MACADDRESS"]
6dd3cc39 227 [--mtu=MTU]
ec8f0f0c
GS
228 Adds INTERFACE inside CONTAINER and connects it as a port
229 in Open vSwitch BRIDGE. Optionally, sets ADDRESS on
230 INTERFACE. ADDRESS can include a '/' to represent network
6dd3cc39
GS
231 prefix length. Optionally, sets a GATEWAY, MACADDRESS
232 and MTU. e.g.:
05444f07
GS
233 ${UTIL} add-port br-int eth1 c474a0e2830e
234 --ipaddress=192.168.1.2/24 --gateway=192.168.1.1
6dd3cc39 235 --macaddress="a2:c3:0d:49:7f:f8" --mtu=1450
ec8f0f0c
GS
236 del-port BRIDGE INTERFACE CONTAINER
237 Deletes INTERFACE inside CONTAINER and removes its
238 connection to Open vSwitch BRIDGE. e.g.:
239 ${UTIL} del-port br-int eth1 c474a0e2830e
240 del-ports BRIDGE CONTAINER
241 Removes all Open vSwitch interfaces from CONTAINER. e.g.:
242 ${UTIL} del-ports br-int c474a0e2830e
348efd04
GS
243 set-vlan BRIDGE INTERFACE CONTAINER VLAN
244 Configures the INTERFACE of CONTAINER attached to BRIDGE
245 to become an access port of VLAN. e.g.:
246 ${UTIL} set-vlan br-int eth1 c474a0e2830e 5
ec8f0f0c
GS
247Options:
248 -h, --help display this help message.
249EOF
250}
251
252UTIL=$(basename $0)
a8353802
GS
253search_path ovs-vsctl
254search_path docker
255search_path uuidgen
ec8f0f0c
GS
256
257if (ip netns) > /dev/null 2>&1; then :; else
258 echo >&2 "$UTIL: ip utility not found (or it does not support netns),"\
259 "cannot proceed"
260 exit 1
261fi
262
263if [ $# -eq 0 ]; then
264 usage
265 exit 0
266fi
267
268case $1 in
269 "add-port")
270 shift
271 add_port "$@"
272 exit 0
273 ;;
274 "del-port")
275 shift
276 del_port "$@"
277 exit 0
278 ;;
279 "del-ports")
280 shift
281 del_ports "$@"
282 exit 0
283 ;;
348efd04
GS
284 "set-vlan")
285 shift
286 set_vlan "$@"
287 exit 0
288 ;;
ec8f0f0c
GS
289 -h | --help)
290 usage
291 exit 0
292 ;;
293 *)
294 echo >&2 "$UTIL: unknown command \"$1\" (use --help for help)"
295 exit 1
296 ;;
297esac