ofp-print: Print bucket ids of OpenFlow 1.5 group messages.
[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_command_avail () {
17     while [ $# -ne 0 ]; do
18         if ("$1" --version) > /dev/null 2>&1; then :; else
19             echo >&2 "$UTIL: missing $1, cannot proceed"
20             exit 1
21         fi
22         shift
23     done
24 }
25
26 ovs_vsctl () {
27     ovs-vsctl --timeout=60 "$@"
28 }
29
30 create_netns_link () {
31     mkdir -p /var/run/netns
32     if [ ! -e /var/run/netns/"$PID" ]; then
33         ln -s /proc/"$PID"/ns/net /var/run/netns/"$PID"
34         trap 'delete_netns_link' 0
35         for signal in 1 2 3 13 14 15; do
36             trap 'delete_netns_link; trap - $signal; kill -$signal $$' $signal
37         done
38     fi
39 }
40
41 delete_netns_link () {
42     rm -f /var/run/netns/"$PID"
43 }
44
45 add_port () {
46     BRIDGE="$1"
47     INTERFACE="$2"
48     CONTAINER="$3"
49     ADDRESS="$4"
50
51     if [ "$#" -lt 3 ]; then
52         usage
53         exit 1
54     fi
55
56     if ovs_vsctl --may-exist add-br "$BRIDGE"; then :; else
57         echo >&2 "$UTIL: Failed to create bridge $BRIDGE"
58         exit 1
59     fi
60
61     if PID=`docker inspect -f '{{.State.Pid}}' "$CONTAINER"`; then :; else
62         echo >&2 "$UTIL: Failed to get the PID of the container"
63         exit 1
64     fi
65
66     create_netns_link
67
68     # Create a veth pair.
69     ID=`uuidgen | sed 's/-//g'`
70     PORTNAME="${ID:0:13}"
71     ip link add "${PORTNAME}_l" type veth peer name "${PORTNAME}_c"
72
73     # Add one end of veth to OVS bridge.
74     if ovs_vsctl --may-exist add-port "$BRIDGE" "${PORTNAME}_l" \
75        -- set interface "${PORTNAME}_l" \
76        external_ids:container_id="$CONTAINER" \
77        external_ids:container_iface="$INTERFACE"; then :; else
78         echo >&2 "$UTIL: Failed to add "${PORTNAME}_l" port to bridge $BRIDGE"
79         ip link delete "${PORTNAME}_l"
80         exit 1
81     fi
82
83     ip link set "${PORTNAME}_l" up
84
85     # Move "${PORTNAME}_c" inside the container and changes its name.
86     ip link set "${PORTNAME}_c" netns "$PID"
87     ip netns exec "$PID" ip link set dev "${PORTNAME}_c" name "$INTERFACE"
88     ip netns exec "$PID" ip link set "$INTERFACE" up
89
90     if [ -n "$ADDRESS" ]; then
91         ip netns exec "$PID" ip addr add "$ADDRESS" dev "$INTERFACE"
92     fi
93 }
94
95 del_port () {
96     BRIDGE="$1"
97     INTERFACE="$2"
98     CONTAINER="$3"
99
100     if [ "$#" -lt 3 ]; then
101         usage
102         exit 1
103     fi
104
105     PORT=`ovs_vsctl --data=bare --no-heading --columns=name find interface \
106              external_ids:container_id="$CONTAINER"  \
107              external_ids:container_iface="$INTERFACE"`
108     if [ -z "$PORT" ]; then
109         echo >&2 "$UTIL: Failed to find any attached port in $BRIDGE" \
110                  "for CONTAINER=$CONTAINER and INTERFACE=$INTERFACE"
111         exit 1
112     fi
113
114     ovs_vsctl --if-exists del-port "$PORT"
115
116     ip link delete "$PORT"
117 }
118
119 del_ports () {
120     BRIDGE="$1"
121     CONTAINER="$2"
122     if [ "$#" -lt 2 ]; then
123         usage
124         exit 1
125     fi
126
127     PORTS=`ovs_vsctl --data=bare --no-heading --columns=name find interface \
128              external_ids:container_id="$CONTAINER"`
129     if [ -z "$PORTS" ]; then
130         exit 0
131     fi
132
133     for PORT in $PORTS; do
134         ovs_vsctl --if-exists del-port "$PORT"
135         ip link delete "$PORT"
136     done
137 }
138
139 usage() {
140     cat << EOF
141 ${UTIL}: Performs integration of Open vSwitch with Docker.
142 usage: ${UTIL} COMMAND
143
144 Commands:
145   add-port BRIDGE INTERFACE CONTAINER [ADDRESS]
146                     Adds INTERFACE inside CONTAINER and connects it as a port
147                     in Open vSwitch BRIDGE. Optionally, sets ADDRESS on
148                     INTERFACE. ADDRESS can include a '/' to represent network
149                     prefix length. e.g.:
150                     ${UTIL} add-port br-int eth1 c474a0e2830e 192.168.1.2/24
151   del-port BRIDGE INTERFACE CONTAINER
152                     Deletes INTERFACE inside CONTAINER and removes its
153                     connection to Open vSwitch BRIDGE. e.g.:
154                     ${UTIL} del-port br-int eth1 c474a0e2830e
155   del-ports BRIDGE CONTAINER
156                     Removes all Open vSwitch interfaces from CONTAINER. e.g.:
157                     ${UTIL} del-ports br-int c474a0e2830e
158 Options:
159   -h, --help        display this help message.
160 EOF
161 }
162
163 UTIL=$(basename $0)
164 check_command_avail ovs-vsctl docker uuidgen
165
166 if (ip netns) > /dev/null 2>&1; then :; else
167     echo >&2 "$UTIL: ip utility not found (or it does not support netns),"\
168              "cannot proceed"
169     exit 1
170 fi
171
172 if [ $# -eq 0 ]; then
173     usage
174     exit 0
175 fi
176
177 case $1 in
178     "add-port")
179         shift
180         add_port "$@"
181         exit 0
182         ;;
183     "del-port")
184         shift
185         del_port "$@"
186         exit 0
187         ;;
188     "del-ports")
189         shift
190         del_ports "$@"
191         exit 0
192         ;;
193     -h | --help)
194         usage
195         exit 0
196         ;;
197     *)
198         echo >&2 "$UTIL: unknown command \"$1\" (use --help for help)"
199         exit 1
200         ;;
201 esac