]>
Commit | Line | Data |
---|---|---|
f7a122fc BP |
1 | #! /bin/sh |
2 | ||
e0edde6f | 3 | # Copyright (c) 2011 Nicira, Inc. |
f7a122fc BP |
4 | # |
5 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | # you may not use this file except in compliance with the License. | |
7 | # You may obtain a copy of the License at: | |
8 | # | |
9 | # http://www.apache.org/licenses/LICENSE-2.0 | |
10 | # | |
11 | # Unless required by applicable law or agreed to in writing, software | |
12 | # distributed under the License is distributed on an "AS IS" BASIS, | |
13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | # See the License for the specific language governing permissions and | |
15 | # limitations under the License. | |
16 | ||
a4175433 GS |
17 | usage() { |
18 | UTIL=$(basename $0) | |
f7a122fc | 19 | cat <<EOF |
a4175433 GS |
20 | ${UTIL}: Provides helper functions to save Open vSwitch's configuration. |
21 | usage: $0 COMMAND | |
f7a122fc | 22 | |
a4175433 GS |
23 | Commands: |
24 | save-interfaces Outputs a shell script on stdout that will restore | |
25 | the current kernel configuration of the specified | |
26 | network interfaces, as well as the system iptables | |
27 | configuration. | |
28 | save-flows Outputs a shell script on stdout that will restore | |
29 | Openflow flows of each Open vSwitch bridge. | |
1eccfa36 GS |
30 | save-ofports Outputs a shell script on stdout that will restore |
31 | the ofport value across a force-reload-kmod. | |
a4175433 | 32 | This script is meant as a helper for the Open vSwitch init script commands. |
f7a122fc | 33 | EOF |
a4175433 | 34 | } |
f7a122fc BP |
35 | |
36 | PATH=/sbin:/bin:/usr/sbin:/usr/bin | |
37 | ||
38 | missing_program () { | |
39 | save_IFS=$IFS | |
40 | IFS=: | |
41 | for dir in $PATH; do | |
42 | IFS=$save_IFS | |
43 | if test -x $dir/$1; then | |
44 | return 1 | |
45 | fi | |
46 | done | |
47 | IFS=$save_IFS | |
48 | return 0 | |
49 | } | |
a4175433 GS |
50 | |
51 | save_interfaces () { | |
52 | if missing_program ip; then | |
53 | echo "$0: ip not found in $PATH" >&2 | |
54 | exit 1 | |
f7a122fc | 55 | fi |
a4175433 GS |
56 | |
57 | if test "$#" = 0; then | |
58 | exit 0 | |
f7a122fc BP |
59 | fi |
60 | ||
a4175433 GS |
61 | devs="$@" |
62 | for dev in $devs; do | |
63 | state=`ip link show dev $dev` || continue | |
64 | ||
65 | echo "# $dev" | |
66 | # Link state (Ethernet addresses, up/down, ...) | |
67 | linkcmd= | |
68 | case $state in | |
69 | *"state UP"* | *[,\<]"UP"[,\>]* ) | |
70 | linkcmd="$linkcmd up" | |
71 | ;; | |
72 | *"state DOWN"*) | |
73 | linkcmd="$linkcmd down" | |
74 | ;; | |
f7a122fc | 75 | esac |
a4175433 GS |
76 | if expr "$state" : '.*\bdynamic\b' > /dev/null; then |
77 | linkcmd="$linkcmd dynamic" | |
78 | fi | |
79 | if qlen=`expr "$state" : '.*qlen \([0-9]+\)'`; then | |
80 | linkcmd="$linkcmd txqueuelen $qlen" | |
81 | fi | |
82 | if hwaddr=`expr "$state" : '.*link/ether \([^ ]*\)'`; then | |
83 | linkcmd="$linkcmd address $hwaddr" | |
84 | fi | |
85 | if brd=`expr "$state" : '.*brd \([^ ]*\)'`; then | |
86 | linkcmd="$linkcmd broadcast $brd" | |
87 | fi | |
88 | if mtu=`expr "$state" : '.*mtu \([0-9]+\)'`; then | |
89 | linkcmd="$linkcmd mtu $mtu" | |
90 | fi | |
91 | if test -n "$linkcmd"; then | |
92 | echo ip link set dev $dev down # Required to change hwaddr. | |
93 | echo ip link set dev $dev $linkcmd | |
94 | fi | |
95 | ||
96 | # IP addresses (including IPv6). | |
97 | echo "ip addr flush dev $dev 2>/dev/null" # Suppresses "Nothing to flush". | |
98 | ip addr show dev $dev | while read addr; do | |
99 | set -- $addr | |
100 | ||
101 | # Check and trim family. | |
102 | family=$1 | |
103 | shift | |
104 | case $family in | |
105 | inet | inet6) ;; | |
106 | *) continue ;; | |
107 | esac | |
f7a122fc | 108 | |
a4175433 GS |
109 | # Trim device off the end--"ip" insists on having "dev" precede it. |
110 | addrcmd= | |
111 | while test $# != 0; do | |
112 | case $1 in | |
113 | dynamic) | |
114 | # Omit kernel-maintained route. | |
f7a122fc | 115 | continue 2 |
a4175433 GS |
116 | ;; |
117 | scope) | |
118 | if test "$2" = link; then | |
119 | # Omit route derived from IP address, e.g. | |
120 | # 172.16.0.0/16 derived from 172.16.12.34. | |
121 | continue 2 | |
122 | fi | |
123 | ;; | |
124 | "$dev"|"$dev:"*) | |
125 | # Address label string | |
126 | addrcmd="$addrcmd label $1" | |
127 | shift | |
128 | continue | |
129 | ;; | |
130 | esac | |
131 | addrcmd="$addrcmd $1" | |
132 | shift | |
133 | done | |
134 | if test "$1" != "$dev"; then | |
135 | addrcmd="$addrcmd $1" | |
136 | fi | |
137 | ||
138 | echo ip -f $family addr add $addrcmd dev $dev | |
139 | done | |
140 | ||
141 | # Routes. | |
142 | echo "ip route flush dev $dev proto boot 2>/dev/null" # Suppresses "Nothing to flush". | |
143 | ip route show dev $dev | while read route; do | |
144 | # "proto kernel" routes are installed by the kernel automatically. | |
145 | case $route in | |
146 | *" proto kernel "*) continue ;; | |
f7a122fc | 147 | esac |
a4175433 GS |
148 | |
149 | echo "ip route add $route dev $dev" | |
f7a122fc | 150 | done |
f7a122fc | 151 | |
a4175433 | 152 | echo |
f7a122fc BP |
153 | done |
154 | ||
a4175433 GS |
155 | if missing_program iptables-save; then |
156 | echo "# iptables-save not found in $PATH, not saving iptables state" | |
157 | else | |
158 | echo "# global" | |
159 | echo "iptables-restore <<'EOF'" | |
160 | iptables-save | |
161 | echo "EOF" | |
162 | fi | |
163 | } | |
164 | ||
165 | save_flows () { | |
166 | if missing_program ovs-ofctl; then | |
167 | echo "$0: ovs-ofctl not found in $PATH" >&2 | |
168 | exit 1 | |
169 | fi | |
f7a122fc | 170 | |
a4175433 GS |
171 | for bridge in "$@"; do |
172 | echo "ovs-ofctl add-flows ${bridge} - << EOF" | |
173 | ovs-ofctl dump-flows "${bridge}" | sed -e '/NXST_FLOW/d' \ | |
174 | -e 's/\(idle\|hard\)_age=[^,]*,//g' | |
175 | echo "EOF" | |
f7a122fc | 176 | done |
a4175433 | 177 | } |
f7a122fc | 178 | |
1eccfa36 GS |
179 | ovs_vsctl () { |
180 | ovs-vsctl --no-wait --timeout=1 "$@" | |
181 | } | |
182 | ||
183 | save_ofports () | |
184 | { | |
185 | if missing_program ovs-vsctl; then | |
186 | echo "$0: ovs-vsctl not found in $PATH" >&2 | |
187 | exit 1 | |
188 | fi | |
189 | ||
190 | for bridge in "$@"; do | |
191 | count=0 | |
192 | for iface in `ovs_vsctl list-ifaces ${bridge}`; do | |
193 | ofport=`ovs_vsctl get interface ${iface} ofport` | |
194 | [ "${count}" -eq 0 ] && cmd="ovs-vsctl --no-wait --timeout=1" | |
195 | cmd="${cmd} -- --if-exists set interface "${iface}" \ | |
196 | ofport_request="${ofport}"" | |
197 | ||
198 | # Run set interface command on 50 ports at a time. | |
199 | count=`expr ${count} + 1` | |
200 | [ "${count}" -eq 50 ] && count=0 && echo "${cmd}" && cmd="" | |
201 | done | |
202 | echo "${cmd}" | |
203 | done | |
204 | } | |
a4175433 GS |
205 | |
206 | while [ $# -ne 0 ] | |
207 | do | |
208 | case $1 in | |
a4175433 GS |
209 | "save-flows") |
210 | shift | |
211 | save_flows "$@" | |
212 | exit 0 | |
213 | ;; | |
214 | "save-interfaces") | |
215 | shift | |
216 | save_interfaces "$@" | |
217 | exit 0 | |
218 | ;; | |
1eccfa36 GS |
219 | "save-ofports") |
220 | shift | |
221 | save_ofports "$@" | |
222 | exit 0 | |
223 | ;; | |
a4175433 GS |
224 | -h | --help) |
225 | usage | |
226 | exit 0 | |
227 | ;; | |
228 | *) | |
229 | echo >&2 "$0: unknown command \"$1\" (use --help for help)" | |
230 | exit 1 | |
231 | ;; | |
232 | esac | |
233 | done | |
f7a122fc BP |
234 | |
235 | exit 0 |