Mar 30, 2016

Contrail BUM tree utility

Contrail creates BUM tree to avoid particular node processes huge BUM traffic when Contrail processes BUM traffic.
At this time, one vRouter replicates BUM traffic to maximum Four vRouter.
We can confirm actual BUM tree by cli or Introspect on vRouter, it's tired to connect multiple vRouter then to execute command.

In case of cli, we can see it in the following procedure.
1) Confirm NextHop ID by VNI
root@contrail-05:~# vxlan --get 2008
VXLAN Table

 VNID    NextHop
----------------
   2008    183

2) Confirm VRF ID from NextHop
root@contrail-05:~# nh --get 183
Id:183        Type:Vrf_Translate  Fmly: AF_INET  Flags:Valid, Vxlan, Unicast Flood,   Rid:0  Ref_cnt:2 Vrf:2005
              Vrf:2005

3) Comfirm MAC address list from VRF ID
root@contrail-05:~# rt --dump 2005 --family bridge
Kernel L2 Bridge table 0/2005

Flags: L=Label Valid, Df=DHCP flood

Index     DestMac                          Flags       Label/VNID      Nexthop
170652     0:44:44:0:0:12                                       -          1
249441     a0:36:9f:74:88:d8                  Df                -          3
315393     0:0:5e:0:1:0                       Df                -          3
404400     0:22:22:0:0:12                                       -          1
540752     ff:ff:ff:ff:ff:ff                 LDf             2008        203
656836     2:d2:2f:ef:ae:93                  LDf               27        792
797245     2:b:eb:af:7:f5                    LDf               24        397

4) Confirm NextHop ID of ff:ff:ff:ff:ff:ff then confirm each Sub NH
root@contrail-05:~# nh --get 203
Id:203        Type:Composite  Fmly:AF_BRIDGE  Flags:Valid, Multicast, L2,   Rid:0  Ref_cnt:4 Vrf:2005
              Sub NH(label): 209(0) 204(0) 200(0)

bumtreedisp.py that I made automatically shows BUM replication list when you set VNI and IP address of vRouter as arguments
Program is HERE.
Download "bumtreedisp.py" and "contrail_sandeshlibs.py"
*** bumtreedisp.py is main program.

Required libraliy of python are "argparse, sys, xmldict, urllib2"

How to use is "python bumtreedisp.py -t <IP address of vRouter> -v <VNI>"
It shows like below
root@console:~# python bumtreedisp.py -t 172.27.113.207 -v 2008
### Host 172.27.113.207 VNI 2008 BUM Tree ###
---- TAP interfaces ----
TAP:tapd22fefae-93  MAC:02:d2:2f:ef:ae:93
---- Tunnel interfaces ----
SIP:192.168.21.1    DIP:10.84.50.5      Encap:MPLSoUDP
SIP:192.168.21.1    DIP:192.168.22.1    Encap:MPLSoUDP

Mar 17, 2016

How to use contrail_sandeshlibs.py

Raw introspect data is not useful to use python program, because there are invisible tags, elements or so in XML data.
in case of virtual-network list of introspect in vrouter-agent, we can see it at http://<compute-node>:8085/Snh_VnListReq?name= by XML.
It's easy to see by Web browser, but hard to use in python as it is.
contrail_sandeshlibs.py is a program to modify from contrail introspect XML data to python dict/list.
It set keys of dict from xml type of '@type' is in 'sandesh', 'struct', 'i64', 'i32', 'i16', 'u64', 'u32', 'u16', 'double', 'string', 'bool'.
If there is list type in it, the list is set in a common dict key.
contrail_sandeshlibs.py has many definitions that is named from Sandesh table name.
For instance, def get_vn_list(self, name='') is named by VnListResp.
Please see comments of each definitions in contrail_sandeshlibs.py

Note: some definitions might return Huge number of data especially ifmap, so some ifmap definitions has flag to avoid it. If you want to get all of it, set ifmap_dump=True to the instance.

** vrouter introspect doc is here
** bumtreedisp.py and tor_tsn_compare.py are using this library.

How To use it.

1) install libraries.
sys
copy
xmltodict
urllib2
** contrail_sandeshlibs.py uses some libraries following. xmltodict is not standerd library, but it is used by Contrail.

2) import contrail_sandeshlibes
3) set hostmane and port. By default, hostname=127.0.0.1 port=8085
   port number is different by each daemons. See RolesDaemaonPorts.
4) Create object
5) Run instance. It is possible to set Argument.


### Sample code
from contrail_sandeshlibs import *

hostname='172.27.113.207'
port='8085'

a = GetContrailSandesh(hostname=hostname,port=port)
py_dict = a.get_vn_list(name='default-domain:test-project1:VRRPvn1')
return py_dict
### Example:Result
{u'VnListResp': {u'vn_list': {u'vxlan_id': u'7833', u'bridging': u'true', u'name': u'default-domain:test-project1:VRRPvn1', u'admin_state': u'true', u'mirror_acl_uuid': '', u'acl_uuid': '', u'config_vxlan_id': u'0', u'enable_rpf': u'true', u'ipv4_forwarding': u'true', u'flood_unknown_unicast': u'false', u'vrf_name': u'default-domain:test-project1:VRRPvn1:VRRPvn1', u'layer2_forwarding': u'true', u'ipam_host_routes': {u'ipam_name': u'default-domain:default-project:default-network-ipam', u'host_routes': ''}, u'mirror_cfg_acl_uuid': '', u'ipam_data': {u'dns_server': u'10.0.0.2', u'dhcp_enable': u'true', u'ipam_name': u'default-domain:default-project:default-network-ipam', u'ip_prefix': u'10.0.0.0', u'prefix_len': u'24', u'gateway': u'10.0.0.1'}, u'vn_id': u'7833', u'uuid': u'bf34d68a-1eb7-4722-ac78-d7d6104de250'}}}
### Ecample:Raw XML
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="/universal_parse.xsl"?>
<__VnListResp_list type="slist">
  <VnListResp type="sandesh">
    <vn_list type="list" identifier="1">
      <list type="struct" size="1">
        <VnSandeshData>
          <name type="string" identifier="1">default-domain:test-project1:VRRPvn1</name>
          <uuid type="string" identifier="2">bf34d68a-1eb7-4722-ac78-d7d6104de250</uuid>
          <acl_uuid type="string" identifier="3" link="AclReq"/>
          <mirror_acl_uuid type="string" identifier="4" link="AclReq"/>
          <mirror_cfg_acl_uuid type="string" identifier="5" link="AclReq"/>
          <vrf_name type="string" identifier="6" link="VrfListReq">default-domain:test-project1:VRRPvn1:VRRPvn1</vrf_name>
          <ipam_data type="list" identifier="7">
            <list type="struct" size="1">
              <VnIpamData>
                <ip_prefix type="string" identifier="1">10.0.0.0</ip_prefix>
                <prefix_len type="i32" identifier="2">24</prefix_len>
                <gateway type="string" identifier="3">10.0.0.1</gateway>
                <ipam_name type="string" identifier="4">default-domain:default-project:default-network-ipam</ipam_name>
                <dhcp_enable type="string" identifier="5">true</dhcp_enable>
                <dns_server type="string" identifier="6">10.0.0.2</dns_server>
              </VnIpamData>
            </list>
          </ipam_data>
          <ipam_host_routes type="list" identifier="8">
            <list type="struct" size="1">
              <VnIpamHostRoutes>
                <ipam_name type="string" identifier="1">default-domain:default-project:default-network-ipam</ipam_name>
                <host_routes type="list" identifier="2">
                  <list type="string" size="0"/>
                </host_routes>
              </VnIpamHostRoutes>
            </list>
          </ipam_host_routes>
          <layer2_forwarding type="bool" identifier="9">true</layer2_forwarding>
          <ipv4_forwarding type="bool" identifier="10">true</ipv4_forwarding>
          <admin_state type="bool" identifier="11">true</admin_state>
          <vxlan_id type="i32" identifier="12">7833</vxlan_id>
          <config_vxlan_id type="i32" identifier="13">0</config_vxlan_id>
          <vn_id type="i32" identifier="14">7833</vn_id>
          <enable_rpf type="bool" identifier="15">true</enable_rpf>
          <bridging type="bool" identifier="16">true</bridging>
          <flood_unknown_unicast type="bool" identifier="17">false</flood_unknown_unicast>
        </VnSandeshData>
      </list>
    </vn_list>
    <more type="bool" identifier="0">true</more>
  </VnListResp>
  <Pagination type="sandesh">
    <req type="struct" identifier="1">
      <PageReqData>
        <prev_page type="string" identifier="1" link="PageReq"/>
        <next_page type="string" identifier="2" link="PageReq"/>
        <first_page type="string" identifier="3" link="PageReq">begin:0,end:99,table:db.vn.0,name:default-domain:test-project1:VRRPvn1</first_page>
        <all type="string" identifier="4" link="PageReq">begin:-1,end:-1,table:db.vn.0,name:default-domain:test-project1:VRRPvn1</all>
        <table_size type="u32" identifier="5">2</table_size>
        <entries type="string" identifier="6">0-0/1</entries>
      </PageReqData>
    </req>
    <more type="bool" identifier="0">false</more>
  </Pagination>
</__VnListResp_list>

If you want to get "undefined" sandesh data, you can get to use "get_path_sandesh_to_dict"
from contrail_sandeshlibs import *

path='Snh_BgpNeighborReq?'
port='8083'
ip = '172.27.113.202'

a= GetContrailSandesh(hostname=ip,port=port)
a.get_path_sandesh_to_dict(path)