From 1713ce221a09497a792146a716eeb81fed382514 Mon Sep 17 00:00:00 2001 From: sbalineni Date: Tue, 8 Sep 2015 10:28:49 -0700 Subject: [PATCH] DM: VRF instances are configured based on VN forwarding mode - VN forwarding mode {l2, l2_l3} - Configure L2 VRF - VN forwarding mode {l3, l2_l3} - Configure L3 VRF - L2 VRF will only have interface config - IRB interfaces, irb ip allocation is done only if fwd mode is 'l2_l3' - For all external VNs subnets, add a static route in global forwarding options - for all L3 vrf instances, static routes with discard nexthops are added. Change-Id: I4832b5036c9aecf3ae25187d4bd88018f08af7bc Closes-Bug: #1472699 --- .../device-manager/device_manager/db.py | 37 ++++++---- .../device_manager/physical_router_config.py | 69 ++++++++++++------- 2 files changed, 66 insertions(+), 40 deletions(-) diff --git a/src/config/device-manager/device_manager/db.py b/src/config/device-manager/device_manager/db.py index 4556eeb91a3..5e1f4aa615f 100644 --- a/src/config/device-manager/device_manager/db.py +++ b/src/config/device-manager/device_manager/db.py @@ -342,16 +342,13 @@ def push_config(self): continue import_set |= ri2.export_targets - if vn_obj.router_external == False: - irb_ips = vn_irb_ip_map.get(vn_id, []) - self.config_manager.add_routing_instance(vrf_name_l3, - import_set, - export_set, - vn_obj.get_prefixes(), - irb_ips, - vn_obj.router_external, - ["irb" + "." + str(vn_obj.vn_network_id)]) + if vn_obj.forwarding_mode in ['l2', 'l2_l3']: + irb_ips = None + if vn_obj.forwarding_mode == 'l2_l3': + irb_ips = vn_irb_ip_map.get(vn_id, []) self.config_manager.add_routing_instance(vrf_name_l2, + True, + vn_obj.forwarding_mode == 'l2_l3', import_set, export_set, vn_obj.get_prefixes(), @@ -360,16 +357,16 @@ def push_config(self): interfaces, vn_obj.vxlan_vni, None, vn_obj.vn_network_id) - else: + + if vn_obj.forwarding_mode in ['l3', 'l2_l3']: self.config_manager.add_routing_instance(vrf_name_l3, + False, + vn_obj.forwarding_mode == 'l2_l3', import_set, export_set, vn_obj.get_prefixes(), None, - vn_obj.router_external, - interfaces, - vn_obj.vxlan_vni, - None, vn_obj.vn_network_id) + vn_obj.router_external) break @@ -385,6 +382,8 @@ def push_config(self): interfaces.append(service_ports[0] + "." + str(service_port_id)) interfaces.append(service_ports[0] + "." + str(service_port_id + 1)) self.config_manager.add_routing_instance(vrf_name, + False, + False, import_set, set(), None, @@ -706,6 +705,7 @@ def __init__(self, uuid, obj_dict=None): self.physical_routers = set() self.router_external = False self.vxlan_vni = None + self.forwarding_mode = None self.gateways = None self.instance_ip_map = {} self.update(obj_dict) @@ -722,6 +722,7 @@ def update(self, obj=None): self.router_external = False self.vn_network_id = obj.get('virtual_network_network_id') self.set_vxlan_vni(obj) + self.forwarding_mode = self.get_forwarding_mode(obj) self.routing_instances = set([ri['uuid'] for ri in obj.get('routing_instances', [])]) self.virtual_machine_interfaces = set( @@ -769,6 +770,14 @@ def set_vxlan_vni(self, obj=None): pass #end set_vxlan_vni + def get_forwarding_mode(self, obj): + default_mode = 'l2_l3' + prop = obj.get('virtual_network_properties') + if prop: + return prop.get('forwarding_mode', default_mode) + return default_mode + #end get_forwarding_mode + def update_instance_ip_map(self): self.instance_ip_map = {} for vmi_uuid in self.virtual_machine_interfaces: diff --git a/src/config/device-manager/device_manager/physical_router_config.py b/src/config/device-manager/device_manager/physical_router_config.py index 44617fd8277..c358fc32b90 100644 --- a/src/config/device-manager/device_manager/physical_router_config.py +++ b/src/config/device-manager/device_manager/physical_router_config.py @@ -133,8 +133,10 @@ def add_dynamic_tunnels(self, tunnel_source_ip, ip_fabric_nets, bgp_router_ips): ''' ri_name: routing instance name to be configured on mx + is_l2: a flag used to indicate routing instance type, i.e : l2 or l3 + is_l2_l3: VN forwarding mode is of type 'l2_l3' or not import/export targets: routing instance import, export targets - prefixes: for l3 public vrf static routes, bug#1395938 + prefixes: for l3 vrf static routes and for public vrf filter terms gateways: for l2 evpn, bug#1395944 router_external: this indicates the routing instance configured is for the public network @@ -142,7 +144,7 @@ def add_dynamic_tunnels(self, tunnel_source_ip, ip_fabric_nets, bgp_router_ips): fip_map: contrail instance ip to floating-ip map, used for snat & floating ip support network_id : this is used for configuraing irb interfaces ''' - def add_routing_instance(self, ri_name, import_targets, export_targets, + def add_routing_instance(self, ri_name, is_l2, is_l2_l3, import_targets, export_targets, prefixes=[], gateways=[], router_external=False, interfaces=[], vni=None, fip_map=None, network_id=None): self.routing_instances[ri_name] = {'import_targets': import_targets, @@ -159,7 +161,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, ri = etree.SubElement(ri_config, "instance") etree.SubElement(ri, "name").text = ri_name ri_opt = None - if router_external: + if router_external and is_l2 == False: ri_opt = etree.SubElement(ri, "routing-options") static_config = etree.SubElement(ri_opt, "static") route_config = etree.SubElement(static_config, "route") @@ -170,14 +172,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, etree.SubElement(ri, "vrf-import").text = ri_name + "-import" etree.SubElement(ri, "vrf-export").text = ri_name + "-export" - if vni is None or router_external: - etree.SubElement(ri, "instance-type").text = "vrf" - etree.SubElement(ri, "vrf-table-label") #only for l3 - if fip_map is None: - for interface in interfaces: - if_element = etree.SubElement(ri, "interface") - etree.SubElement(if_element, "name").text = interface - + if not is_l2: if ri_opt is None: ri_opt = etree.SubElement(ri, "routing-options") if prefixes and fip_map is None: @@ -186,6 +181,17 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, route_config = etree.SubElement(static_config, "route") etree.SubElement(route_config, "name").text = prefix etree.SubElement(route_config, "discard") + if router_external: + self.add_to_global_ri_opts(prefix) + + etree.SubElement(ri, "instance-type").text = "vrf" + etree.SubElement(ri, "vrf-table-label") #only for l3 + if fip_map is None: + for interface in interfaces: + if_element = etree.SubElement(ri, "interface") + etree.SubElement(if_element, "name").text = interface + if ri_opt is None: + ri_opt = etree.SubElement(ri, "routing-options") auto_export = "" ri_opt.append(etree.fromstring(auto_export)) else: @@ -314,7 +320,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, bd_config = None interfaces_config = self.interfaces_config proto_config = self.proto_config - if (router_external==False and vni is not None and + if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): etree.SubElement(ri, "vtep-source-interface").text = "lo0.0" bd_config = etree.SubElement(ri, "bridge-domains") @@ -326,26 +332,28 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, for interface in interfaces: if_element = etree.SubElement(bd, "interface") etree.SubElement(if_element, "name").text = interface - etree.SubElement(bd, "routing-interface").text = "irb." + str(network_id) #network_id is unique, hence irb + if is_l2_l3: + etree.SubElement(bd, "routing-interface").text = "irb." + str(network_id) #network_id is unique, hence irb evpn_proto_config = etree.SubElement(ri, "protocols") evpn = etree.SubElement(evpn_proto_config, "evpn") etree.SubElement(evpn, "encapsulation").text = "vxlan" etree.SubElement(evpn, "extended-vni-list").text = "all" interfaces_config = self.interfaces_config or etree.Element("interfaces") - irb_intf = etree.SubElement(interfaces_config, "interface") - etree.SubElement(irb_intf, "name").text = "irb" - etree.SubElement(irb_intf, "gratuitous-arp-reply") - if gateways is not None: - intf_unit = etree.SubElement(irb_intf, "unit") - etree.SubElement(intf_unit, "name").text = str(network_id) - family = etree.SubElement(intf_unit, "family") - inet = etree.SubElement(family, "inet") - for (irb_ip, gateway) in gateways: - addr = etree.SubElement(inet, "address") - etree.SubElement(addr, "name").text = irb_ip - if len(gateway) and gateway != '0.0.0.0': - etree.SubElement(addr, "virtual-gateway-address").text = gateway + if is_l2_l3: + irb_intf = etree.SubElement(interfaces_config, "interface") + etree.SubElement(irb_intf, "name").text = "irb" + etree.SubElement(irb_intf, "gratuitous-arp-reply") + if gateways is not None: + intf_unit = etree.SubElement(irb_intf, "unit") + etree.SubElement(intf_unit, "name").text = str(network_id) + family = etree.SubElement(intf_unit, "family") + inet = etree.SubElement(family, "inet") + for (irb_ip, gateway) in gateways: + addr = etree.SubElement(inet, "address") + etree.SubElement(addr, "name").text = irb_ip + if len(gateway) and gateway != '0.0.0.0': + etree.SubElement(addr, "virtual-gateway-address").text = gateway lo_intf = etree.SubElement(interfaces_config, "interface") etree.SubElement(lo_intf, "name").text = "lo0" @@ -452,6 +460,15 @@ def set_global_routing_options(self, bgp_params): etree.SubElement(self.global_routing_options_config, "router-id").text = bgp_params['address'] #end set_global_routing_options + def add_to_global_ri_opts(self, prefix): + if self.global_routing_options_config is None: + self.global_routing_options_config = etree.Element("routing-options") + static_config = etree.SubElement(self.global_routing_options_config, "static") + route_config = etree.SubElement(static_config, "route") + etree.SubElement(route_config, "name").text = prefix + etree.SubElement(route_config, "discard") + #end add_to_global_ri_opts + def is_family_configured(self, params, family_name): if params is None or params.get('address_families') is None: return False