写个脚本列出neutron的ovs的topology。

运行结果如下:

 $ ./nova-ifinfo  a7026868-407c-4c54-bb8f-a68623d7e13f
vm name is: instance-00000035    # 查找VM的名字
qemu pid is: 43146, iface host fd: 28, iface fd: 26, iface MAC: fa:16:3e:3f:ae:50

# 查找VM的tap设备的fd,通过fd找到对应的bridge。
************************************************
VM:instance-00000035 ---> tap: tap4ab104d3-5f ---> bridge: qbr4ab104d3-5f
************************************************
# 遍历VM的bridge。
************************************************
bridge: qbr4ab104d3-5f
           |__ qvb4ab104d3-5f
           |__ tap4ab104d3-5f
************************************************
# 找到VM的bridge的veth设备,通过veth设备,找到对端接在哪个bridge上。
************************************************
bridge: qbr4ab104d3-5f                                  bridge: br-int
           |__ veth: qvb4ab104d3-5f <----> veth: qvo4ab104d3-5f __|
************************************************
# 接续查找该bridge接到了哪里。
************************************************
bridge: br-int                                   bridge: br-tun
           |__ veth: patch-tun <----> veth: patch-int __|

bridge: br-int                                   bridge: br-ex
           |__ veth: int-br-ex <----> veth: phy-br-ex __|

************************************************



内容如下:

$ cat nova-ifinfo

精简版

  1 #!/bin/bash
  2 ST=`nova hypervisor-servers $HOSTNAME | grep $1`
  3 if [[ $? != 0 ]] ; then
  4     echo "not find $1 on $HOSTNAME"
  5     nova hypervisor-servers $HOSTNAME
  6     exit 1
  7 fi
  8 
  9 ST=`nova show $1`
 10 if [[ $? != 0 ]] ; then
 11     nova list
 12     exit 1
 13 fi
 14 
 15 QEMU_NAME=`nova show $1 |grep "OS-EXT-SRV-ATTR:instance_name" | awk '{print $4}'`
 16 if [[ $? != 0 ]] ; then
 17     exit 1
 18 fi
 19 
 20 ST=`sudo virsh domstate $1`
 21 if [[ $? != 0 ]] ; then
 22     exit 1
 23 fi
 24 if [[ "$ST" =~ "shut off" ]] ; then
 25     sudo virsh list --all
 26     echo "$QEMU_NAME is shut off"
 27     exit 1
 28 fi
 29 echo "vm name is: $QEMU_NAME"
 30 
 31 QEMU_CMD=`ps -ef |grep " $QEMU_NAME " |grep -v grep`
 32 # echo $QEMU_CMD
 33 QEMU_PID=`cut -d " " -f2 <<< $QEMU_CMD`
 34 CMD_IFS=""
 35 IF_FD=""
 36 HOST_FD=""
 37 [[ "$QEMU_CMD" =~ "-netdev" ]] && CMD_IFS=${QEMU_CMD#*-netdev}
 38 [[ "$QEMU_CMD" =~ "tap,fd=" ]] && CMD_IFS=${CMD_IFS#*tap,fd=} && IF_FD=${CMD_IFS%%,*}
 39 [[ "$QEMU_CMD" =~ "vhostfd=" ]] && CMD_IFS=${CMD_IFS#*vhostfd=} && HOST_FD=${CMD_IFS%% *}
 40 [[ "$QEMU_CMD" =~ "mac=" ]] && CMD_MAC=${QEMU_CMD#*mac=} && CMD_MAC=${CMD_MAC%%,*}
 41 
 42 echo "qemu pid is: $QEMU_PID, iface host fd: $HOST_FD, iface fd: $IF_FD, iface MAC: $CMD_MAC"
 43 
 44 # egrep -l iff:.*tap* /proc/*/fdinfo/* 2>/dev/null|cut -d/ -f3
 45 TAPNAME=`sudo cat /proc/$QEMU_PID/fdinfo/$IF_FD | grep "iff:.*tap*"`
 46 TAPNAME=${TAPNAME#iff:[[:space:]]*}
 47 # TAPNAME="${TAPNAME##[[:space:]]}"
 48 # TAPNAME="${TAPNAME//[[:space:]]/}"
 49 
 50 # kernel version less than 3.14
 51 if [[ -z $TAPNAME ]];  then
 52 TAPNAME=`ifconfig |grep ${CMD_MAC:2}`
 53 TAPNAME="${TAPNAME%%[[:space:]]*}"
 54 fi
 55 
 56 BR=`ls -l /sys/class/net/$TAPNAME/brport/bridge`
 57 BR=${BR##*/}
 58 # BR=""
 59 # for br in `ls /sys/class/net/`; do
 60 #     if [[ -d "/sys/class/net/$br/bridge"  && -d  "/sys/class/net/$br/lower_$TAPNAME" ]]; then
 61 #         BR=$br     
 62 #         break
 63 #     fi   
 64 # done
 65 
 66 echo ""
 67 echo "************************************************"
 68 echo "VM:$QEMU_NAME ---> tap: $TAPNAME ---> bridge: $BR"
 69 echo "************************************************"
 70 
 71 echo ""
 72 echo "************************************************"
 73 echo "bridge: $BR"
 74 for port in `ls /sys/class/net/$BR/brif/`; do
 75     echo "           |__ $port"
 76 done
 77 echo "************************************************"
 78 
 79 # BR_PORT="qvb${BR:3}"
 80 # OVS_PORT="qvo${BR_PORT:3}"
 81 OVS_BR_INT=""
 82 echo ""
 83 echo "************************************************"
 84 for port in `ls /sys/class/net/$BR/brif/`; do
 85     PORT_TY=`ethtool -i $port | grep "driver:" |awk '{print $2}'`
 86     if [[ $PORT_TY == "veth" ]] ; then
 87         PEER_INDEX=`ethtool -S $port | grep "peer_ifindex:" |awk '{print $2}'`
 88         for peer in `ls /sys/class/net/`; do
 89             INDEX=`cat /sys/class/net/$peer/ifindex`
 90             if [[ $PEER_INDEX == $INDEX ]]; then
 91                 if [[ -d /sys/class/net/$OVS_PORT/brport/bridge ]]; then
 92                     OVS_BR_INT=`ls /sys/class/net/$OVS_PORT/brport/bridge -l`
 93                     OVS_BR_INT=${OVS_BR_INT##*/}
 94                 else
 95                     OVS_BR_INT=`sudo ovs-vsctl port-to-br $peer`
 96                     # OVS_BR_INT=`sudo ovs-vsctl iface-to-br $peer`
 97                 fi
 98                 echo "bridge: $BR                                  bridge: $OVS_BR_INT"
 99                 echo "           |__ patch: $port <----> patch: $peer __|"
100             fi
101         done
102     fi
103 done
104 echo "************************************************"
105 
106 IS_OVS=`sudo ovs-vsctl list-br | grep $OVS_BR_INT`
107 OVS_INFOS=`sudo ovs-vsctl show |tr "\n" " "`
108 ALL=""
109 
110 echo ""
111 echo "************************************************"
112 while [[ "$OVS_INFOS" =~ "{peer=" ]]
113 do
114     PORT=${OVS_INFOS%%\}*}
115     PORT=${PORT%[[:space:]]*type*}
116     PORT=${PORT##*Interface}
117     PORT=`echo $PORT`
118     PEER=${OVS_INFOS#*\{peer=}
119     PEER=${PEER%%\}*}
120     OVS_INFOS=${OVS_INFOS#*\{peer=*\}}
121     if [[ ! "$ALL" =~ "$PORT" ]]
122     then
123         ALL="$ALL $PORT $PEER"
124         PEER_BR=`sudo ovs-vsctl iface-to-br $PORT`
125         BR=`sudo ovs-vsctl iface-to-br $PEER`
126         echo "bridge: $BR                                   bridge: $PEER_BR"
127         echo "           |__ veth: $PEER <----> veth: $PORT __|"
128         echo ""
129     else
130         continue
131     fi
132 done
133 echo "************************************************"
134 
135 # for port in `sudo ovs-vsctl show |grep "options: {peer=" |cut -d "=" -f2`
136 # do
137 #     port=${port%%\}*}
138 #     THIS_BR=`sudo ovs-vsctl iface-to-br $port`
139 #     if [[ $THIS_BR == $OVS_BR_INT ]]; then
140 #          
141 #         echo "bridge: $THIS_BR                             bridge: $PEER_BR"
142 #         echo "           |__ veth: $port <----> veth: $peer __|"
143 #      
144 #     fi
145 # done
View Code

 

  1 #!/bin/bash
  2 ST=`nova hypervisor-servers $HOSTNAME | grep $1`
  3 if [[ $? != 0 ]] ; then
  4     echo "not find $1 on $HOSTNAME"
  5     nova hypervisor-servers $HOSTNAME
  6     exit 1
  7 fi
  8 
  9 ST=`nova show $1`
 10 if [[ $? != 0 ]] ; then
 11     nova list
 12     exit 1
 13 fi
 14 
 15 QEMU_NAME=`nova show $1 |grep "OS-EXT-SRV-ATTR:instance_name" | awk '{print $4}'`
 16 if [[ $? != 0 ]] ; then
 17     exit 1
 18 fi
 19 
 20 ST=`sudo virsh domstate $1`
 21 if [[ $? != 0 ]] ; then
 22     exit 1
 23 fi
 24 if [[ "$ST" =~ "shut off" ]] ; then
 25     sudo virsh list --all
 26     echo "$QEMU_NAME is shut off"
 27     exit 1
 28 fi
 29 echo ""
 30 echo "vm name is: $QEMU_NAME"
 31 
 32 QEMU_CMD=`ps -ef |grep " $QEMU_NAME " |grep -v grep`
 33 # echo $QEMU_CMD
 34 QEMU_PID=`cut -d " " -f2 <<< $QEMU_CMD`
 35 CMD_IFS=""
 36 IF_FD=""
 37 HOST_FD=""
 38 [[ "$QEMU_CMD" =~ "-netdev" ]] && CMD_IFS=${QEMU_CMD#*-netdev}
 39 [[ "$QEMU_CMD" =~ "tap,fd=" ]] && CMD_IFS=${CMD_IFS#*tap,fd=} && IF_FD=${CMD_IFS%%,*}
 40 [[ "$QEMU_CMD" =~ "vhostfd=" ]] && CMD_IFS=${CMD_IFS#*vhostfd=} && HOST_FD=${CMD_IFS%% *}
 41 [[ "$QEMU_CMD" =~ "mac=" ]] && CMD_MAC=${QEMU_CMD#*mac=} && CMD_MAC=${CMD_MAC%%,*}
 42 
 43 echo "qemu pid is: $QEMU_PID, iface host fd: $HOST_FD, iface fd: $IF_FD, iface MAC: $CMD_MAC"
 44 
 45 FLOATING_IP=`nova floating-ip-list |grep $1`
 46 FIX_IP=`awk '{print $8}' <<< $FLOATING_IP`
 47 FLOATING_IP=`awk '{print $4}' <<< $FLOATING_IP`
 48 NETINFO=`nova show $1 |grep "network  *|"`
 49 NETINFO=="${NETINFO##network[[:space:]]*|}"
 50 NET_NAME="${NETINFO%[[:space:]]*network*}"
 51 NET_NAME="${NET_NAME#*[[:space:]]*}"
 52 NET_ID=`nova network-show $NET_NAME |grep "| *id *|" |awk '{print $4}'`
 53 echo " fix ip is: $FIX_IP, floating ip is: $FLOATING_IP"
 54 echo "network id is: $NET_ID" 
 55 echo "and info please run: sudo ip netns exec qdhcp-$NET_ID"
 56 # echo `cat /opt/stack/data/neutron/dhcp/$NET_ID/opts |grep "router"`
 57 
 58 # egrep -l iff:.*tap* /proc/*/fdinfo/* 2>/dev/null|cut -d/ -f3
 59 TAPNAME=`sudo cat /proc/$QEMU_PID/fdinfo/$IF_FD | grep "iff:.*tap*"`
 60 TAPNAME=${TAPNAME#iff:[[:space:]]*}
 61 # TAPNAME="${TAPNAME##[[:space:]]}"
 62 # TAPNAME="${TAPNAME//[[:space:]]/}"
 63 
 64 # kernel version less than 3.14
 65 if [[ -z $TAPNAME ]];  then
 66 TAPNAME=`ifconfig |grep ${CMD_MAC:2}`
 67 TAPNAME="${TAPNAME%%[[:space:]]*}"
 68 fi
 69 
 70 BR=`ls -l /sys/class/net/$TAPNAME/brport/bridge`
 71 BR=${BR##*/}
 72 # BR=""
 73 # for br in `ls /sys/class/net/`; do
 74 #     if [[ -d "/sys/class/net/$br/bridge"  && -d  "/sys/class/net/$br/lower_$TAPNAME" ]]; then
 75 #         BR=$br     
 76 #         break
 77 #     fi   
 78 # done
 79 
 80 echo ""
 81 echo "================================================================================"
 82 echo "The follow are L2 info:"
 83 echo "************************************************"
 84 echo "VM:$QEMU_NAME ---> tap: $TAPNAME ---> bridge: $BR"
 85 echo "************************************************"
 86 
 87 echo ""
 88 echo "************************************************"
 89 echo "bridge: $BR"
 90 for port in `ls /sys/class/net/$BR/brif/`; do
 91     echo "           |__ port: $port"
 92 done
 93 echo "************************************************"
 94 
 95 # BR_PORT="qvb${BR:3}"
 96 # OVS_PORT="qvo${BR_PORT:3}"
 97 function br_connetion_brs_by_veth()
 98 {
 99     echo ""
100     echo "************************************************"
101     OVS_BR_INT=""
102     BR=$1
103     for port in `ls /sys/class/net/$BR/brif/`; do
104         PORT_TY=`ethtool -i $port | grep "driver:" |awk '{print $2}'`
105         if [[ $PORT_TY == "veth" ]] ; then
106             PEER_INDEX=`ethtool -S $port | grep "peer_ifindex:" |awk '{print $2}'`
107             for peer in `ls /sys/class/net/`; do
108                 INDEX=`cat /sys/class/net/$peer/ifindex`
109                 BR_TYPE="linux_br"
110                 if [[ $PEER_INDEX == $INDEX ]]; then
111                     if [[ -d /sys/class/net/$OVS_PORT/brport/bridge ]]; then
112                         BR_TYPE="linux_br"
113                         OVS_BR_INT=`ls /sys/class/net/$OVS_PORT/brport/bridge -l`
114                         OVS_BR_INT=${OVS_BR_INT##*/}
115                     else
116                         BR_TYPE="ovs_br"
117                         OVS_BR_INT=`sudo ovs-vsctl port-to-br $peer`
118                         # OVS_BR_INT=`sudo ovs-vsctl iface-to-br $peer`
119                     fi
120                     echo "bridge: $BR                                  $BR_TYPE: $OVS_BR_INT"
121                     echo "           |__ veth: $port <----> veth: $peer __|"
122                 fi
123             done
124         fi
125     done
126     echo "************************************************"
127 }
128 br_connetion_brs_by_veth $BR
129 
130 # IS_OVS=`sudo ovs-vsctl list-br | grep $OVS_BR_INT`
131 
132 echo ""
133 echo "************************************************"
134 function connetion_between_brs_by_peer()
135 {
136     OVS_INFOS=`sudo ovs-vsctl show |tr "\n" " "`
137     ALL=""
138     while [[ "$OVS_INFOS" =~ "{peer=" ]]
139     do
140         PORT=${OVS_INFOS%%\}*}
141         PORT=${PORT%[[:space:]]*type*}
142         PORT=${PORT##*Interface}
143         PORT=`echo $PORT`
144         PEER=${OVS_INFOS#*\{peer=}
145         PEER=${PEER%%\}*}
146         OVS_INFOS=${OVS_INFOS#*\{peer=*\}}
147         if [[ ! "$ALL" =~ "$PORT" ]]
148         then
149             ALL="$ALL $PORT $PEER"
150             PEER_BR=`sudo ovs-vsctl iface-to-br $PORT`
151             BR=`sudo ovs-vsctl iface-to-br $PEER`
152             echo "ovs_br: $BR                                   ovs_br: $PEER_BR"
153             echo "           |__ patch: $PEER <----> patch: $PORT __|"
154             echo ""
155         else
156             continue
157         fi
158     done
159 }
160 connetion_between_brs_by_peer
161 echo "************************************************"
162 
163 
164 echo ""
165 echo "================================================================================"
166 echo "The follow are L3 info in namesapce:"
167 echo ""
168 echo "in name space qdhcp-$NET_ID:"
169 function ns_info()
170 {
171     NS=$1
172     LOCAL_IFS=`sudo ip netns exec $NS ip link |egrep "[0-9]+: " | awk '{print $2}'`
173     for i in $LOCAL_IFS
174     do
175         if [[ ${i%%:} == lo ]]
176         then 
177             continue 
178         fi
179         echo "interface: ${i%%:}"
180         sudo ip netns exec $NS ip a show ${i%%:} |grep "global ${i%%:}"
181         DVR=`sudo ip netns exec $NS ethtool  -i ${i%%:}|grep "driver:" |awk '{print $2}'`
182         if [[ $DVR ==  "openvswitch" ]]
183         then
184             OVS_BR=`sudo ip netns exec $NS ovs-vsctl iface-to-br ${i%%:}`
185             echo "ovs-bridge: $OVS_BR" 
186             echo "             |__ port: ${i%%:}"
187         else
188             echo "unknow iface type $DVR" 
189         fi
190         echo ""
191     done
192     return $((0+0));
193     # return $($NS);
194 }
195 
196 ns_info qdhcp-$NET_ID
197 echo "Get route info by:"
198 echo "sudo ip netns exec qdhcp-$NET_ID route"
199 echo "Get iptable info by:"
200 echo "sudo ip netns exec qdhcp-$NET_ID iptables -nv -t nat -L"
201 
202 echo ""
203 echo  "namespace router is: "
204 for i in `sudo ip netns |grep qrouter-`
205 do
206     echo "*****************************"
207     NAME_S=$i
208     ns_info $i
209     echo "Get route info by:"
210     echo "sudo ip netns exec $NAME_S route"
211     echo "Get iptable info by:"
212     echo "sudo ip netns exec $NAME_S iptables -nv -t nat -L"
213     echo ""
214 done
215 
216 function filter_link_by_ip()
217 {
218     for i in `ip netns`;
219     do
220         L_IP=`sudo ip netns exec $i ip addr |grep $1`;
221         if [[ ! -z $L_IP ]]; then
222             L_PORT=${L_IP##*[[:space:]]}
223             echo "sudo ip netns exec $i ip a show $L_PORT"
224             sudo ip netns exec $i ip a show $L_PORT 
225             break
226         fi
227     done
228 }
229 # filter_link_by_ip $FLOATING_IP
230 
231 #something wrong with this logic
232 function ovs_br_2_ovs_br()
233 {
234     for port in `sudo ovs-vsctl show |grep "options: {peer=" |cut -d "=" -f1`
235     do
236         port=${port%%\}*}
237         echo $port
238         THIS_BR=`sudo ovs-vsctl iface-to-br $port`
239         if [[ $THIS_BR == $OVS_BR_INT ]]; then
240              
241             echo "bridge: $THIS_BR                             bridge: $PEER_BR"
242             echo "           |__ veth: $port <----> veth: $peer __|"
243          
244         fi
245     done
246 }
247 
248 # ovs_br_2_ovs_br
249 
250 
251 # we can use this logic to find which VM attach to br_int
252 function connetion_between_brs()
253 {
254     echo ""
255     echo "************************************************"
256     IS_OVS=`sudo ovs-vsctl list-br | grep $OVS_BR_INT`
257     if [[ $IS_OVS == $OVS_BR_INT ]]; then
258         for port in `sudo ovs-vsctl list-ifaces $OVS_BR_INT`; do
259             PORT_TY=`ethtool -i $port 2>&- | grep "driver:" |awk '{print $2}'`
260             if [[ $PORT_TY == "veth" ]] ; then
261                 PEER_INDEX=`ethtool -S $port | grep "peer_ifindex:" |awk '{print $2}'`
262                 for peer in `ls /sys/class/net/`; do
263                     INDEX=`cat /sys/class/net/$peer/ifindex`
264                     if [[ $PEER_INDEX == $INDEX ]]; then
265                         PEER_INT=""
266                         if [[ -d /sys/class/net/$peer/brport/bridge ]]; then
267                             PEER_INT=`ls /sys/class/net/$peer/brport/bridge -l`
268                             PEER_INT=${PEER_INT##*/}
269                         else
270                             PEER_INT=`sudo ovs-vsctl port-to-br $peer`
271                             # PEER_INT=`sudo ovs-vsctl iface-to-br $peer`
272                         fi
273                         if [[ "x$PEER_INT" == "x" ]]; then
274                             continue
275                         fi
276                         echo "bridge: $OVS_BR_INT                               bridge: $PEER_INT"
277                         echo "           |__ veth: $port <----> veth: $peer __|"
278                         echo ""
279                     fi
280                 done
281             fi
282         done
283     fi
284     echo "************************************************"
285 }
286 # connetion_between_brs "br_int"
287 
288 NETINFO=`nova show $1 |grep "network  *|"`
289 function find_nova_net_id()
290 {
291      NETINFO=$1
292      NETINFO="${NETINFO##network[[:space:]]*|}"
293      NET_NAME="${NETINFO%[[:space:]]*network*}"
294      NET_NAME="${NET_NAME#*[[:space:]]*}"
295      ID=`nova network-show $NET_NAME |grep "| *id *|" |awk '{print $4}'`
296      echo "$ID"
297 }
298 NET_ID=`find_nova_net_id "$NETINFO"`
299 
300 function find_nova_net_ips()
301 {
302     NETINFO=$1
303     IPS="${NETINFO#*network[[:space:]]*|}"
304     IPS="${IPS%[[:space:]]*|*}"
305     IPS="${IPS%[[:space:]]*}"
306     IPS=`tr "," " " <<<  ${IPS#*[[:space:]]}`
307     for i in $IPS; do echo $i; done
308 }
309 # NET_ID=`find_nova_net_ips "$NETINFO"`
310 
311 # ps ww `pgrep dnsmasq` |grep $NET_ID 
View Code

 

你可能感兴趣的:(写个脚本列出neutron的ovs的topology。)