From 479aad9f2e7e2f755c2c57e0c26ddd981f0e3e0f Mon Sep 17 00:00:00 2001 From: sbalineni Date: Sun, 14 Jun 2015 17:26:38 -0700 Subject: [PATCH] service interfaces need to be configured correctly DM should configure left service interface static route on private-network-nat-vrf, and right-service-interface static route on public-network-vrf. Currently, DM configures lefa and rightt service-interfaces on nat-vrf. A firewall filter need to be created and applied to private vrf irb interface for traffic to go from private vrf to natted-vrf. for l2evpn, router-id configuration is must. Added. both l2 & l3 need to have import export targets as policies, vrf-targets config not required for l2 UT to be done, tracking bug https://bugs.launchpad.net/juniperopenstack/+bug/1465437 Closes-Bug: #1464448 Closes-Bug: #1464456 Closes-Bug: #1464453 Change-Id: I705ef74081ed9342fc881321cfb3f7cd2ac46c0d --- .../device-manager/device_manager/db.py | 11 +- .../device_manager/physical_router_config.py | 106 +++++++++++++----- src/config/utils/provision_physical_router.py | 4 +- 3 files changed, 85 insertions(+), 36 deletions(-) diff --git a/src/config/device-manager/device_manager/db.py b/src/config/device-manager/device_manager/db.py index 00d0b1ba9b7..3974d9f487d 100644 --- a/src/config/device-manager/device_manager/db.py +++ b/src/config/device-manager/device_manager/db.py @@ -133,7 +133,7 @@ def delete(cls, uuid): return obj = cls._dict[uuid] obj.config_manager.delete_bgp_config() - self.uve_send(True) + obj.uve_send(True) obj.update_single_ref('bgp_router', {}) obj.update_multiple_refs('virtual_network', {}) del cls._dict[uuid] @@ -181,6 +181,7 @@ def push_config(self): self.config_manager.add_bgp_peer(peer.params['address'], params, external) self.config_manager.set_bgp_config(bgp_router.params) + self.config_manager.set_global_routing_options(bgp_router.params) bgp_router_ips = bgp_router.get_all_bgp_router_ips() if self.dataplane_ip is not None and self.is_valid_ip(self.dataplane_ip): self.config_manager.add_dynamic_tunnels(self.dataplane_ip, @@ -210,10 +211,10 @@ def push_config(self): vn_dict[vn_id] = [li.name] #for now, assume service port ifls unit numbers are always starts with 0 and goes on - service_port_id = 0 + service_port_id = 1 for vn_id, interfaces in vn_dict.items(): vn_obj = VirtualNetworkDM.get(vn_id) - if vn_obj is None: + if vn_obj is None or vn_obj.vxlan_vni is None: continue export_set = None import_set = None @@ -278,7 +279,7 @@ def push_config(self): False, interfaces, None, - vn_obj.instance_ip_map) + vn_obj.instance_ip_map, vn_obj.vxlan_vni) self.config_manager.send_bgp_config() self.uve_send() @@ -624,7 +625,7 @@ def set_vxlan_vni(self, obj=None): if obj is None: obj = self.read_obj(self.uuid) if GlobalVRouterConfigDM.is_global_vxlan_id_mode_auto(): - self.vxlan_vni = obj['virtual_network_network_id'] + self.vxlan_vni = obj.get('virtual_network_network_id') else: try: prop = obj['virtual_network_properties'] 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 dd4a28f5ade..7fa72ee6d23 100644 --- a/src/config/device-manager/device_manager/physical_router_config.py +++ b/src/config/device-manager/device_manager/physical_router_config.py @@ -131,8 +131,25 @@ def add_dynamic_tunnels(self, tunnel_source_ip, ip_fabric_nets, bgp_router_ips): etree.SubElement(dest_network, "name").text = bgp_router_ip + '/32' #end add_dynamic_tunnels + ''' + ri_name: routing instance name to be configured on mx + import/export targets: routing instance import, export targets + prefixes: for l3 public vrf static routes, bug#1395938 + gateways: for l2 evpn, bug#1395944 + router_external: this indicates the routing instance configured is for + the public network + interfaces: logical interfaces to be part of vrf + fip_map: contrail instance ip to floating-ip map, used for snat & floating ip support + private_vni: This is used only for configuring snat vrf. + private vn routing instance has an irb interface with the unit number + same as network vni. Snat vrf firewall filter should be applied + to private network irb interface, hence needed irb interface unit number. + This allows the traffic flow from private vrf to snat to + public and vice-versa + ''' def add_routing_instance(self, ri_name, import_targets, export_targets, - prefixes=[], gateways=[], router_external=False, interfaces=[], vni=None, fip_map=None): + prefixes=[], gateways=[], router_external=False, + interfaces=[], vni=None, fip_map=None, private_vni=None): self.routing_instances[ri_name] = {'import_targets': import_targets, 'export_targets': export_targets, 'prefixes': prefixes, @@ -144,35 +161,38 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, ri_config = self.ri_config or etree.Element("routing-instances") policy_config = self.policy_config or etree.Element("policy-options") - ri = etree.SubElement(ri_config, "instance", operation="replace") + ri = etree.SubElement(ri_config, "instance") etree.SubElement(ri, "name").text = ri_name ri_opt = None - if vni is None: + if router_external: + ri_opt = etree.SubElement(ri, "routing-options") + static_config = etree.SubElement(ri_opt, "static") + route_config = etree.SubElement(static_config, "route") + etree.SubElement(route_config, "name").text = "0.0.0.0/0" + etree.SubElement(route_config, "next-table").text = "inet.0" + + #for both l2 and l3 + 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" - for interface in interfaces: - if_element = etree.SubElement(ri, "interface") - etree.SubElement(if_element, "name").text = interface - etree.SubElement(ri, "vrf-import").text = ri_name + "-import" - etree.SubElement(ri, "vrf-export").text = ri_name + "-export" - etree.SubElement(ri, "vrf-table-label") + 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 prefixes: - ri_opt = etree.SubElement(ri, "routing-options") - static_config = etree.SubElement(ri_opt, "static") + if prefixes and fip_map is None: + if ri_opt is None: + ri_opt = etree.SubElement(ri, "routing-options") + static_config = etree.SubElement(ri_opt, "static") for prefix in prefixes: route_config = etree.SubElement(static_config, "route") etree.SubElement(route_config, "name").text = prefix etree.SubElement(route_config, "discard") auto_export = "" ri_opt.append(etree.fromstring(auto_export)) - - if router_external: - if ri_opt is None: - ri_opt = etree.SubElement(ri, "routing-options") - static_config = etree.SubElement(ri_opt, "static") - route_config = etree.SubElement(static_config, "route") - etree.SubElement(route_config, "name").text = "0.0.0.0/0" - etree.SubElement(route_config, "next-table").text = "inet.0" else: etree.SubElement(ri, "instance-type").text = "virtual-switch" @@ -183,6 +203,8 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, route_config = etree.SubElement(static_config, "route") etree.SubElement(route_config, "name").text = "0.0.0.0/0" etree.SubElement(route_config, "next-hop").text = interfaces[0] + if_element = etree.SubElement(ri, "interface") + etree.SubElement(if_element, "name").text = interfaces[0] public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: @@ -194,6 +216,8 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, etree.SubElement(ri_public, "name").text = public_vrf ri_opt = etree.SubElement(ri_public, "routing-options") static_config = etree.SubElement(ri_opt, "static") + if_element = etree.SubElement(ri_public, "interface") + etree.SubElement(if_element, "name").text = interfaces[1] for fip in fips: route_config = etree.SubElement(static_config, "route") @@ -229,7 +253,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, # add firewall config for public VRF forwarding_options_config = self.forwarding_options_config firewall_config = self.firewall_config - if router_external: + if router_external or fip_map is not None: forwarding_options_config = self.forwarding_options_config or etree.Element("forwarding-options") fo = etree.SubElement(forwarding_options_config, "family") inet = etree.SubElement(fo, "inet") @@ -238,12 +262,17 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, etree.SubElement(f, "input").text = "redirect_to_" + ri_name[:46] + "_vrf" firewall_config = self.firewall_config or etree.Element("firewall") - f = etree.SubElement(firewall_config, "filter") + fc = etree.SubElement(firewall_config, "family") + inet = etree.SubElement(fc, "inet") + f = etree.SubElement(inet, "filter") etree.SubElement(f, "name").text = "redirect_to_" + ri_name[:46] + "_vrf" term = etree.SubElement(f, "term") etree.SubElement(term, "name").text= "t1" - from_ = etree.SubElement(term, "from") - if prefixes: + if fip_map is not None: + from_ = etree.SubElement(term, "from") + etree.SubElement(from_, "destination-address").text = ';'.join(fip_map.keys()) + elif prefixes: + from_ = etree.SubElement(term, "from") etree.SubElement(from_, "destination-address").text = ';'.join(prefixes) then_ = etree.SubElement(term, "then") etree.SubElement(then_, "routing-instance").text = ri_name @@ -252,23 +281,31 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, then_ = etree.SubElement(term, "then") etree.SubElement(then_, "accept") + if fip_map is not None: + interfaces_config = self.interfaces_config or etree.Element("interfaces") + irb_intf = etree.SubElement(interfaces_config, "interface") + etree.SubElement(irb_intf, "name").text = "irb" + intf_unit = etree.SubElement(irb_intf, "unit") + etree.SubElement(intf_unit, "name").text = str(private_vni) + family = etree.SubElement(intf_unit, "family") + inet = etree.SubElement(family, "inet") + f = etree.SubElement(inet, "filter") + input = etree.SubElement(f, "input") + etree.SubElement(input, "filter-name").text = "redirect_to_" + ri_name[:46] + "_vrf" + # add L2 EVPN and BD config bd_config = None interfaces_config = self.interfaces_config proto_config = self.proto_config - if vni is not None and self.is_family_configured(self.bgp_params, "e-vpn"): + if (router_external==False and vni is not None and + self.is_family_configured(self.bgp_params, "e-vpn")): etree.SubElement(ri, "vtep-source-interface").text = "lo0.0" - rt_element = etree.SubElement(ri, "vrf-target") - #fix me, check if this is correct target value for vrf-target - for route_target in import_targets: - etree.SubElement(rt_element, "community").text = route_target bd_config = etree.SubElement(ri, "bridge-domains") bd= etree.SubElement(bd_config, "domain") etree.SubElement(bd, "name").text = "bd-" + str(vni) etree.SubElement(bd, "vlan-id").text = str(vni) vxlan = etree.SubElement(bd, "vxlan") etree.SubElement(vxlan, "vni").text = str(vni) - etree.SubElement(vxlan, "ingress-node-replication") for interface in interfaces: if_element = etree.SubElement(bd, "interface") etree.SubElement(if_element, "name").text = interface @@ -394,6 +431,12 @@ def add_routing_instance(self, ri_name, import_targets, export_targets, self.ri_config = ri_config # end add_routing_instance + def set_global_routing_options(self, bgp_params): + if bgp_params['address'] is not None: + self.global_routing_options_config = etree.Element("routing-options") + etree.SubElement(self.global_routing_options_config, "router-id").text = bgp_params['address'] + #end set_global_routing_options + def is_family_configured(self, params, family_name): if params is None or params.get('address_families') is None: return False @@ -469,6 +512,7 @@ def reset_bgp_config(self): self.policy_config = None self.firewall_config = None self.forwarding_options_config = None + self.global_routing_options_config = None self.proto_config = None self.route_targets = set() self.bgp_peers = {} @@ -558,6 +602,8 @@ def send_bgp_config(self): config_list.append(self.firewall_config) if self.forwarding_options_config is not None: config_list.append(self.forwarding_options_config) + if self.global_routing_options_config is not None: + config_list.append(self.global_routing_options_config) if self.proto_config is not None: config_list.append(self.proto_config) self.send_netconf(config_list) diff --git a/src/config/utils/provision_physical_router.py b/src/config/utils/provision_physical_router.py index d13a348e573..9724c62b890 100644 --- a/src/config/utils/provision_physical_router.py +++ b/src/config/utils/provision_physical_router.py @@ -389,7 +389,7 @@ def add_bms_config(self): if pr is None: bgp_router, pr = self.create_router('a2-mx-80', '10.84.7.253') - pr.set_virtual_network(vn1_obj) + pr.add_virtual_network(vn1_obj) junos_service_ports = JunosServicePorts() junos_service_ports.service_port.append("si-0/0/0") pr.set_physical_router_junos_service_ports(junos_service_ports) @@ -476,6 +476,8 @@ def add_bms_config(self): vn2_obj.set_router_external(True) vn2_obj.add_network_ipam(ipam_obj, VnSubnetsType([IpamSubnetType(SubnetType("192.168.7.0", 24))])) vn2_uuid = self._vnc_lib.virtual_network_create(vn2_obj) + pr.add_virtual_network(vn2_obj) + self._vnc_lib.physical_router_update(pr) fip_pool = None try: