]>
Commit | Line | Data |
---|---|---|
f7a122fc BP |
1 | #! /bin/sh |
2 | ||
fba6bd1d | 3 | # Copyright (c) 2011, 2013 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 | |
ea274df9 | 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 | 35 | |
a4175433 | 36 | save_interfaces () { |
4e4cdb43 | 37 | if (ip -V) > /dev/null 2>&1; then :; else |
a4175433 GS |
38 | echo "$0: ip not found in $PATH" >&2 |
39 | exit 1 | |
f7a122fc | 40 | fi |
a4175433 GS |
41 | |
42 | if test "$#" = 0; then | |
43 | exit 0 | |
f7a122fc BP |
44 | fi |
45 | ||
a4175433 GS |
46 | devs="$@" |
47 | for dev in $devs; do | |
48 | state=`ip link show dev $dev` || continue | |
49 | ||
50 | echo "# $dev" | |
51 | # Link state (Ethernet addresses, up/down, ...) | |
52 | linkcmd= | |
53 | case $state in | |
54 | *"state UP"* | *[,\<]"UP"[,\>]* ) | |
55 | linkcmd="$linkcmd up" | |
56 | ;; | |
57 | *"state DOWN"*) | |
58 | linkcmd="$linkcmd down" | |
59 | ;; | |
f7a122fc | 60 | esac |
a4175433 GS |
61 | if expr "$state" : '.*\bdynamic\b' > /dev/null; then |
62 | linkcmd="$linkcmd dynamic" | |
63 | fi | |
64 | if qlen=`expr "$state" : '.*qlen \([0-9]+\)'`; then | |
65 | linkcmd="$linkcmd txqueuelen $qlen" | |
66 | fi | |
67 | if hwaddr=`expr "$state" : '.*link/ether \([^ ]*\)'`; then | |
68 | linkcmd="$linkcmd address $hwaddr" | |
69 | fi | |
70 | if brd=`expr "$state" : '.*brd \([^ ]*\)'`; then | |
71 | linkcmd="$linkcmd broadcast $brd" | |
72 | fi | |
73 | if mtu=`expr "$state" : '.*mtu \([0-9]+\)'`; then | |
74 | linkcmd="$linkcmd mtu $mtu" | |
75 | fi | |
76 | if test -n "$linkcmd"; then | |
77 | echo ip link set dev $dev down # Required to change hwaddr. | |
78 | echo ip link set dev $dev $linkcmd | |
79 | fi | |
80 | ||
81 | # IP addresses (including IPv6). | |
82 | echo "ip addr flush dev $dev 2>/dev/null" # Suppresses "Nothing to flush". | |
83 | ip addr show dev $dev | while read addr; do | |
84 | set -- $addr | |
85 | ||
86 | # Check and trim family. | |
87 | family=$1 | |
88 | shift | |
89 | case $family in | |
90 | inet | inet6) ;; | |
91 | *) continue ;; | |
92 | esac | |
f7a122fc | 93 | |
a4175433 GS |
94 | # Trim device off the end--"ip" insists on having "dev" precede it. |
95 | addrcmd= | |
96 | while test $# != 0; do | |
97 | case $1 in | |
98 | dynamic) | |
99 | # Omit kernel-maintained route. | |
f7a122fc | 100 | continue 2 |
a4175433 GS |
101 | ;; |
102 | scope) | |
103 | if test "$2" = link; then | |
104 | # Omit route derived from IP address, e.g. | |
105 | # 172.16.0.0/16 derived from 172.16.12.34. | |
106 | continue 2 | |
107 | fi | |
108 | ;; | |
109 | "$dev"|"$dev:"*) | |
110 | # Address label string | |
111 | addrcmd="$addrcmd label $1" | |
112 | shift | |
113 | continue | |
114 | ;; | |
115 | esac | |
116 | addrcmd="$addrcmd $1" | |
117 | shift | |
118 | done | |
119 | if test "$1" != "$dev"; then | |
120 | addrcmd="$addrcmd $1" | |
121 | fi | |
122 | ||
123 | echo ip -f $family addr add $addrcmd dev $dev | |
124 | done | |
125 | ||
126 | # Routes. | |
127 | echo "ip route flush dev $dev proto boot 2>/dev/null" # Suppresses "Nothing to flush". | |
128 | ip route show dev $dev | while read route; do | |
129 | # "proto kernel" routes are installed by the kernel automatically. | |
130 | case $route in | |
131 | *" proto kernel "*) continue ;; | |
f7a122fc | 132 | esac |
a4175433 GS |
133 | |
134 | echo "ip route add $route dev $dev" | |
f7a122fc | 135 | done |
f7a122fc | 136 | |
a4175433 | 137 | echo |
f7a122fc BP |
138 | done |
139 | ||
4e4cdb43 | 140 | if (iptables-save) > /dev/null 2>&1; then |
a4175433 GS |
141 | echo "# global" |
142 | echo "iptables-restore <<'EOF'" | |
143 | iptables-save | |
144 | echo "EOF" | |
4e4cdb43 GS |
145 | else |
146 | echo "# iptables-save not found in $PATH, not saving iptables state" | |
a4175433 GS |
147 | fi |
148 | } | |
149 | ||
150 | save_flows () { | |
4e4cdb43 | 151 | if (ovs-ofctl --version) > /dev/null 2>&1; then :; else |
a4175433 GS |
152 | echo "$0: ovs-ofctl not found in $PATH" >&2 |
153 | exit 1 | |
154 | fi | |
f7a122fc | 155 | |
a4175433 GS |
156 | for bridge in "$@"; do |
157 | echo "ovs-ofctl add-flows ${bridge} - << EOF" | |
158 | ovs-ofctl dump-flows "${bridge}" | sed -e '/NXST_FLOW/d' \ | |
159 | -e 's/\(idle\|hard\)_age=[^,]*,//g' | |
160 | echo "EOF" | |
f7a122fc | 161 | done |
a4175433 | 162 | } |
f7a122fc | 163 | |
1eccfa36 | 164 | ovs_vsctl () { |
fba6bd1d | 165 | ovs-vsctl --no-wait "$@" |
1eccfa36 GS |
166 | } |
167 | ||
168 | save_ofports () | |
169 | { | |
4e4cdb43 | 170 | if (ovs-vsctl --version) > /dev/null 2>&1; then :; else |
1eccfa36 GS |
171 | echo "$0: ovs-vsctl not found in $PATH" >&2 |
172 | exit 1 | |
173 | fi | |
174 | ||
175 | for bridge in "$@"; do | |
176 | count=0 | |
177 | for iface in `ovs_vsctl list-ifaces ${bridge}`; do | |
178 | ofport=`ovs_vsctl get interface ${iface} ofport` | |
fba6bd1d | 179 | [ "${count}" -eq 0 ] && cmd="ovs-vsctl --no-wait" |
1eccfa36 GS |
180 | cmd="${cmd} -- --if-exists set interface "${iface}" \ |
181 | ofport_request="${ofport}"" | |
182 | ||
183 | # Run set interface command on 50 ports at a time. | |
184 | count=`expr ${count} + 1` | |
185 | [ "${count}" -eq 50 ] && count=0 && echo "${cmd}" && cmd="" | |
186 | done | |
187 | echo "${cmd}" | |
188 | done | |
189 | } | |
a4175433 GS |
190 | |
191 | while [ $# -ne 0 ] | |
192 | do | |
193 | case $1 in | |
a4175433 GS |
194 | "save-flows") |
195 | shift | |
196 | save_flows "$@" | |
197 | exit 0 | |
198 | ;; | |
199 | "save-interfaces") | |
200 | shift | |
201 | save_interfaces "$@" | |
202 | exit 0 | |
203 | ;; | |
1eccfa36 GS |
204 | "save-ofports") |
205 | shift | |
206 | save_ofports "$@" | |
207 | exit 0 | |
208 | ;; | |
a4175433 GS |
209 | -h | --help) |
210 | usage | |
211 | exit 0 | |
212 | ;; | |
213 | *) | |
214 | echo >&2 "$0: unknown command \"$1\" (use --help for help)" | |
215 | exit 1 | |
216 | ;; | |
217 | esac | |
218 | done | |
f7a122fc BP |
219 | |
220 | exit 0 |