Fix tox errors in existing specs
[netvirt.git] / resources / tools / odltools / netvirt / ds_analyze.py
1 import constants as const
2 import ds_get_data as dsg
3 import flow_parser as fp
4 import json
5 import netvirt_utils as utils
6 from collections import defaultdict
7
8
9 # Required
10 ifaces = None
11 ifstates = None
12
13 #Optional
14 ports = {}
15 tunnels = {}
16 confNodes = {}
17 operNodes = {}
18
19
20 def by_ifname(ifname):
21     ifstate = ifstates.get(ifname)
22     iface = ifaces.get(ifname)
23     port = None
24     tunnel = None
25     tunState = None
26     if iface and iface.get('type') == const.IFTYPE_VLAN:
27         ports = dsg.get_neutron_ports()
28         port = ports.get(ifname)
29     elif iface and iface.get('type') == const.IFTYPE_TUNNEL:
30         tunnels = dsg.get_config_tunnels()
31         tunnel = tunnels.get(ifname)
32         tunStates = dsg.get_tunnel_states()
33         tunState = tunStates.get(ifname)
34     else:
35         print "UNSUPPORTED IfType"
36     return iface,ifstate,port,tunnel,tunState
37
38
39 def print_keys():
40     print "InterfaceNames: ", ifaces.keys()
41     print
42     print "IfStateNames: ", ifstates.keys()
43
44
45 def analyze_interface(ifname=None):
46     global ifaces, ifstates
47     if not ifname:
48         print_keys()
49         exit(1)
50     ifname = ifname[0]
51     ifaces = dsg.get_config_interfaces()
52     ifstates = dsg.get_interface_states()
53     iface,ifstate,port,tunnel,tunState = by_ifname(ifname)
54     print "InterfaceConfig: "
55     json.dumps(iface, indent=2)
56     print "InterfaceState: "
57     json.dumps(ifstate, indent=2)
58     if port:
59         print "NeutronPort: "
60         json.dumps(port, indent=2)
61         analyze_neutron_port(port, iface, ifstate)
62         return
63     if tunnel:
64         print "Tunnel: "
65         json.dumps(tunnel, indent=2)
66     if tunState:
67         print "TunState: "
68         json.dumps(tunState, indent=2)
69     if ifstate:
70         ncId = ifstate.get('lower-layer-if')[0]
71         nodeId = ncId[:ncId.rindex(':')]
72         analyze_inventory(nodeId, True, ncId, ifname)
73         #analyze_inventory(nodeId, False, ncId, ifname)
74
75 def analyze_neutron_port(port, iface, ifstate):
76     for flow in utils.sort(get_all_flows(['all']), 'table'):
77         if ((flow.get('ifname') == port['uuid']) or
78             (flow.get('lport') and ifstate and flow['lport'] == ifstate.get('if-index')) or
79             (iface['name'] == flow.get('ifname'))):
80                 result = 'Table:{},FlowId:{}{}'.format(
81                 flow['table'], flow['id'],
82                 utils.show_optionals(flow))
83                 print result
84                 print 'Flow:', json.dumps(parse_flow(flow.get('flow')))
85
86
87 def analyze_inventory(nodeId, isConfig=True, ncId=None, ifName=None):
88     if isConfig:
89         nodes = dsg.get_inventory_config()
90         print "Inventory Config:"
91     else:
92         print "Inventory Operational:"
93         nodes = dsg.get_inventory_oper()
94     node = nodes.get(nodeId)
95     tables = node.get(const.NODE_TABLE)
96     groups = node.get(const.NODE_GROUP)
97     flow_list = []
98     print "Flows:"
99     for table in tables:
100         for flow in table.get('flow', []):
101             if not ifName or ifName in utils.nstr(flow.get('flow-name')):
102                 flow_dict = {}
103                 flow_dict['table'] = table['id']
104                 flow_dict['id'] = flow['id']
105                 flow_dict['name'] = flow.get('flow-name')
106                 flow_dict['flow'] = flow
107                 flow_list.append(flow_dict)
108     flows = sorted(flow_list, key=lambda x: x['table'])
109     for flow in flows:
110         print 'Table:', flow['table']
111         print 'FlowId:', flow['id'], 'FlowName:', flow.get('name')
112
113
114 def get_dpn_host_mapping(oper_nodes=None):
115         nodes_dict = {}
116         nodes = oper_nodes or dsg.get_inventory_oper()
117         for node in nodes.itervalues():
118             dpnid = utils.get_dpn_from_ofnodeid(node['id'])
119             nodes_dict[dpnid] = node.get('flow-node-inventory:description', '')
120         return nodes_dict
121
122
123 def get_groups(ofnodes=None):
124     of_nodes = ofnodes or dsg.get_inventory_config()
125     key ='group-id'
126     group_dict = defaultdict(dict)
127     for node in of_nodes.itervalues():
128         dpnid = utils.get_dpn_from_ofnodeid(node['id'])
129         for group in node.get(const.NODE_GROUP, []):
130             if group_dict.get(dpnid) and group_dict.get(dpnid).get(group[key]):
131                 print 'Duplicate:', dpnid, group[key]
132             group_dict[dpnid][group[key]] = group
133     return dict(group_dict)
134
135
136 def get_stale_flows(modules=['ifm']):
137     if not modules:
138         return 'No modules specified'
139     ifaces = {}
140     ifstates = {}
141     ifindexes = {}
142     bindings = {}
143     einsts = {}
144     eifaces = {}
145     fibentries = {}
146     vpnids = {}
147     vpninterfaces = {}
148     groups = {}
149     table_list = list(set([table for module in modules for table in const.TABLE_MAP[module]]))
150     ##table_list = [214, 244]
151     of_nodes = dsg.get_inventory_config()
152     if 'ifm' in modules:
153         ifaces = dsg.get_config_interfaces()
154         ifstates = dsg.get_interface_states()
155     if 'l3vpn' in modules:
156         ifaces = ifaces or dsg.get_config_interfaces()
157         ifindexes = ifindexes or dsg.get_ifindexes()
158         fibentries = fibentries or dsg.get_fibentries_by_label()
159         vpnids = vpnids or dsg.get_vpnids()
160         vpninterfaces = vpninterfaces or dsg.get_vpninterfaces()
161         groups = groups or get_groups(of_nodes)
162     if 'acl' in modules:
163         ifaces = ifaces or dsg.get_config_interfaces()
164         ifindexes = ifindexes or dsg.get_ifindexes()
165         einsts = einsts or dsg.get_elan_instances()
166         eifaces = eifaces or dsg.get_elan_interfaces()
167     if 'elan' in modules:
168         ifaces = ifaces or dsg.get_config_interfaces()
169         einsts = einsts or dsg.get_elan_instances()
170         eifaces = eifaces or dsg.get_elan_interfaces()
171         ifindexes = ifindexes or dsg.get_ifindexes()
172     stale_flows = []
173     for node in of_nodes.itervalues():
174         tables = [x for x in node[const.NODE_TABLE] if x['id'] in table_list]
175         for table in tables:
176             for flow in table.get('flow', []):
177                 flow_dict = None
178                 flow_info = {}
179                 flow_info['dpnid'] = utils.get_dpn_from_ofnodeid(node['id'])
180                 if 'ifm' in modules and table['id'] in const.TABLE_MAP['ifm']:
181                     flow_dict = fp.stale_ifm_flow(flow, flow_info, ifaces, ifstates)
182                 if 'l3vpn' in modules and table['id'] in const.TABLE_MAP['l3vpn']:
183                     flow_dict = fp.stale_l3vpn_flow(flow, flow_info, groups, ifaces, ifindexes, vpnids, vpninterfaces, fibentries)
184                 if 'elan' in modules and table['id'] in const.TABLE_MAP['elan']:
185                     flow_dict = fp.stale_elan_flow(flow, flow_info, ifaces, ifindexes, einsts, eifaces)
186                 if 'acl' in modules and table['id'] in const.TABLE_MAP['acl']:
187                     flow_dict = fp.stale_acl_flow(flow, flow_info, ifaces, ifindexes, einsts, eifaces)
188                 if flow_dict is not None:
189                     stale_flows.append(flow_dict)
190
191     return stale_flows
192
193
194 def show_stale_bindings():
195     stale_ids, bindings = get_stale_bindings()
196     for iface_id in sorted(stale_ids):
197         for binding in bindings[iface_id].itervalues():
198             #if binding.get('bound-services'):
199             path = get_data_path('bindings', binding)
200             print json.dumps(bindings[iface_id])
201             print('http://192.168.2.32:8383/restconf/config/{}'.format(path))
202
203
204 def get_stale_bindings():
205     ifaces = dsg.get_config_interfaces()
206     bindings, orphans = dsg.get_service_bindings()
207     return set(bindings.keys()) - set(ifaces.keys()), bindings
208
209
210 def get_ips_for_iface(nports, ifname):
211     ips = []
212     port = nports.get(ifname) if ifname else None
213     fixed_ips = port.get('fixed-ips', []) if port else []
214     for fixed_ip in fixed_ips:
215         ips.append(fixed_ip['ip-address'])
216     return ips
217
218
219 def show_link_flow_binding():
220     stale_ids, bindings = get_stale_bindings()
221     flows = get_stale_flows()
222     print len(stale_ids), len(flows)
223     for flow in flows:
224         if flow['ifname'] in stale_ids and 'bound-services' in bindings[flow['ifname']]:
225             print 'Flow with binding: ', flow['ifname']
226         else:
227             print 'Flow without binding: ', flow['ifname']
228
229
230 def show_stale_flows(sort_by='table'):
231     compute_map = get_dpn_host_mapping()
232     nports = dsg.get_neutron_ports()
233     for flow in utils.sort(get_stale_flows(['ifm', 'acl', 'elan', 'l3vpn']), sort_by):
234         host = compute_map.get(flow.get('dpnid'), flow.get('dpnid'))
235         ip_list = get_ips_for_iface(nports, flow.get('ifname'))
236         if ip_list:
237             flow['iface-ips'] = ip_list
238         result = 'Table:{},Host:{},FlowId:{}{}'.format(
239             flow['table'], host, flow['id'],
240             utils.show_optionals(flow))
241         print result
242         ##path = get_data_path('flows', flow)
243         #print('http://192.168.2.32:8383/restconf/config/{}'.format(path))
244         #print 'Flow:', json.dumps(parse_flow(flow['flow']))
245
246
247 def get_all_flows(modules=['ifm'], filter=[]):
248     if not modules:
249         return 'No modules specified'
250     ifaces = {}
251     ifstates = {}
252     ifindexes = {}
253     bindings = {}
254     einsts = {}
255     eifaces = {}
256     fibentries = {}
257     vpnids = {}
258     vpninterfaces = {}
259     groups = {}
260     if 'all' in modules:
261         table_list = list(range(0, 255))
262     else:
263         table_list = list(set([table for module in modules for table in const.TABLE_MAP[module]]))
264     ##table_list = [214, 244]
265     of_nodes = dsg.get_inventory_config()
266     if 'ifm' in modules:
267         ifaces = dsg.get_config_interfaces()
268         ifstates = dsg.get_interface_states()
269     if 'l3vpn' in modules:
270         ifaces = ifaces or dsg.get_config_interfaces()
271         ifindexes = ifindexes or dsg.get_ifindexes()
272         fibentries = fibentries or dsg.get_fibentries_by_label()
273         vpnids = vpnids or dsg.get_vpnids()
274         vpninterfaces = vpninterfaces or dsg.get_vpninterfaces()
275         groups = groups or get_groups(of_nodes)
276     if 'acl' in modules:
277         ifaces = ifaces or dsg.get_config_interfaces()
278         ifindexes = ifindexes or dsg.get_ifindexes()
279         einsts = einsts or dsg.get_elan_instances()
280         eifaces = eifaces or dsg.get_elan_interfaces()
281     if 'elan' in modules:
282         ifaces = ifaces or dsg.get_config_interfaces()
283         einsts = einsts or dsg.get_elan_instances()
284         eifaces = eifaces or dsg.get_elan_interfaces()
285         ifindexes = ifindexes or dsg.get_ifindexes()
286     if 'all' in modules:
287         groups = groups or get_groups(of_nodes)
288         ifaces = ifaces or dsg.get_config_interfaces()
289         ifstates = ifstates or dsg.get_interface_states()
290         ifindexes = ifindexes or dsg.get_ifindexes()
291         fibentries = fibentries or dsg.get_fibentries_by_label()
292         vpnids = vpnids or dsg.get_vpnids()
293         vpninterfaces = vpninterfaces or dsg.get_vpninterfaces()
294         einsts = einsts or dsg.get_elan_instances()
295         eifaces = eifaces or dsg.get_elan_interfaces()
296     flows = []
297     for node in of_nodes.itervalues():
298         tables = [x for x in node[const.NODE_TABLE] if x['id'] in table_list]
299         for table in tables:
300             for flow in table.get('flow', []):
301                 flow_dict = None
302                 flow_info = {}
303                 flow_info['dpnid'] = utils.get_dpn_from_ofnodeid(node['id'])
304                 flow_dict = fp.get_any_flow(flow, flow_info, groups,
305                                         ifaces, ifstates, ifindexes,
306                                         fibentries, vpnids, vpninterfaces,
307                                         einsts, eifaces)
308                 if (flow_dict is not None and
309                         utils.filter_flow(flow_dict, filter)):
310                     flows.append(flow_dict)
311     return flows
312
313
314 def show_flows(modules=['ifm'], sort_by='table', filter_by=[]):
315     compute_map = get_dpn_host_mapping()
316     nports = dsg.get_neutron_ports()
317     for flow in utils.sort(get_all_flows(modules, filter_by), sort_by):
318         host = compute_map.get(flow.get('dpnid'), flow.get('dpnid'))
319         ip_list = get_ips_for_iface(nports, flow.get('ifname'))
320         if ip_list:
321             flow['iface-ips'] = ip_list
322         result = 'Table:{},Host:{},FlowId:{}{}'.format(
323             flow['table'], host, flow['id'],
324             utils.show_optionals(flow))
325         print result
326         print 'Flow:', json.dumps(parse_flow(flow['flow']))
327
328
329 def show_all_flows():
330     show_flows(modules=['all'])
331
332
333 def show_elan_flows():
334     compute_map = get_dpn_host_mapping()
335     for flow in utils.sort(get_all_flows(['elan']), 'id'):
336         host = compute_map.get(flow.get('dpnid'), flow.get('dpnid'))
337         result = 'MacHost:{}{},Table:{},FlowId:{},{},Flow:{}'.format(flow['id'][-17:],host,flow['table'],flow['id'],utils.show_optionals(flow),json.dumps(parse_flow(flow['flow'])))
338         print result
339         #print 'Flow:', json.dumps(parse_flow(flow['flow']))
340
341
342 def get_matchstr(flow):
343     if flow and flow.get('flow') and flow.get('flow').get('match'):
344         return json.dumps(flow.get('flow').get('match', None))
345
346
347 def get_key_for_dup_detect(flow):
348     result = '{}:{}:{}'.format(flow.get('dpnid'), flow.get('table'), get_matchstr(flow))
349     return result
350
351
352 def show_dup_flows():
353     mmac = dsg.get_mip_mac()
354     einsts = dsg.get_elan_instances()
355     flows = utils.sort(get_all_flows(['elan']), 'table')
356     matches = defaultdict(list)
357     compute_map = get_dpn_host_mapping()
358     for flow in flows:
359         dup_key = get_key_for_dup_detect(flow)
360         if dup_key:
361             if matches and matches.get(dup_key):
362                 matches[dup_key].append(flow)
363             else:
364                 matches[dup_key].append(flow)
365     for k, v in matches.iteritems():
366         if len(v) > 1:
367             dpnid = k.split(':')[0]
368             host = compute_map.get(dpnid, dpnid)
369             result = 'Host:{},FlowCount:{},MatchKey:{},ElanTag:{}'.format(host, len(v), k,v[0].get('elan-tag'))
370             print result
371             for idx, flow in enumerate(v):
372                 result = "Duplicate"
373                 mac_addr = flow.get('dst-mac')
374                 if mac_addr and mmac.get(mac_addr):
375                     result = fp.is_correct_elan_flow(flow, mmac.get(mac_addr), einsts, host)
376                 print '    {}Flow-{}:{}'.format(result, idx, json.dumps(parse_flow(flow.get('flow'))))
377
378
379 def show_learned_mac_flows():
380     nports = dsg.get_neutron_ports(key_field='mac-address')
381     flows = utils.sort(get_all_flows(['elan']), 'table')
382     compute_map = get_dpn_host_mapping()
383     for flow_info in flows:
384         flow = flow_info.get('flow')
385         dpnid = flow_info.get('dpnid')
386         host = compute_map.get(dpnid, dpnid)
387         if ((flow_info.get('table') == 50 and
388                 flow.get('idle-timeout') == 300 and not
389                 nports.get(flow_info.get('src-mac'))) or
390                 (flow_info.get('table') == 51 and
391                  not nports.get(flow_info.get('dst-mac')))):
392             result = 'Table:{},Host:{},FlowId:{}{}'.format(
393                 flow_info.get('table'), host, flow.get('id'),
394                 utils.show_optionals(flow_info))
395             print result
396             print 'Flow:{}'.format(json.dumps(parse_flow(flow)))
397
398
399 def show_elan_instances():
400     insts = dsg.get_elan_instances()
401     json.dumps(insts)
402
403
404 def get_duplicate_ids():
405     duplicate_ids= {}
406     for pool in dsg.get_idpools().itervalues():
407         id_values = {}
408         for id_entry in pool.get('id-entries', []):
409             id_info = {}
410             id_value = id_entry.get('id-value')[0]
411             id_key = id_entry.get('id-key')
412             if id_values and id_values.get(id_value, None):
413                 key_list = id_values.get(id_value)
414                 key_list.append(id_key)
415                 id_info['id-value'] = id_value
416                 id_info['id-keys'] = key_list
417                 id_info['pool-name'] = pool.get('pool-name')
418                 id_info['parent-pool-name'] = pool.get('parent-pool-name')
419                 duplicate_ids[id_value] = id_info
420             else:
421                 id_values[id_value] = [id_key]
422     return duplicate_ids
423
424
425
426 def show_idpools():
427     ports = dsg.get_neutron_ports()
428     iface_ids = []
429     for k,v in get_duplicate_ids().iteritems():
430         result = "Id:{},Keys:{}".format(k, json.dumps(v.get('id-keys')))
431         if v.get('pool-name'):
432             result = "{},Pool:{}".format(result, v.get('pool-name'))
433             if v.get('pool-name') == 'interfaces':
434                 iface_ids.extend(v.get('id-keys'))
435         if v.get('parent-pool-name'):
436             result = "{},ParentPool:{}".format(result, v.get('parent-pool-name'))
437         print result
438     print "\nNeutron Ports"
439     print "============="
440     for id in iface_ids:
441         port = ports.get(id, {})
442         print "Iface={}, NeutronPort={}".format(id, json.dumps(port))
443
444
445 def parse_flow(flow):
446     #parse flow fields
447     #hex(int(mask, 16) & int(data, 16))
448     if flow['cookie']:
449         utils.to_hex(flow, 'cookie')
450     # parse instructions
451     for instruction in flow['instructions'].get('instruction', []):
452         if 'write-metadata' in instruction:
453             utils.to_hex(instruction['write-metadata'],'metadata')
454             utils.to_hex(instruction['write-metadata'],'metadata-mask')
455         if 'apply-actions' in instruction:
456             for action in instruction['apply-actions'].get('action', []):
457                 if 'openflowplugin-extension-nicira-action:nx-reg-load' in action:
458                     utils.to_hex(action['openflowplugin-extension-nicira-action:nx-reg-load'], 'value')
459     # parse matches
460     if 'metadata' in flow['match']:
461         metadata = flow['match']['metadata']
462         utils.to_hex(metadata,'metadata')
463         utils.to_hex(metadata,'metadata-mask')
464
465     for ofex in flow['match'].get('openflowplugin-extension-general:extension-list', []):
466         if ofex['extension-key'] == 'openflowplugin-extension-nicira-match:nxm-nx-reg6-key':
467             utils.to_hex(ofex['extension']['openflowplugin-extension-nicira-match:nxm-nx-reg'], 'value')
468
469     return flow
470
471
472 def get_data_path(res_type, data):
473     if res_type == 'bindings':
474         return 'interface-service-bindings:service-bindings/services-info/{}/{}'.format(data['interface-name'],data['service-mode'])
475     elif res_type == 'flows':
476         return 'opendaylight-inventory:nodes/node/openflow:{}/flow-node-inventory:table/{}/flow/{}'.format(data['dpnid'],data['table'],data['id'])
477
478
479 # Sample method that shows how to use
480 def show_all_tables():
481     of_nodes = dsg.get_inventory_config()
482     tables = set()
483     for node in of_nodes.itervalues():
484         for table in node[const.NODE_TABLE]:
485             if table.get('flow'):
486                 tables.add(table['id'])
487     print list(tables)
488
489
490 def show_all_groups():
491     of_nodes = dsg.get_inventory_config()
492     groups = get_groups(of_nodes)
493     for dpn in groups:
494         for group_key in groups[dpn]:
495             print 'Dpn:', dpn, 'ID:', group_key, 'Group:', json.dumps(groups[dpn][group_key])
496
497
498 def analyze_trunks():
499     nports = dsg.get_neutron_ports()
500     ntrunks = dsg.get_neutron_trunks()
501     vpninterfaces = dsg.get_vpninterfaces()
502     ifaces = dsg.get_config_interfaces()
503     ifstates = dsg.get_interface_states()
504     subport_dict = {}
505     for v in ntrunks.itervalues():
506         nport = nports.get(v.get('port-id'))
507         s_subports = []
508         for subport in v.get('sub-ports'):
509             sport_id = subport.get('port-id')
510             snport = nports.get(sport_id)
511             svpniface = vpninterfaces.get(sport_id)
512             siface = ifaces.get(sport_id)
513             sifstate = ifstates.get(sport_id)
514             subport['SubNeutronPort'] = 'Correct' if snport else 'Wrong'
515             subport['SubVpnInterface'] = 'Correct' if svpniface else 'Wrong'
516             subport['ofport'] = utils.get_ofport_from_ncid(sifstate.get('lower-layer-if')[0]) 
517             if siface:
518                 vlan_mode = siface.get('odl-interface:l2vlan-mode')
519                 parent_iface_id = siface.get('odl-interface:parent-interface')
520                 if vlan_mode !='trunk-member':
521                     subport['SubIface'] = 'WrongMode'
522                 elif parent_iface_id !=v.get('port-id'):
523                     subport['SubIface'] = 'WrongParent'
524                 elif siface.get('odl-interface:vlan-id') !=subport.get('segmentation-id'):
525                     subport['SubIface'] = 'WrongVlanId'
526                 else:
527                     subport['SubIface'] = 'Correct'
528             else:
529                 subport['SubIface'] = 'Wrong'
530             s_subport = 'SegId:{},PortId:{},SubNeutronPort:{},SubIface:{},SubVpnIface:{}'.format(
531                     subport.get('segmentation-id'),subport.get('port-id'),
532                     subport.get('SubNeutronPort'),
533                     subport.get('SubIface'),
534                     subport.get('SubVpnInterface'))
535             s_subports.append(subport)
536             subport_dict[subport['port-id']] = subport
537         s_trunk = 'TrunkName:{},TrunkId:{},PortId:{},NeutronPort:{},SubPorts:{}'.format(
538                 v.get('name'), v.get('uuid'), v.get('port-id'),
539                 'Correct' if nport else 'Wrong', json.dumps(s_subports))
540         print s_trunk
541     print '\n------------------------------------'
542     print   'Analyzing Flow status for SubPorts'
543     print   '------------------------------------'
544     for flow in utils.sort(get_all_flows(['ifm'], ['vlanid']), 'ifname'):
545         subport = subport_dict.get(flow.get('ifname')) or None
546         vlanid = subport.get('segmentation-id') if subport else None
547         ofport = subport.get('ofport') if subport else None
548         flow_status = 'Okay'
549         if flow.get('ofport') and flow.get('ofport') != ofport:
550             flow_status = 'OfPort mismatch for SubPort:{} and Flow:{}'.format(subport, flow.get('flow'))
551         if flow.get('vlanid') and flow.get('vlanid') != vlanid:
552             flow_status = 'VlanId mismatch for SubPort:{} and Flow:{}'.format(subport, flow.get('flow'))
553         if subport:
554             print 'SubPort:{},Table:{},FlowStatus:{}'.format(
555                     subport.get('port-id'), flow.get('table'), flow_status)
556
557 def get_all_dumps():
558     dsg.get_all_dumps()
559
560
561 def main(args=None):
562     options, args = utils.parse_args()
563     if options.callMethod:
564         if args[1:]:
565             eval(options.callMethod)(args[1:])
566             return
567         else:
568             eval(options.callMethod)()
569             return
570     #print json.dumps(dsg.get_vpninterfaces())
571     #show_all_tables()
572     #analyze_inventory('openflow:165862438671169',ifName='tunf94333cc491')
573     #show_stale_flows()
574     #show_stale_bindings()
575     analyze_interface([args[1]])
576     #og.print_flow_dict(og.get_ofctl_flows())
577
578
579 if __name__ == '__main__':
580     import sys
581     main()