Custom Search

Monday, June 15, 2015

Contrail add Static Routes via Host Routes notes


http://fosshelp.blogspot.in/2015/06/contrail-add-static-routes-via-host.html

1)
Port Create Flow.

This check "host routes" of the subnet, then create InterfaceRouteTable and attach to the port.

a)
Port create operation create "interface route table" for the port if subnet has a "host route" for this port's IP and "apply_subnet_host_routes=True" in /etc/contrail/api_server.conf .

https://github.com/Juniper/contrail-controller/blob/master/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py#L3454
def port_create(self, context, port_q):
        if self._apply_subnet_host_routes:
            self._port_check_and_add_iface_route_table(ret_port_q['fixed_ips'],
                                                       net_obj, port_obj)

b)

https://github.com/Juniper/contrail-controller/blob/master/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py#L2089

def _port_check_and_add_iface_route_table(self, fixed_ips, net_obj,port_obj):

* Get ipam of the network.
* Get subnets of the network from the ipam.
* Get host routes of each subnet
* If "IP" address of this port is defined as next-hop in "host routes" of any one of the subnet on this network, then invoke "_port_add_iface_route_table" and pass CIDR defined in "host routes" for this IP (next-hop) with port and subnet object.

c)
https://github.com/Juniper/contrail-controller/blob/master/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py#L2114

* Create InterfaceRouteTable and set routes.
* Add created InterfaceRouteTable to port.

from vnc_api.gen.resource_client import InterfaceRouteTable

def _port_add_iface_route_table(self, route_prefix_list, port_obj, subnet_id):

    project_obj = self._project_read(proj_id=port_obj.parent_uuid)

    #Create RouteTableType object and set route as empty.
    route_table = RouteTableType(intf_rt_name)
    route_table.set_route([])
   
    #Create InterfaceRouteTable object and set interface_route_table_routes
    intf_route_table = InterfaceRouteTable(
                        interface_route_table_routes=route_table,
                        parent_obj=project_obj,
                        name=intf_rt_name)

    #Create InterfaceRouteTable by making vnc api call
    intf_route_table_id = self._vnc_lib.interface_route_table_create(
                            intf_route_table)
    intf_route_table_obj = self._vnc_lib.interface_route_table_read(
                            id=intf_route_table_id)

    #Get routes from InterfaceRouteTable object.
    rt_routes = intf_route_table_obj.get_interface_route_table_routes()
    routes = rt_routes.get_route()
    # delete any old routes
    routes = []
   
    #Set routes to InterfaceRouteTable
    for prefix in route_prefix_list:
        routes.append(RouteType(prefix=prefix))
    rt_routes.set_route(routes)
    intf_route_table_obj.set_interface_route_table_routes(rt_routes)
    self._vnc_lib.interface_route_table_update(intf_route_table_obj)
   
    #Add InterfaceRouteTable to port
    port_obj.add_interface_route_table(intf_route_table_obj)
    self._vnc_lib.virtual_machine_interface_update(port_obj)

d)
d1)

https://github.com/Juniper/contrail-controller/blob/26f014b4f6e55afbb09d86551e9efea5d9efe30e/src/schema/vnc_cfg.xsd#L1409
contrail-controller/src/schema/vnc_cfg.xsd

<xsd:complexType name="RouteTableType">
    <xsd:all>
        <xsd:element name="route" type="RouteType" maxOccurs="unbounded"/>
    </xsd:all>
</xsd:complexType>

d2)
https://github.com/Juniper/contrail-controller/blob/26f014b4f6e55afbb09d86551e9efea5d9efe30e/src/schema/vnc_cfg.xsd#L1437
contrail-controller/src/schema/vnc_cfg.xsd


 <xsd:element name="interface-route-table" type="ifmap:IdentityType"/>

<xsd:element name="interface-route-table-routes" type="RouteTableType"/>


2)
Examples:

a)
Static route util example, using same logic.
https://github.com/Juniper/contrail-controller/blob/master/src/config/utils/provision_static_route.py

b)
Another static route example from svc-monitor.

https://github.com/Juniper/contrail-controller/blob/332bc0a51558439eec4e19b56380d9fc15c4aff7/src/config/svc-monitor/svc_monitor/instance_manager.py#L109

3)
Some Findings


---------------

* Example of one host route entry which i added to a subnet "10.1.10/24" of network "mynetwork1" is "12.1.1.0/24, 10.1.1.3".
* Here 10.1.1.3 is the IP of a VM which belongs to same subnet where we added host route "12.1.1.0/24, 10.1.1.3".
* Add routes in the "subnet:Host Routes" to VRF which mapped to the Network.
* Next-hop should be IP of a VM
* Route get delete from VRF when we shoutdown the next-hop VM.
* Route get add again to VRF when we start the next-hop VM from controller http://ip:8083/Snh_IFMapTableShowReq?x=interface-route-table
* Other VMs in the same subnet can redirect trafic destinct to "12.1.1.0/24" to VM "10.1.1.3".

---------------

* mynetwork1 --> subnet1:(10.1.1.0/24), subnet2:(10.5.5.0/24)

* Delete "host route" from subnet (Edit sudnet), this will remove route from controller "http://ip:8083/Snh_IFMapTableShowReq?x=interface-route-table" and VRF which mapped to the Network. After that, if we try to ping to next-hot VM:10.1.1.3 from a VM:10.5.5.4 which belongs to
different subnet in the same network, ping not works, we need to restart net-hop VM:10.1.1.3 to make ping working.

* Similarly, if we add "host route" back to the subnet, that will add route to controller "http://ip:8083/Snh_IFMapTableShowReq?x=interface-route-table" and VRF which mapped to the Network. This will not prevent the ping from a VM:10.5.5.4 which belongs to different subnet in the same network to VM:10.1.1.3. we need to restart net-hop VM:10.1.1.3 to prevent ping.

---------------

4)
Update subnet flow.


* Get all IP objects of the network where this subnet belongs.
* If an IP match with next-hop defined in the subnet's "host routes", then find the port assocuated with the IP, then create InterfaceRouteTable and attach to the port.

a)
https://github.com/Juniper/contrail-controller/blob/26f014b4f6e55afbb09d86551e9efea5d9efe30e/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py#L2582
 

contrail-controller/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py

def subnet_update(self, subnet_id, subnet_q):
    if self._apply_subnet_host_routes:
        old_host_routes = subnet_vnc.get_host_routes()
        subnet_cidr = '%s/%s' % (subnet_vnc.subnet.get_ip_prefix(),
                                 subnet_vnc.subnet.get_ip_prefix_len())
        self._port_update_iface_route_table(net_obj,
                                            subnet_cidr,
                                            subnet_id,
                                            host_routes,
                                            old_host_routes)


b)
https://github.com/Juniper/contrail-controller/blob/26f014b4f6e55afbb09d86551e9efea5d9efe30e/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py#L2150
 

contrail-controller/src/config/vnc_openstack/vnc_openstack/neutron_plugin_db.py

def _port_update_iface_route_table(self, net_obj, subnet_cidr, subnet_id,
                                   new_host_routes, old_host_routes=None):

                                  
    # get the list of all the ip objs for this network
    ipobjs = self._instance_ip_list(back_ref_id=[net_obj.uuid])
    for ipobj in ipobjs:
        ipaddr = ipobj.get_instance_ip_address()
        if ipaddr in old_host_prefixes:
            self._port_remove_iface_route_table(ipobj, subnet_id)
            continue

        if ipaddr in new_host_prefixes:
            port_back_refs = ipobj.get_virtual_machine_interface_refs()
            for port_ref in port_back_refs:
                port_obj = self._virtual_machine_interface_read(
                                port_id=port_ref['uuid'])
                self._port_add_iface_route_table(new_host_prefixes[ipaddr],
                                                 port_obj, subnet_id)


5)
a)

#sudo grep -r apply_subnet_host_routes /etc/contrail

b)
#sudo grep -r apply_subnet_host_routes /usr/lib/python2.7/dist-packages/vnc_openstack

c)
IFMap Node table

http://192.168.56.102:8083/Snh_IFMapNodeTableListShowReq

Route table
http://192.168.56.102:8083/Snh_IFMapTableShowReq?x=route-table

Interface Route table
http://192.168.56.102:8083/Snh_IFMapTableShowReq?x=interface-route-table

VRF List
http://192.168.56.102:8085/Snh_VrfListReq?name=

Static Route
https://github.com/Juniper/contrail-controller/wiki/Static-Routes

Patch
https://github.com/Juniper/contrail-controller/commit/5031f59adcca7e238c1489fde2558521e2c2d81a#diff-1e8d43a6c800def7704681bd7b7827bd



No comments:

Post a Comment