2 # Copyright (C) 2014 Nicira, Inc.
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:
8 # http://www.apache.org/licenses/LICENSE-2.0
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.
16 # Check for programs we'll need.
22 if test -x "$dir/$1"; then
27 echo >&2 "$0: $1 not found in \$PATH, please install and try again"
32 ovs-vsctl
--timeout=60 "$@"
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
46 delete_netns_link
() {
47 rm -f /var
/run
/netns
/"$PID"
50 get_port_for_container_interface
() {
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"
69 if [ -z "$BRIDGE" ] ||
[ -z "$INTERFACE" ] ||
[ -z "$CONTAINER" ]; then
70 echo >&2 "$UTIL add-port: not enough arguments (use --help for help)"
75 while [ $# -ne 0 ]; do
78 ADDRESS
=`expr X"$1" : 'X[^=]*=\(.*\)'`
82 MACADDRESS
=`expr X"$1" : 'X[^=]*=\(.*\)'`
86 GATEWAY
=`expr X"$1" : 'X[^=]*=\(.*\)'`
90 MTU
=`expr X"$1" : 'X[^=]*=\(.*\)'`
94 echo >&2 "$UTIL add-port: unknown option \"$1\""
100 # Check if a port is already attached for the given container and interface
101 PORT
=`get_port_for_container_interface "$CONTAINER" "$INTERFACE" \
103 if [ -n "$PORT" ]; then
104 echo >&2 "$UTIL: Port already attached" \
105 "for CONTAINER=$CONTAINER and INTERFACE=$INTERFACE"
109 if ovs_vsctl br-exists
"$BRIDGE" || \
110 ovs_vsctl add-br
"$BRIDGE"; then :; else
111 echo >&2 "$UTIL: Failed to create bridge $BRIDGE"
115 if PID
=`docker inspect -f '{{.State.Pid}}' "$CONTAINER"`; then :; else
116 echo >&2 "$UTIL: Failed to get the PID of the container"
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"
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"
137 ip link
set "${PORTNAME}_l" up
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
144 if [ -n "$MTU" ]; then
145 ip netns
exec "$PID" ip link
set dev
"$INTERFACE" mtu
"$MTU"
148 if [ -n "$ADDRESS" ]; then
149 ip netns
exec "$PID" ip addr add
"$ADDRESS" dev
"$INTERFACE"
152 if [ -n "$MACADDRESS" ]; then
153 ip netns
exec "$PID" ip link
set dev
"$INTERFACE" address
"$MACADDRESS"
156 if [ -n "$GATEWAY" ]; then
157 ip netns
exec "$PID" ip route add default via
"$GATEWAY"
166 if [ "$#" -lt 3 ]; then
171 PORT
=`get_port_for_container_interface "$CONTAINER" "$INTERFACE"`
172 if [ -z "$PORT" ]; then
176 ovs_vsctl
--if-exists del-port
"$PORT"
178 ip link delete
"$PORT"
184 if [ "$#" -lt 2 ]; then
189 PORTS
=`ovs_vsctl --data=bare --no-heading --columns=name find interface \
190 external_ids:container_id="$CONTAINER"`
191 if [ -z "$PORTS" ]; then
195 for PORT
in $PORTS; do
196 ovs_vsctl
--if-exists del-port
"$PORT"
197 ip link delete
"$PORT"
207 if [ "$#" -lt 4 ]; then
212 PORT
=`get_port_for_container_interface "$CONTAINER_ID" "$INTERFACE"`
213 if [ -z "$PORT" ]; then
216 ovs_vsctl
set port
"$PORT" tag
="$VLAN"
221 ${UTIL}: Performs integration of Open vSwitch with Docker.
222 usage: ${UTIL} COMMAND
225 add-port BRIDGE INTERFACE CONTAINER [--ipaddress="ADDRESS"]
226 [--gateway=GATEWAY] [--macaddress="MACADDRESS"]
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
231 prefix length. Optionally, sets a GATEWAY, MACADDRESS
233 ${UTIL} add-port br-int eth1 c474a0e2830e
234 --ipaddress=192.168.1.2/24 --gateway=192.168.1.1
235 --macaddress="a2:c3:0d:49:7f:f8" --mtu=1450
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
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
248 -h, --help display this help message.
253 search_path ovs-vsctl
257 if (ip netns
) > /dev
/null
2>&1; then :; else
258 echo >&2 "$UTIL: ip utility not found (or it does not support netns),"\
263 if [ $# -eq 0 ]; then
294 echo >&2 "$UTIL: unknown command \"$1\" (use --help for help)"