def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) static_routes = ri_conf.get("static_routes", {}) no_vrf_table_label = ri_conf.get("no_vrf_table_label", False) restrict_proxy_arp = ri_conf.get("restrict_proxy_arp", False) self.routing_instances[ri_name] = ri_conf ri_config = self.ri_config or RoutingInstances() policy_config = self.policy_config or PolicyOptions() ri = Instance(name=ri_name) ri_config.add_instance(ri) ri_opt = None if router_external and is_l2 == False: ri_opt = RoutingInstanceRoutingOptions(static=Static(route=[Route(name="0.0.0.0/0", next_table="inet.0")])) ri.set_routing_options(ri_opt) # for both l2 and l3 ri.set_vrf_import(DMUtils.make_import_name(ri_name)) ri.set_vrf_export(DMUtils.make_export_name(ri_name)) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) if prefixes and fip_map is None: static_config = ri_opt.get_static() if not static_config: static_config = Static() ri_opt.set_static(static_config) rib_config_v6 = None static_config_v6 = None for prefix in prefixes: if ":" in prefix and not rib_config_v6: static_config_v6 = Static() rib_config_v6 = RIB(name=ri_name + ".inet6.0") rib_config_v6.set_static(static_config_v6) ri_opt.set_rib(rib_config_v6) if ":" in prefix: static_config_v6.add_route(Route(name=prefix, discard="")) else: static_config.add_route(Route(name=prefix, discard="")) if router_external: self.add_to_global_ri_opts(prefix) ri.set_instance_type("vrf") if not no_vrf_table_label: ri.set_vrf_table_label("") # only for l3 if fip_map is None: for interface in interfaces: ri.add_interface(Interface(name=interface.name)) if static_routes: self.add_static_routes(ri_opt, static_routes) if has_ipv4_prefixes: ri_opt.set_auto_export(AutoExport(family=Family(inet=FamilyInet(unicast="")))) if has_ipv6_prefixes: ri_opt.set_auto_export(AutoExport(family=Family(inet6=FamilyInet6(unicast="")))) else: ri.set_instance_type("virtual-switch") if fip_map is not None: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) static_config = ri_opt.get_static() if not static_config: static_config = Static() ri_opt.set_static(static_config) static_config.add_route(Route(name="0.0.0.0/0", next_hop=interfaces[0].name)) ri.add_interface(Interface(name=interfaces[0].name)) public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri_public = Instance(name=public_vrf) ri_config.add_instance(ri_public) ri_public.add_interface(Interface(name=interfaces[1].name)) ri_opt = RoutingInstanceRoutingOptions() ri_public.set_routing_options(ri_opt) static_config = Static() ri_opt.set_static(static_config) for fip in fips: static_config.add_route(Route(name=fip + "/32", next_hop=interfaces[1].name)) # add policies for export route targets ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) then = Then() ps.set_term(Term(name="t1", then=then)) for route_target in export_targets: comm = Community(add="", community_name=DMUtils.make_community_name(route_target)) then.add_community(comm) if fip_map is not None: # for nat instance then.set_reject("") else: then.set_accept("") policy_config.add_policy_statement(ps) # add policies for import route targets ps = PolicyStatement(name=DMUtils.make_import_name(ri_name)) from_ = From() term = Term(name="t1", fromxx=from_) ps.set_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) term.set_then(Then(accept="")) ps.set_then(Then(reject="")) policy_config.add_policy_statement(ps) # add firewall config for public VRF forwarding_options_config = self.forwarding_options_config firewall_config = self.firewall_config if router_external and is_l2 == False: forwarding_options_config = self.forwarding_options_config or ForwardingOptions() firewall_config = self.firewall_config or Firewall() if has_ipv4_prefixes and not self.inet4_forwarding_filter: # create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet" ) if has_ipv6_prefixes and not self.inet6_forwarding_filter: # create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet6" ) if has_ipv4_prefixes: # add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.inet4_forwarding_filter.get_term() terms = [term] + (terms or []) self.inet4_forwarding_filter.set_term(terms) if has_ipv6_prefixes: # add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert before the last term terms = self.inet6_forwarding_filter.get_term() terms = [term] + (terms or []) self.inet6_forwarding_filter.set_term(terms) if fip_map is not None: firewall_config = firewall_config or Firewall() f = FirewallFilter(name=DMUtils.make_private_vrf_filter_name(ri_name)) ff = firewall_config.get_family() if not ff: ff = FirewallFamily() firewall_config.set_family(ff) inet = ff.get_inet() if not inet: inet = FirewallInet() ff.set_inet(inet) inet.add_filter(f) term = Term(name=DMUtils.make_vrf_term_name(ri_name)) from_ = From() for fip_user_ip in fip_map.keys(): from_.add_source_address(fip_user_ip) term.set_from(from_) term.set_then(Then(routing_instance=[ri_name])) f.add_term(term) term = Term(name="default-term", then=Then(accept="")) f.add_term(term) interfaces_config = self.interfaces_config or Interfaces() irb_intf = Interface(name="irb") interfaces_config.add_interface(irb_intf) intf_unit = Unit(name=str(network_id)) if restrict_proxy_arp: intf_unit.set_proxy_arp(ProxyArp(restricted="")) inet = FamilyInet() inet.set_filter(InetFilter(input=DMUtils.make_private_vrf_filter_name(ri_name))) intf_unit.set_family(Family(inet=inet)) irb_intf.add_unit(intf_unit) # add L2 EVPN and BD config bd_config = None interfaces_config = self.interfaces_config proto_config = self.proto_config if is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn"): ri.set_vtep_source_interface("lo0.0") bd_config = BridgeDomains() ri.set_bridge_domains(bd_config) bd = Domain(name=DMUtils.make_bridge_name(vni), vlan_id="none", vxlan=VXLan(vni=vni)) bd_config.add_domain(bd) for interface in interfaces: bd.add_interface(Interface(name=interface.name)) if is_l2_l3: # network_id is unique, hence irb bd.set_routing_interface("irb." + str(network_id)) ri.set_protocols(RoutingInstanceProtocols(evpn=Evpn(encapsulation="vxlan", extended_vni_list="all"))) interfaces_config = self.interfaces_config or Interfaces() if is_l2_l3: irb_intf = Interface(name="irb", gratuitous_arp_reply="") interfaces_config.add_interface(irb_intf) if gateways is not None: intf_unit = Unit(name=str(network_id)) irb_intf.add_unit(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (irb_ip, gateway) in gateways: if ":" in irb_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) addr.set_name(irb_ip) if len(gateway) and gateway != "0.0.0.0": addr.set_virtual_gateway_address(gateway) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) fam_inet = FamilyInet(address=[Address(name=self.bgp_params["address"] + "/32", primary="", preferred="")]) intf_unit = Unit(name="0", family=Family(inet=fam_inet)) lo_intf.add_unit(intf_unit) self.build_l2_evpn_interface_config(interfaces_config, interfaces) # fip services config services_config = self.services_config if fip_map is not None: services_config = self.services_config or Services() service_name = DMUtils.make_services_set_name(ri_name) service_set = ServiceSet(name=service_name) services_config.add_service_set(service_set) nat_rule = NATRules(name=service_name + "-sn-rule") service_set.add_nat_rules(NATRules(name=DMUtils.make_snat_rule_name(ri_name))) service_set.add_nat_rules(NATRules(name=DMUtils.make_dnat_rule_name(ri_name))) next_hop_service = NextHopService( inside_service_interface=interfaces[0].name, outside_service_interface=interfaces[1].name ) service_set.set_next_hop_service(next_hop_service) nat = NAT(allow_overlapping_nat_pools="") services_config.add_nat(nat) snat_rule = Rule(name=DMUtils.make_snat_rule_name(ri_name), match_direction="input") nat.add_rule(snat_rule) dnat_rule = Rule(name=DMUtils.make_dnat_rule_name(ri_name), match_direction="output") nat.add_rule(dnat_rule) for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] term = Term(name=DMUtils.make_ip_term_name(pip)) snat_rule.set_term(term) # private ip from_ = From(source_address=[pip + "/32"]) term.set_from(from_) # public ip then_ = Then() term.set_then(then_) translated = Translated(source_prefix=fip + "/32", translation_type=TranslationType(basic_nat44="")) then_.set_translated(translated) term = Term(name=DMUtils.make_ip_term_name(fip)) dnat_rule.set_term(term) # public ip from_ = From(destination_address=[fip + "/32"]) term.set_from(from_) # private ip then_ = Then() term.set_then(then_) translated = Translated(destination_prefix=pip + "/32", translation_type=TranslationType(dnat_44="")) then_.set_translated(translated) interfaces_config = self.interfaces_config or Interfaces() si_intf = Interface(name=interfaces[0].ifd_name) interfaces_config.add_interface(si_intf) intf_unit = Unit(name=interfaces[0].unit) si_intf.add_unit(intf_unit) family = Family(inet=FamilyInet()) intf_unit.set_family(family) intf_unit.set_service_domain("inside") intf_unit = Unit(name=interfaces[1].unit) si_intf.add_unit(intf_unit) family = Family(inet=FamilyInet()) intf_unit.set_family(family) intf_unit.set_service_domain("outside") self.forwarding_options_config = forwarding_options_config self.firewall_config = firewall_config self.policy_config = policy_config self.proto_config = proto_config self.interfaces_config = interfaces_config self.services_config = services_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) network_id = ri_conf.get("network_id", None) self.routing_instances[ri_name] = ri_conf ri_config = self.ri_config or RoutingInstances( comment=DMUtils.routing_instances_comment()) policy_config = self.policy_config or PolicyOptions( comment=DMUtils.policy_options_comment()) ri = Instance(name=ri_name) ri_config.add_instance(ri) ri_opt = None # for both l2 and l3 ri.set_vrf_import(DMUtils.make_import_name(ri_name)) ri.set_vrf_export(DMUtils.make_export_name(ri_name)) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) ri.set_instance_type("vrf") for interface in interfaces: ri.add_interface(Interface(name=interface.name)) family = Family() if has_ipv4_prefixes: family.set_inet(FamilyInet(unicast='')) if has_ipv6_prefixes: family.set_inet6(FamilyInet6(unicast='')) if has_ipv4_prefixes or has_ipv6_prefixes: auto_export = AutoExport(family=family) ri_opt.set_auto_export(auto_export) else: ri.set_instance_type("virtual-switch") # add policies for export route targets ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Export")) then = Then() ps.add_term(Term(name="t1", then=then)) for route_target in export_targets: comm = Community( add='', community_name=DMUtils.make_community_name(route_target)) then.add_community(comm) then.set_accept('') self.add_vni_option(network_id, DMUtils.make_community_name(route_target)) policy_config.add_policy_statement(ps) self.add_to_global_switch_opts(DMUtils.make_export_name(ri_name), False) # add policies for import route targets ps = PolicyStatement(name=DMUtils.make_import_name(ri_name)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Import")) from_ = From() term = Term(name="t1", fromxx=from_) ps.add_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) self.add_vni_option(network_id, DMUtils.make_community_name(route_target)) term.set_then(Then(accept='')) ps.set_then(Then(reject='')) policy_config.add_policy_statement(ps) self.add_to_global_switch_opts(DMUtils.make_import_name(ri_name), True) # add vlan config if is_l2 and vni and self.is_family_configured(self.bgp_params, "e-vpn"): self.add_vlan_config(ri_name, vni) # add L2 EVPN and BD config interfaces_config = self.interfaces_config proto_config = self.proto_config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): ri.set_vtep_source_interface("lo0.0") evpn = Evpn(encapsulation='vxlan', extended_vni_list='all') self.set_evpn_default_gateway_params(evpn) ri.set_protocols(RoutingInstanceProtocols(evpn=evpn)) interfaces_config = self.interfaces_config or Interfaces( comment=DMUtils.interfaces_comment()) if is_l2_l3: irb_intf = Interface(name='irb', gratuitous_arp_reply='') interfaces_config.add_interface(irb_intf) if gateways is not None: intf_unit = Unit(name=str(network_id), comment=DMUtils.vn_irb_comment( vn, False, is_l2_l3)) irb_intf.add_unit(intf_unit) if self.is_spine(): intf_unit.set_proxy_macip_advertisement('') family = Family() intf_unit.set_family(family) inet = None inet6 = None for (irb_ip, gateway) in gateways: if ':' in irb_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) addr.set_name(irb_ip) addr.set_comment(DMUtils.irb_ip_comment(irb_ip)) if len(gateway) and gateway != '0.0.0.0': addr.set_virtual_gateway_address(gateway) self.build_l2_evpn_interface_config(interfaces_config, interfaces, vn) if (not is_l2 and not is_l2_l3 and gateways): interfaces_config = self.interfaces_config or Interfaces( comment=DMUtils.interfaces_comment()) ifl_num = str(1000 + int(network_id)) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) intf_unit = Unit(name=ifl_num, comment=DMUtils.l3_lo_intf_comment(vn)) lo_intf.add_unit(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) lo_ip = ip + '/' + '128' else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) lo_ip = ip + '/' + '32' addr.set_name(lo_ip) addr.set_comment(DMUtils.lo0_ip_comment(subnet)) ri.add_interface( Interface(name="lo0." + ifl_num, comment=DMUtils.lo0_ri_intf_comment(vn))) self.policy_config = policy_config self.proto_config = proto_config self.interfaces_config = interfaces_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) is_internal_vn = True if '_contrail_lr_internal_vn_' in vn.name else False highest_encapsulation_priority = \ ri_conf.get("highest_encapsulation_priority") or "MPLSoGRE" self.routing_instances[ri_name] = ri_conf self.ri_config = self.ri_config or [] self.policy_config = self.policy_config or\ Policy(comment=DMUtils.policy_options_comment()) ri = RoutingInstance(name=ri_name) if vn: is_nat = True if fip_map else False ri.set_comment( DMUtils.vn_ri_comment(vn, is_l2, is_l2_l3, is_nat, router_external)) self.ri_config.append(ri) ri.set_is_public_network(router_external) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: ri.set_instance_type("vrf") if fip_map is None: for interface in interfaces: ri.add_interfaces(LogicalInterface(name=interface.name)) else: if highest_encapsulation_priority == "VXLAN": ri.set_routing_instance_type("virtual-switch") elif highest_encapsulation_priority in ["MPLSoGRE", "MPLSoUDP"]: ri.set_routing_instance_type("evpn") if is_internal_vn: self.internal_vn_ris.append(ri) self.add_bogus_lo0(ri, network_id, vn) if self.is_spine() and is_l2_l3: self.add_irb_config(ri_conf) self.attach_irb(ri_conf, ri) if fip_map is not None: ri.add_interfaces(LogicalInterface(name=interfaces[0].name)) public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): floating_ips = [] ri.add_floating_ip_list( FloatingIpList(public_routing_instance=public_vrf, floating_ips=floating_ips)) for fip in fips: floating_ips.append(FloatingIpMap(floating_ip=fip)) # add policies for export route targets if self.is_spine(): p = PolicyRule(name=DMUtils.make_export_name(ri_name)) p.set_comment(DMUtils.vn_ps_comment(vn, "Export")) then = Then() p.add_term(Term(name="t1", then=then)) for route_target in export_targets: then.add_community(DMUtils.make_community_name(route_target)) then.set_accept_or_reject(True) self.policy_config.add_policy_rule(p) # add policies for import route targets p = PolicyRule(name=DMUtils.make_import_name(ri_name)) p.set_comment(DMUtils.vn_ps_comment(vn, "Import")) # add term switch policy from_ = From() term = Term(name=DMUtils.get_switch_policy_name(), fromxx=from_) p.add_term(term) from_.add_community(DMUtils.get_switch_policy_name()) term.set_then(Then(accept_or_reject=True)) from_ = From() term = Term(name="t1", fromxx=from_) p.add_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) if not is_internal_vn: self.add_vni_option(vni or network_id, route_target) term.set_then(Then(accept_or_reject=True)) self.policy_config.add_policy_rule(p) # add L2 EVPN and BD config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): # add vlan config vlan_conf = self.add_vlan_config(ri_name, vni, is_l2_l3, "irb." + str(network_id)) self.interfaces_config = self.interfaces_config or [] self.build_l2_evpn_interface_config(self.interfaces_config, interfaces, vn, vlan_conf) if (not is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): ri.set_vtep_source_interface("lo0.0") evpn = self.build_evpn_config() if evpn: ri.set_protocols(RoutingInstanceProtocols(evpn=evpn)) #add vlans self.add_ri_vlan_config(ri, vni) if (not is_l2 and not is_l2_l3 and gateways): self.interfaces_config = self.interfaces_config or [] ifl_num = str(1000 + int(network_id)) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) intf_unit = Unit(name=ifl_num, comment=DMUtils.l3_lo_intf_comment(vn)) lo_intf.add_logical_interfaces(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) lo_ip = ip + '/' + '128' else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) lo_ip = ip + '/' + '32' addr.set_name(lo_ip) addr.set_comment(DMUtils.lo0_ip_comment(subnet)) ri.add_interface( Interface(name="lo0." + ifl_num, comment=DMUtils.lo0_ri_intf_comment(vn))) self.route_targets |= import_targets | export_targets
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) network_id = ri_conf.get("network_id", None) is_internal_vn = True if '_contrail_lr_internal_vn_' in vn.name else False self.routing_instances[ri_name] = ri_conf ri_config = None policy_config = self.policy_config or \ PolicyOptions(comment=DMUtils.policy_options_comment()) ri = None ri_opt = None ri_config = self.ri_config or \ RoutingInstances(comment=DMUtils.routing_instances_comment()) ri = Instance(name=ri_name) if not is_l2: ri_config.add_instance(ri) ri.set_vrf_import(DMUtils.make_import_name(ri_name)) ri.set_vrf_export(DMUtils.make_export_name(ri_name)) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) ri.set_instance_type("vrf") for interface in interfaces: ri.add_interface(Interface(name=interface.name)) family = Family() if has_ipv4_prefixes: family.set_inet(FamilyInet(unicast='')) if has_ipv6_prefixes: family.set_inet6(FamilyInet6(unicast='')) if has_ipv4_prefixes or has_ipv6_prefixes: auto_export = AutoExport(family=family) ri_opt.set_auto_export(auto_export) if is_internal_vn: self.internal_vn_ris.append(ri) self.add_bogus_lo0(ri, network_id, vn) if self.is_spine() and is_l2_l3: self.add_irb_config(ri_conf) self.attach_irb(ri_conf, ri) # add policies for export route targets if self.is_spine(): ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Export")) then = Then() ps.add_term(Term(name="t1", then=then)) for route_target in export_targets: comm = Community( add='', community_name=DMUtils.make_community_name(route_target)) then.add_community(comm) then.set_accept('') policy_config.add_policy_statement(ps) self.add_to_global_switch_opts(DMUtils.make_export_name(ri_name), False) # add policies for import route targets ps = PolicyStatement(name=DMUtils.make_import_name(ri_name)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Import")) # add term switch policy from_ = From() term = Term(name=DMUtils.get_switch_policy_name(), fromxx=from_) ps.add_term(term) from_.add_community(DMUtils.get_switch_policy_name()) term.set_then(Then(accept='')) from_ = From() term = Term(name="t1", fromxx=from_) ps.add_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) if not is_internal_vn: self.add_vni_option(vni or network_id, route_target) term.set_then(Then(accept='')) policy_config.add_policy_statement(ps) self.add_to_global_switch_opts(DMUtils.make_import_name(ri_name), True) # add L2 EVPN and BD config interfaces_config = self.interfaces_config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): # add vlan config vlan_conf = self.add_vlan_config(ri_name, vni, is_l2_l3, "irb." + str(network_id)) interfaces_config = self.interfaces_config or Interfaces( comment=DMUtils.interfaces_comment()) self.build_l2_evpn_interface_config(interfaces_config, interfaces, vn, vlan_conf) if (not is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): ri.set_vtep_source_interface("lo0.0") evpn = self.build_evpn_config() if evpn: ri.set_protocols(RoutingInstanceProtocols(evpn=evpn)) #add vlans self.add_ri_vlan_config(ri, vni) if (not is_l2 and not is_l2_l3 and gateways): interfaces_config = self.interfaces_config or \ Interfaces(comment=DMUtils.interfaces_comment()) ifl_num = str(1000 + int(network_id)) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) intf_unit = Unit(name=ifl_num, comment=DMUtils.l3_lo_intf_comment(vn)) lo_intf.add_unit(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) lo_ip = ip + '/' + '128' else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) lo_ip = ip + '/' + '32' addr.set_name(lo_ip) addr.set_comment(DMUtils.lo0_ip_comment(subnet)) ri.add_interface( Interface(name="lo0." + ifl_num, comment=DMUtils.lo0_ri_intf_comment(vn))) self.policy_config = policy_config self.interfaces_config = interfaces_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) static_routes = ri_conf.get("static_routes", {}) no_vrf_table_label = ri_conf.get("no_vrf_table_label", False) restrict_proxy_arp = ri_conf.get("restrict_proxy_arp", False) self.routing_instances[ri_name] = ri_conf 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") etree.SubElement(ri, "name").text = ri_name ri_opt = None 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") 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 = DMUtils.make_import_name(ri_name) etree.SubElement(ri, "vrf-export").text = DMUtils.make_export_name(ri_name) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = etree.SubElement(ri, "routing-options") if prefixes and fip_map is None: static_config = etree.SubElement(ri_opt, "static") rib_config_v6 = None static_config_v6 = None for prefix in prefixes: if ':' in prefix and not rib_config_v6: rib_config_v6 = etree.SubElement(ri_opt, "rib") etree.SubElement(rib_config_v6, "name").text = ri_name + ".inet6.0" static_config_v6 = etree.SubElement( rib_config_v6, "static") if ':' in prefix: route_config = etree.SubElement( static_config_v6, "route") else: 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" if not no_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.name if ri_opt is None: ri_opt = etree.SubElement(ri, "routing-options") if static_routes: self.add_static_routes(ri_opt, static_routes) if has_ipv4_prefixes: auto_export = """<auto-export> <family><inet><unicast/></inet></family> </auto-export>""" ri_opt.append(etree.fromstring(auto_export)) if has_ipv6_prefixes: auto_export = """<auto-export> <family><inet6><unicast/></inet6></family> </auto-export>""" ri_opt.append(etree.fromstring(auto_export)) else: etree.SubElement(ri, "instance-type").text = "virtual-switch" if fip_map is not None: 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-hop").text = interfaces[0].name if_element = etree.SubElement(ri, "interface") etree.SubElement(if_element, "name").text = interfaces[0].name public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri_public = etree.SubElement(ri_config, "instance") 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].name for fip in fips: route_config = etree.SubElement(static_config, "route") etree.SubElement(route_config, "name").text = fip + "/32" etree.SubElement(route_config, "next-hop").text = interfaces[1].name # add policies for export route targets ps = etree.SubElement(policy_config, "policy-statement") etree.SubElement(ps, "name").text = DMUtils.make_export_name(ri_name) term = etree.SubElement(ps, "term") etree.SubElement(term, "name").text = "t1" then = etree.SubElement(term, "then") for route_target in export_targets: comm = etree.SubElement(then, "community") etree.SubElement(comm, "add") etree.SubElement( comm, "community-name").text = DMUtils.make_community_name( route_target) if fip_map is not None: # for nat instance etree.SubElement(then, "reject") else: etree.SubElement(then, "accept") # add policies for import route targets ps = etree.SubElement(policy_config, "policy-statement") etree.SubElement(ps, "name").text = DMUtils.make_import_name(ri_name) term = etree.SubElement(ps, "term") etree.SubElement(term, "name").text = "t1" from_ = etree.SubElement(term, "from") for route_target in import_targets: target_name = DMUtils.make_community_name(route_target) etree.SubElement(from_, "community").text = target_name then = etree.SubElement(term, "then") etree.SubElement(then, "accept") then = etree.SubElement(ps, "then") etree.SubElement(then, "reject") # add firewall config for public VRF forwarding_options_config = self.forwarding_options_config firewall_config = self.firewall_config if router_external and is_l2 == False: forwarding_options_config = (self.forwarding_options_config or etree.Element("forwarding-options")) firewall_config = self.firewall_config or etree.Element("firewall") if has_ipv4_prefixes and not self.inet4_forwarding_filter: #create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet4", "inet") if has_ipv6_prefixes and not self.inet6_forwarding_filter: #create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet6", "inet6") if has_ipv4_prefixes: #add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert after 'name' element but before the last term self.inet4_forwarding_filter.insert(1, term) if has_ipv6_prefixes: #add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert after 'name' element but before the last term self.inet6_forwarding_filter.insert(1, term) if fip_map is not None: firewall_config = self.firewall_config or etree.Element("firewall") fc = etree.SubElement(firewall_config, "family") inet = etree.SubElement(fc, "inet") f = etree.SubElement(inet, "filter") etree.SubElement( f, "name").text = DMUtils.make_private_vrf_filter_name(ri_name) term = etree.SubElement(f, "term") etree.SubElement(term, "name").text = DMUtils.make_vrf_term_name(ri_name) from_ = etree.SubElement(term, "from") for fip_user_ip in fip_map.keys(): etree.SubElement(from_, "source-address").text = fip_user_ip then_ = etree.SubElement(term, "then") etree.SubElement(then_, "routing-instance").text = ri_name term = etree.SubElement(f, "term") etree.SubElement(term, "name").text = "default-term" then_ = etree.SubElement(term, "then") etree.SubElement(then_, "accept") 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(network_id) if restrict_proxy_arp: proxy_arp = etree.SubElement(intf_unit, "proxy-arp") etree.SubElement(proxy_arp, "restricted") family = etree.SubElement(intf_unit, "family") inet = etree.SubElement(family, "inet") f = etree.SubElement(inet, "filter") iput = etree.SubElement(f, "input") etree.SubElement( iput, "filter-name").text = DMUtils.make_private_vrf_filter_name( ri_name) # add L2 EVPN and BD config bd_config = None interfaces_config = self.interfaces_config proto_config = self.proto_config 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") bd = etree.SubElement(bd_config, "domain") etree.SubElement(bd, "name").text = DMUtils.make_bridge_name(vni) etree.SubElement(bd, "vlan-id").text = 'none' vxlan = etree.SubElement(bd, "vxlan") etree.SubElement(vxlan, "vni").text = str(vni) for interface in interfaces: if_element = etree.SubElement(bd, "interface") etree.SubElement(if_element, "name").text = interface.name if is_l2_l3: # network_id is unique, hence irb etree.SubElement( bd, "routing-interface").text = "irb." + str(network_id) 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") 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 = None inet6 = None for (irb_ip, gateway) in gateways: if ':' in irb_ip: if not inet6: inet6 = etree.SubElement(family, "inet6") addr = etree.SubElement(inet6, "address") else: if not inet: inet = etree.SubElement(family, "inet") 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" intf_unit = etree.SubElement(lo_intf, "unit") etree.SubElement(intf_unit, "name").text = "0" family = etree.SubElement(intf_unit, "family") inet = etree.SubElement(family, "inet") addr = etree.SubElement(inet, "address") etree.SubElement(addr, "name").text = self.bgp_params['address'] + "/32" etree.SubElement(addr, "primary") etree.SubElement(addr, "preferred") self.build_l2_evpn_interface_config(interfaces_config, interfaces) # fip services config services_config = self.services_config if fip_map is not None: services_config = self.services_config or etree.Element("services") # mx has limitation for service-set and nat-rule name length, # allowed max 63 chars service_name = DMUtils.make_services_set_name(ri_name) service_set = etree.SubElement(services_config, "service-set") etree.SubElement(service_set, "name").text = service_name nat_rule = etree.SubElement(service_set, "nat-rules") etree.SubElement( nat_rule, "name").text = DMUtils.make_snat_rule_name(ri_name) nat_rule = etree.SubElement(service_set, "nat-rules") etree.SubElement( nat_rule, "name").text = DMUtils.make_dnat_rule_name(ri_name) next_hop_service = etree.SubElement(service_set, "next-hop-service") etree.SubElement( next_hop_service, "inside-service-interface").text = interfaces[0].name etree.SubElement( next_hop_service, "outside-service-interface").text = interfaces[1].name nat = etree.SubElement(services_config, "nat") etree.SubElement(nat, "allow-overlapping-nat-pools") snat_rule = etree.SubElement(nat, "rule") etree.SubElement( snat_rule, "name").text = DMUtils.make_snat_rule_name(ri_name) etree.SubElement(snat_rule, "match-direction").text = "input" dnat_rule = etree.SubElement(nat, "rule") etree.SubElement( dnat_rule, "name").text = DMUtils.make_dnat_rule_name(ri_name) etree.SubElement(dnat_rule, "match-direction").text = "output" for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] term = etree.SubElement(snat_rule, "term") etree.SubElement(term, "name").text = DMUtils.make_ip_term_name(pip) from_ = etree.SubElement(term, "from") src_addr = etree.SubElement(from_, "source-address") # private ip etree.SubElement(src_addr, "name").text = pip + "/32" then_ = etree.SubElement(term, "then") translated = etree.SubElement(then_, "translated") etree.SubElement( translated, "source-prefix").text = fip + "/32" # public ip translation_type = etree.SubElement(translated, "translation-type") etree.SubElement(translation_type, "basic-nat44") term = etree.SubElement(dnat_rule, "term") etree.SubElement(term, "name").text = DMUtils.make_ip_term_name(fip) from_ = etree.SubElement(term, "from") src_addr = etree.SubElement(from_, "destination-address") etree.SubElement(src_addr, "name").text = fip + "/32" # public ip then_ = etree.SubElement(term, "then") translated = etree.SubElement(then_, "translated") etree.SubElement( translated, "destination-prefix").text = pip + "/32" # source ip translation_type = etree.SubElement(translated, "translation-type") etree.SubElement(translation_type, "dnat-44") interfaces_config = self.interfaces_config or etree.Element( "interfaces") si_intf = etree.SubElement(interfaces_config, "interface") etree.SubElement(si_intf, "name").text = interfaces[0].ifd_name intf_unit = etree.SubElement(si_intf, "unit") etree.SubElement(intf_unit, "name").text = interfaces[0].unit family = etree.SubElement(intf_unit, "family") etree.SubElement(family, "inet") etree.SubElement(intf_unit, "service-domain").text = "inside" intf_unit = etree.SubElement(si_intf, "unit") etree.SubElement(intf_unit, "name").text = interfaces[1].unit family = etree.SubElement(intf_unit, "family") etree.SubElement(family, "inet") etree.SubElement(intf_unit, "service-domain").text = "outside" self.forwarding_options_config = forwarding_options_config self.firewall_config = firewall_config self.policy_config = policy_config self.proto_config = proto_config self.interfaces_config = interfaces_config self.services_config = services_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) static_routes = ri_conf.get("static_routes", {}) no_vrf_table_label = ri_conf.get("no_vrf_table_label", False) restrict_proxy_arp = ri_conf.get("restrict_proxy_arp", False) highest_enapsulation_priority = \ ri_conf.get("highest_enapsulation_priority") or "MPLSoGRE" self.routing_instances[ri_name] = ri_conf ri_config = self.ri_config or RoutingInstances() policy_config = self.policy_config or PolicyOptions() ri = Instance(name=ri_name) ri_config.add_instance(ri) ri_opt = None if router_external and is_l2 == False: ri_opt = RoutingInstanceRoutingOptions(static=Static( route=[Route(name="0.0.0.0/0", next_table="inet.0")])) ri.set_routing_options(ri_opt) # for both l2 and l3 ri.set_vrf_import(DMUtils.make_import_name(ri_name)) ri.set_vrf_export(DMUtils.make_export_name(ri_name)) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) if prefixes and fip_map is None: static_config = ri_opt.get_static() if not static_config: static_config = Static() ri_opt.set_static(static_config) rib_config_v6 = None static_config_v6 = None for prefix in prefixes: if ':' in prefix and not rib_config_v6: static_config_v6 = Static() rib_config_v6 = RIB(name=ri_name + ".inet6.0") rib_config_v6.set_static(static_config_v6) ri_opt.set_rib(rib_config_v6) if ':' in prefix: static_config_v6.add_route( Route(name=prefix, discard='')) else: static_config.add_route(Route(name=prefix, discard='')) if router_external: self.add_to_global_ri_opts(prefix) ri.set_instance_type("vrf") if not no_vrf_table_label: ri.set_vrf_table_label('') # only for l3 if fip_map is None: for interface in interfaces: ri.add_interface(Interface(name=interface.name)) if static_routes: self.add_static_routes(ri_opt, static_routes) if has_ipv4_prefixes: ri_opt.set_auto_export( AutoExport(family=Family(inet=FamilyInet(unicast='')))) if has_ipv6_prefixes: ri_opt.set_auto_export( AutoExport(family=Family(inet6=FamilyInet6(unicast='')))) else: if highest_enapsulation_priority == "VXLAN": ri.set_instance_type("virtual-switch") elif highest_enapsulation_priority in ["MPLSoGRE", "MPLSoUDP"]: ri.set_instance_type("evpn") if fip_map is not None: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) static_config = ri_opt.get_static() if not static_config: static_config = Static() ri_opt.set_static(static_config) static_config.add_route( Route(name="0.0.0.0/0", next_hop=interfaces[0].name)) ri.add_interface(Interface(name=interfaces[0].name)) public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri_public = Instance(name=public_vrf) ri_config.add_instance(ri_public) ri_public.add_interface(Interface(name=interfaces[1].name)) ri_opt = RoutingInstanceRoutingOptions() ri_public.set_routing_options(ri_opt) static_config = Static() ri_opt.set_static(static_config) for fip in fips: static_config.add_route( Route(name=fip + "/32", next_hop=interfaces[1].name)) # add policies for export route targets ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) then = Then() ps.set_term(Term(name="t1", then=then)) for route_target in export_targets: comm = Community( add='', community_name=DMUtils.make_community_name(route_target)) then.add_community(comm) if fip_map is not None: # for nat instance then.set_reject('') else: then.set_accept('') policy_config.add_policy_statement(ps) # add policies for import route targets ps = PolicyStatement(name=DMUtils.make_import_name(ri_name)) from_ = From() term = Term(name="t1", fromxx=from_) ps.set_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) term.set_then(Then(accept='')) ps.set_then(Then(reject='')) policy_config.add_policy_statement(ps) # add firewall config for public VRF forwarding_options_config = self.forwarding_options_config firewall_config = self.firewall_config if router_external and is_l2 == False: forwarding_options_config = (self.forwarding_options_config or ForwardingOptions()) firewall_config = self.firewall_config or Firewall() if has_ipv4_prefixes and not self.inet4_forwarding_filter: #create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet") if has_ipv6_prefixes and not self.inet6_forwarding_filter: #create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet6") if has_ipv4_prefixes: #add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.inet4_forwarding_filter.get_term() terms = [term] + (terms or []) self.inet4_forwarding_filter.set_term(terms) if has_ipv6_prefixes: #add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert before the last term terms = self.inet6_forwarding_filter.get_term() terms = [term] + (terms or []) self.inet6_forwarding_filter.set_term(terms) if fip_map is not None: firewall_config = firewall_config or Firewall() f = FirewallFilter( name=DMUtils.make_private_vrf_filter_name(ri_name)) ff = firewall_config.get_family() if not ff: ff = FirewallFamily() firewall_config.set_family(ff) inet = ff.get_inet() if not inet: inet = FirewallInet() ff.set_inet(inet) inet.add_filter(f) term = Term(name=DMUtils.make_vrf_term_name(ri_name)) from_ = From() for fip_user_ip in fip_map.keys(): from_.add_source_address(fip_user_ip) term.set_from(from_) term.set_then(Then(routing_instance=[ri_name])) f.add_term(term) term = Term(name="default-term", then=Then(accept='')) f.add_term(term) interfaces_config = self.interfaces_config or Interfaces() irb_intf = Interface(name="irb") interfaces_config.add_interface(irb_intf) intf_unit = Unit(name=str(network_id)) if restrict_proxy_arp: intf_unit.set_proxy_arp(ProxyArp(restricted='')) inet = FamilyInet() inet.set_filter( InetFilter( input=DMUtils.make_private_vrf_filter_name(ri_name))) intf_unit.set_family(Family(inet=inet)) irb_intf.add_unit(intf_unit) # add L2 EVPN and BD config bd_config = None interfaces_config = self.interfaces_config proto_config = self.proto_config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): ri.set_vtep_source_interface("lo0.0") if highest_enapsulation_priority == "VXLAN": bd_config = BridgeDomains() ri.set_bridge_domains(bd_config) bd = Domain(name=DMUtils.make_bridge_name(vni), vlan_id='none', vxlan=VXLan(vni=vni)) bd_config.add_domain(bd) for interface in interfaces: bd.add_interface(Interface(name=interface.name)) if is_l2_l3: # network_id is unique, hence irb bd.set_routing_interface("irb." + str(network_id)) ri.set_protocols( RoutingInstanceProtocols(evpn=Evpn( encapsulation='vxlan', extended_vni_list='all'))) elif highest_enapsulation_priority in ["MPLSoGRE", "MPLSoUDP"]: ri.set_vlan_id('none') if is_l2_l3: # network_id is unique, hence irb ri.set_routing_interface("irb." + str(network_id)) evpn = Evpn() for interface in interfaces: evpn.add_interface(Interface(name=interface.name)) ri.set_protocols(RoutingInstanceProtocols(evpn=evpn)) interfaces_config = self.interfaces_config or Interfaces() if is_l2_l3: irb_intf = Interface(name='irb', gratuitous_arp_reply='') interfaces_config.add_interface(irb_intf) if gateways is not None: intf_unit = Unit(name=str(network_id)) irb_intf.add_unit(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (irb_ip, gateway) in gateways: if ':' in irb_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) addr.set_name(irb_ip) if len(gateway) and gateway != '0.0.0.0': addr.set_virtual_gateway_address(gateway) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) fam_inet = FamilyInet(address=[ Address(name=self.bgp_params['address'] + "/32", primary='', preferred='') ]) intf_unit = Unit(name="0", family=Family(inet=fam_inet)) lo_intf.add_unit(intf_unit) self.build_l2_evpn_interface_config(interfaces_config, interfaces) if (not is_l2 and not is_l2_l3 and gateways): interfaces_config = self.interfaces_config or Interfaces() ifl_num = str(1000 + int(network_id)) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) intf_unit = Unit(name=ifl_num) lo_intf.add_unit(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (lo_ip, _) in gateways: (ip, _) = lo_ip.split('/') if ':' in lo_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) lo_ip = ip + '/' + '128' else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) lo_ip = ip + '/' + '32' addr.set_name(lo_ip) ri.add_interface(Interface(name="lo0." + ifl_num)) # fip services config services_config = self.services_config if fip_map is not None: services_config = self.services_config or Services() service_name = DMUtils.make_services_set_name(ri_name) service_set = ServiceSet(name=service_name) services_config.add_service_set(service_set) nat_rule = NATRules(name=service_name + "-sn-rule") service_set.add_nat_rules( NATRules(name=DMUtils.make_snat_rule_name(ri_name))) service_set.add_nat_rules( NATRules(name=DMUtils.make_dnat_rule_name(ri_name))) next_hop_service = NextHopService( inside_service_interface=interfaces[0].name, outside_service_interface=interfaces[1].name) service_set.set_next_hop_service(next_hop_service) nat = NAT(allow_overlapping_nat_pools='') services_config.add_nat(nat) snat_rule = Rule(name=DMUtils.make_snat_rule_name(ri_name), match_direction="input") nat.add_rule(snat_rule) dnat_rule = Rule(name=DMUtils.make_dnat_rule_name(ri_name), match_direction="output") nat.add_rule(dnat_rule) for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] term = Term(name=DMUtils.make_ip_term_name(pip)) snat_rule.set_term(term) # private ip from_ = From(source_address=[pip + "/32"]) term.set_from(from_) # public ip then_ = Then() term.set_then(then_) translated = Translated( source_prefix=fip + "/32", translation_type=TranslationType(basic_nat44='')) then_.set_translated(translated) term = Term(name=DMUtils.make_ip_term_name(fip)) dnat_rule.set_term(term) # public ip from_ = From(destination_address=[fip + "/32"]) term.set_from(from_) # private ip then_ = Then() term.set_then(then_) translated = Translated( destination_prefix=pip + "/32", translation_type=TranslationType(dnat_44='')) then_.set_translated(translated) interfaces_config = self.interfaces_config or Interfaces() si_intf = Interface(name=interfaces[0].ifd_name) interfaces_config.add_interface(si_intf) intf_unit = Unit(name=interfaces[0].unit) si_intf.add_unit(intf_unit) family = Family(inet=FamilyInet()) intf_unit.set_family(family) intf_unit.set_service_domain("inside") intf_unit = Unit(name=interfaces[1].unit) si_intf.add_unit(intf_unit) family = Family(inet=FamilyInet()) intf_unit.set_family(family) intf_unit.set_service_domain("outside") self.forwarding_options_config = forwarding_options_config self.firewall_config = firewall_config self.policy_config = policy_config self.proto_config = proto_config self.interfaces_config = interfaces_config self.services_config = services_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) static_routes = ri_conf.get("static_routes", {}) no_vrf_table_label = ri_conf.get("no_vrf_table_label", False) restrict_proxy_arp = ri_conf.get("restrict_proxy_arp", False) self.routing_instances[ri_name] = ri_conf 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") etree.SubElement(ri, "name").text = ri_name ri_opt = None 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") 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 = DMUtils.make_import_name(ri_name) etree.SubElement(ri, "vrf-export").text = DMUtils.make_export_name(ri_name) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = etree.SubElement(ri, "routing-options") if prefixes and fip_map is None: static_config = etree.SubElement(ri_opt, "static") rib_config_v6 = None static_config_v6 = None for prefix in prefixes: if ':' in prefix and not rib_config_v6: rib_config_v6 = etree.SubElement(ri_opt, "rib") etree.SubElement(rib_config_v6, "name").text = ri_name + ".inet6.0" static_config_v6 = etree.SubElement(rib_config_v6, "static") if ':' in prefix: route_config = etree.SubElement(static_config_v6, "route") else: 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" if not no_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.name if ri_opt is None: ri_opt = etree.SubElement(ri, "routing-options") if static_routes: self.add_static_routes(ri_opt, static_routes) if has_ipv4_prefixes: auto_export = """<auto-export> <family><inet><unicast/></inet></family> </auto-export>""" ri_opt.append(etree.fromstring(auto_export)) if has_ipv6_prefixes: auto_export = """<auto-export> <family><inet6><unicast/></inet6></family> </auto-export>""" ri_opt.append(etree.fromstring(auto_export)) else: etree.SubElement(ri, "instance-type").text = "virtual-switch" if fip_map is not None: 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-hop").text = interfaces[0].name if_element = etree.SubElement(ri, "interface") etree.SubElement(if_element, "name").text = interfaces[0].name public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri_public = etree.SubElement(ri_config, "instance") 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].name for fip in fips: route_config = etree.SubElement(static_config, "route") etree.SubElement(route_config, "name").text = fip + "/32" etree.SubElement( route_config, "next-hop").text = interfaces[1].name # add policies for export route targets ps = etree.SubElement(policy_config, "policy-statement") etree.SubElement(ps, "name").text = DMUtils.make_export_name(ri_name) term = etree.SubElement(ps, "term") etree.SubElement(term, "name").text = "t1" then = etree.SubElement(term, "then") for route_target in export_targets: comm = etree.SubElement(then, "community") etree.SubElement(comm, "add") etree.SubElement( comm, "community-name").text = DMUtils.make_community_name(route_target) if fip_map is not None: # for nat instance etree.SubElement(then, "reject") else: etree.SubElement(then, "accept") # add policies for import route targets ps = etree.SubElement(policy_config, "policy-statement") etree.SubElement(ps, "name").text = DMUtils.make_import_name(ri_name) term = etree.SubElement(ps, "term") etree.SubElement(term, "name").text = "t1" from_ = etree.SubElement(term, "from") for route_target in import_targets: target_name = DMUtils.make_community_name(route_target) etree.SubElement(from_, "community").text = target_name then = etree.SubElement(term, "then") etree.SubElement(then, "accept") then = etree.SubElement(ps, "then") etree.SubElement(then, "reject") # add firewall config for public VRF forwarding_options_config = self.forwarding_options_config firewall_config = self.firewall_config if router_external and is_l2 == False: forwarding_options_config = (self.forwarding_options_config or etree.Element("forwarding-options")) firewall_config = self.firewall_config or etree.Element("firewall") if has_ipv4_prefixes and not self.inet4_forwarding_filter: #create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet4", "inet") if has_ipv6_prefixes and not self.inet6_forwarding_filter: #create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( forwarding_options_config, firewall_config, "inet6", "inet6") if has_ipv4_prefixes: #add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert after 'name' element but before the last term self.inet4_forwarding_filter.insert(1, term) if has_ipv6_prefixes: #add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert after 'name' element but before the last term self.inet6_forwarding_filter.insert(1, term) if fip_map is not None: firewall_config = self.firewall_config or etree.Element("firewall") fc = etree.SubElement(firewall_config, "family") inet = etree.SubElement(fc, "inet") f = etree.SubElement(inet, "filter") etree.SubElement( f, "name").text = DMUtils.make_private_vrf_filter_name(ri_name) term = etree.SubElement(f, "term") etree.SubElement(term, "name").text = DMUtils.make_vrf_term_name(ri_name) from_ = etree.SubElement(term, "from") for fip_user_ip in fip_map.keys(): etree.SubElement(from_, "source-address").text = fip_user_ip then_ = etree.SubElement(term, "then") etree.SubElement(then_, "routing-instance").text = ri_name term = etree.SubElement(f, "term") etree.SubElement(term, "name").text = "default-term" then_ = etree.SubElement(term, "then") etree.SubElement(then_, "accept") 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(network_id) if restrict_proxy_arp: proxy_arp = etree.SubElement(intf_unit, "proxy-arp") etree.SubElement(proxy_arp, "restricted") family = etree.SubElement(intf_unit, "family") inet = etree.SubElement(family, "inet") f = etree.SubElement(inet, "filter") iput = etree.SubElement(f, "input") etree.SubElement( iput, "filter-name").text = DMUtils.make_private_vrf_filter_name(ri_name) # add L2 EVPN and BD config bd_config = None interfaces_config = self.interfaces_config proto_config = self.proto_config 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") bd = etree.SubElement(bd_config, "domain") etree.SubElement(bd, "name").text = DMUtils.make_bridge_name(vni) etree.SubElement(bd, "vlan-id").text = 'none' vxlan = etree.SubElement(bd, "vxlan") etree.SubElement(vxlan, "vni").text = str(vni) for interface in interfaces: if_element = etree.SubElement(bd, "interface") etree.SubElement(if_element, "name").text = interface.name if is_l2_l3: # network_id is unique, hence irb etree.SubElement( bd, "routing-interface").text = "irb." + str(network_id) 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") 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 = None inet6 = None for (irb_ip, gateway) in gateways: if ':' in irb_ip: if not inet6: inet6 = etree.SubElement(family, "inet6") addr = etree.SubElement(inet6, "address") else: if not inet: inet = etree.SubElement(family, "inet") 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" intf_unit = etree.SubElement(lo_intf, "unit") etree.SubElement(intf_unit, "name").text = "0" family = etree.SubElement(intf_unit, "family") inet = etree.SubElement(family, "inet") addr = etree.SubElement(inet, "address") etree.SubElement(addr, "name").text = self.bgp_params[ 'address'] + "/32" etree.SubElement(addr, "primary") etree.SubElement(addr, "preferred") self.build_l2_evpn_interface_config(interfaces_config, interfaces) # fip services config services_config = self.services_config if fip_map is not None: services_config = self.services_config or etree.Element("services") # mx has limitation for service-set and nat-rule name length, # allowed max 63 chars service_name = DMUtils.make_services_set_name(ri_name) service_set = etree.SubElement(services_config, "service-set") etree.SubElement(service_set, "name").text = service_name nat_rule = etree.SubElement(service_set, "nat-rules") etree.SubElement(nat_rule, "name").text = DMUtils.make_snat_rule_name(ri_name) nat_rule = etree.SubElement(service_set, "nat-rules") etree.SubElement(nat_rule, "name").text = DMUtils.make_dnat_rule_name(ri_name) next_hop_service = etree.SubElement( service_set, "next-hop-service") etree.SubElement( next_hop_service, "inside-service-interface").text = interfaces[0].name etree.SubElement( next_hop_service, "outside-service-interface").text = interfaces[1].name nat = etree.SubElement(services_config, "nat") etree.SubElement(nat, "allow-overlapping-nat-pools") snat_rule = etree.SubElement(nat, "rule") etree.SubElement( snat_rule, "name").text = DMUtils.make_snat_rule_name(ri_name) etree.SubElement(snat_rule, "match-direction").text = "input" dnat_rule = etree.SubElement(nat, "rule") etree.SubElement( dnat_rule, "name").text = DMUtils.make_dnat_rule_name(ri_name) etree.SubElement(dnat_rule, "match-direction").text = "output" for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] term = etree.SubElement(snat_rule, "term") etree.SubElement( term, "name").text = DMUtils.make_ip_term_name(pip) from_ = etree.SubElement(term, "from") src_addr = etree.SubElement(from_, "source-address") # private ip etree.SubElement(src_addr, "name").text = pip + "/32" then_ = etree.SubElement(term, "then") translated = etree.SubElement(then_, "translated") etree.SubElement( translated, "source-prefix").text = fip + "/32" # public ip translation_type = etree.SubElement( translated, "translation-type") etree.SubElement(translation_type, "basic-nat44") term = etree.SubElement(dnat_rule, "term") etree.SubElement( term, "name").text = DMUtils.make_ip_term_name(fip) from_ = etree.SubElement(term, "from") src_addr = etree.SubElement(from_, "destination-address") etree.SubElement( src_addr, "name").text = fip + "/32" # public ip then_ = etree.SubElement(term, "then") translated = etree.SubElement(then_, "translated") etree.SubElement( translated, "destination-prefix").text = pip + "/32" # source ip translation_type = etree.SubElement( translated, "translation-type") etree.SubElement(translation_type, "dnat-44") interfaces_config = self.interfaces_config or etree.Element( "interfaces") si_intf = etree.SubElement(interfaces_config, "interface") etree.SubElement(si_intf, "name").text = interfaces[0].ifd_name intf_unit = etree.SubElement(si_intf, "unit") etree.SubElement(intf_unit, "name").text = interfaces[0].unit family = etree.SubElement(intf_unit, "family") etree.SubElement(family, "inet") etree.SubElement(intf_unit, "service-domain").text = "inside" intf_unit = etree.SubElement(si_intf, "unit") etree.SubElement(intf_unit, "name").text = interfaces[1].unit family = etree.SubElement(intf_unit, "family") etree.SubElement(family, "inet") etree.SubElement(intf_unit, "service-domain").text = "outside" self.forwarding_options_config = forwarding_options_config self.firewall_config = firewall_config self.policy_config = policy_config self.proto_config = proto_config self.interfaces_config = interfaces_config self.services_config = services_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) is_dci = ri_conf.get("is_dci_network", False) connected_dci_network = ri_conf.get("connected_dci_network") interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) is_internal_vn = True if '_contrail_lr_internal_vn_' in vn.name else False is_dci_vn = True if '_contrail_dci_internal_vn_' in vn.name else False encapsulation_priorities = \ ri_conf.get("encapsulation_priorities") or ["MPLSoGRE"] ri = RoutingInstance(name=ri_name) if vn: is_nat = True if fip_map else False ri.set_comment( DMUtils.vn_ri_comment(vn, is_l2, is_l2_l3, is_nat, router_external)) self.ri_map[ri_name] = ri ri.set_virtual_network_id(str(network_id)) ri.set_vxlan_id(str(vni)) ri.set_virtual_network_is_internal(is_internal_vn or is_dci_vn) ri.set_is_public_network(router_external) if is_l2_l3: ri.set_virtual_network_mode('l2-l3') elif is_l2: ri.set_virtual_network_mode('l2') else: ri.set_virtual_network_mode('l3') has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: ri.set_routing_instance_type("vrf") if fip_map is None: for interface in interfaces: self.add_ref_to_list(ri.get_interfaces(), interface.name) if prefixes: for prefix in prefixes: ri.add_static_routes(self.get_route_for_cidr(prefix)) ri.add_prefixes(self.get_subnet_for_cidr(prefix)) else: if encapsulation_priorities[0] == "VXLAN": ri.set_routing_instance_type("virtual-switch") elif (any(x in encapsulation_priorities for x in ["MPLSoGRE", "MPLSoUDP"])): ri.set_routing_instance_type("evpn") if is_internal_vn: self.internal_vn_ris.append(ri) if is_dci_vn: self.dci_vn_ris.append(ri) if is_internal_vn or router_external or is_dci_vn: self.add_bogus_lo0(ri, network_id, vn) if self.is_gateway() and is_l2_l3: self.add_irb_config(ri_conf) self.attach_irb(ri_conf, ri) if fip_map is not None: self.add_ref_to_list(ri.get_interfaces(), interfaces[0].name) public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri_public = RoutingInstance(name=public_vrf) self.ri_map[public_vrf] = ri_public self.add_ref_to_list(ri_public.get_interfaces(), interfaces[1].name) floating_ips = [] for fip in fips: ri_public.add_static_routes( Route(prefix=fip, prefix_len=32, next_hop=interfaces[1].name, comment=DMUtils.fip_egress_comment())) floating_ips.append(FloatingIpMap(floating_ip=fip + "/32")) ri_public.add_floating_ip_list( FloatingIpList(public_routing_instance=public_vrf, floating_ips=floating_ips)) # add firewall config for public VRF if router_external and is_l2 is False: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) if has_ipv4_prefixes and not self.inet4_forwarding_filter: # create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( self.firewall_config, "inet") if has_ipv6_prefixes and not self.inet6_forwarding_filter: # create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( self.firewall_config, "inet6") if has_ipv4_prefixes: # add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.inet4_forwarding_filter.get_terms() terms = [term] + (terms or []) self.inet4_forwarding_filter.set_terms(terms) if has_ipv6_prefixes: # add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert before the last term terms = self.inet6_forwarding_filter.get_terms() terms = [term] + (terms or []) self.inet6_forwarding_filter.set_terms(terms) # add firewall config for DCI Network if is_dci: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) self.dci_forwarding_filter[vn.uuid] = self.add_inet_vrf_filter( self.firewall_config, ri_name) # add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.dci_forwarding_filter[vn.uuid].get_terms() terms = [term] + (terms or []) self.dci_forwarding_filter[vn.uuid].set_terms(terms) if fip_map is not None: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) f = FirewallFilter( name=DMUtils.make_private_vrf_filter_name(ri_name)) f.set_comment(DMUtils.vn_firewall_comment(vn, "private")) self.firewall_config.add_firewall_filters(f) term = Term(name=DMUtils.make_vrf_term_name(ri_name)) from_ = From() for fip_user_ip in fip_map.keys(): from_.add_source_address(self.get_subnet_for_cidr(fip_user_ip)) term.set_from(from_) term.set_then(Then(routing_instance=[ri_name])) f.add_terms(term) irb_intf, li_map = self.set_default_pi('irb', 'irb') intf_name = 'irb.' + str(network_id) intf_unit = self.set_default_li(li_map, intf_name, network_id) intf_unit.set_comment(DMUtils.vn_irb_fip_inet_comment(vn)) intf_unit.set_family("inet") intf_unit.add_firewall_filters( DMUtils.make_private_vrf_filter_name(ri_name)) self.add_ref_to_list(ri.get_routing_interfaces(), intf_name) if gateways is not None: for (ip, gateway) in gateways: ri.add_gateways( GatewayRoute(ip_address=self.get_subnet_for_cidr(ip), gateway=self.get_subnet_for_cidr(gateway))) # add L2 EVPN and BD config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): vlan = None if encapsulation_priorities[0] == "VXLAN": vlan = Vlan(name=DMUtils.make_bridge_name(vni), vxlan_id=vni) vlan.set_comment(DMUtils.vn_bd_comment(vn, "VXLAN")) self.vlan_map[vlan.get_name()] = vlan for interface in interfaces: self.add_ref_to_list(vlan.get_interfaces(), interface.name) if is_l2_l3: # network_id is unique, hence irb irb_intf = "irb." + str(network_id) self.add_ref_to_list(vlan.get_interfaces(), irb_intf) elif (any(x in encapsulation_priorities for x in ["MPLSoGRE", "MPLSoUDP"])): self.init_evpn_config(encapsulation_priorities[1]) self.evpn.set_comment( DMUtils.vn_evpn_comment(vn, encapsulation_priorities[1])) for interface in interfaces: self.add_ref_to_list(self.evpn.get_interfaces(), interface.name) self.build_l2_evpn_interface_config(interfaces, vn, vlan) if (not is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): self.init_evpn_config() if not is_internal_vn and not is_dci_vn: # add vlans self.add_ri_vlan_config(ri_name, vni) if (not is_l2 and not is_l2_l3 and gateways): ifl_num = 1000 + int(network_id) lo_intf, li_map = self.set_default_pi('lo0', 'loopback') intf_name = 'lo0.' + str(ifl_num) intf_unit = self.set_default_li(li_map, intf_name, ifl_num) intf_unit.set_comment(DMUtils.l3_lo_intf_comment(vn)) for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: lo_ip = ip + '/' + '128' else: lo_ip = ip + '/' + '32' intf_unit.add_ip_list(lo_ip) self.add_ref_to_list(ri.get_loopback_interfaces(), intf_name) # fip services config if fip_map is not None: nat_rules = NatRules(allow_overlapping_nat_pools=True, name=DMUtils.make_services_set_name(ri_name), comment=DMUtils.service_set_comment(vn)) ri.set_nat_rules(nat_rules) snat_rule = NatRule(name=DMUtils.make_snat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment( vn, "SNAT"), direction="input", translation_type="basic-nat44") snat_rule.set_comment(DMUtils.snat_rule_comment()) nat_rules.add_rules(snat_rule) dnat_rule = NatRule(name=DMUtils.make_dnat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment( vn, "DNAT"), direction="output", translation_type="dnat-44") dnat_rule.set_comment(DMUtils.dnat_rule_comment()) nat_rules.add_rules(dnat_rule) nat_rules.set_inside_interface(interfaces[0].name) nat_rules.set_outside_interface(interfaces[1].name) for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] # private ip snat_rule.add_source_addresses(self.get_subnet_for_cidr(pip)) # public ip snat_rule.add_source_prefixes(self.get_subnet_for_cidr(fip)) # public ip dnat_rule.add_destination_addresses( self.get_subnet_for_cidr(fip)) # private ip dnat_rule.add_destination_prefixes( self.get_subnet_for_cidr(pip)) self.add_ref_to_list(ri.get_ingress_interfaces(), interfaces[0].name) self.add_ref_to_list(ri.get_egress_interfaces(), interfaces[1].name) for target in import_targets: self.add_to_list(ri.get_import_targets(), target) for target in export_targets: self.add_to_list(ri.get_export_targets(), target)
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) network_id = ri_conf.get("network_id", None) self.routing_instances[ri_name] = ri_conf ri_config = None policy_config = self.policy_config or \ PolicyOptions(comment=DMUtils.policy_options_comment()) ri = None ri_opt = None if not is_l2: ri_config = self.ri_config or \ RoutingInstances(comment=DMUtils.routing_instances_comment()) ri = Instance(name=ri_name) ri_config.add_instance(ri) ri.set_vrf_import(DMUtils.make_import_name(ri_name)) ri.set_vrf_export(DMUtils.make_export_name(ri_name)) has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: if ri_opt is None: ri_opt = RoutingInstanceRoutingOptions() ri.set_routing_options(ri_opt) ri.set_instance_type("vrf") for interface in interfaces: ri.add_interface(Interface(name=interface.name)) family = Family() if has_ipv4_prefixes: family.set_inet(FamilyInet(unicast='')) if has_ipv6_prefixes: family.set_inet6(FamilyInet6(unicast='')) if has_ipv4_prefixes or has_ipv6_prefixes: auto_export = AutoExport(family=family) ri_opt.set_auto_export(auto_export) # add policies for export route targets if self.is_spine(): ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Export")) then = Then() ps.add_term(Term(name="t1", then=then)) for route_target in export_targets: comm = Community(add='', community_name=DMUtils.make_community_name(route_target)) then.add_community(comm) then.set_accept('') policy_config.add_policy_statement(ps) self.add_to_global_switch_opts(DMUtils.make_export_name(ri_name), False) # add policies for import route targets ps = PolicyStatement(name=DMUtils.make_import_name(ri_name)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Import")) # add term switch policy from_ = From() term = Term(name=DMUtils.get_switch_policy_name(), fromxx=from_) ps.add_term(term) from_.add_community(DMUtils.get_switch_policy_name()) term.set_then(Then(accept='')) from_ = From() term = Term(name="t1", fromxx=from_) ps.add_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) if not self.is_spine(): self.add_vni_option(vni or network_id, route_target) term.set_then(Then(accept='')) policy_config.add_policy_statement(ps) self.add_to_global_switch_opts(DMUtils.make_import_name(ri_name), True) # add L2 EVPN and BD config interfaces_config = self.interfaces_config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): # add vlan config vlan_conf = self.add_vlan_config(ri_name, vni) interfaces_config = self.interfaces_config or Interfaces(comment=DMUtils.interfaces_comment()) if is_l2_l3 and self.is_spine(): irb_intf = Interface(name='irb', gratuitous_arp_reply='') interfaces_config.add_interface(irb_intf) if gateways is not None: intf_unit = Unit(name=str(network_id), comment=DMUtils.vn_irb_comment(vn, False, is_l2_l3)) irb_intf.add_unit(intf_unit) if self.is_spine(): intf_unit.set_proxy_macip_advertisement('') family = Family() intf_unit.set_family(family) inet = None inet6 = None for (irb_ip, gateway) in gateways: if ':' in irb_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) addr.set_name(irb_ip) addr.set_comment(DMUtils.irb_ip_comment(irb_ip)) if len(gateway) and gateway != '0.0.0.0': addr.set_virtual_gateway_address(gateway) self.build_l2_evpn_interface_config(interfaces_config, interfaces, vn, vlan_conf) if (not is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): ri.set_vtep_source_interface("lo0.0") evpn = self.build_evpn_config() if evpn: ri.set_protocols(RoutingInstanceProtocols(evpn=evpn)) #add vlans self.add_ri_vlan_config(ri, vni) if (not is_l2 and not is_l2_l3 and gateways): interfaces_config = self.interfaces_config or \ Interfaces(comment=DMUtils.interfaces_comment()) ifl_num = str(1000 + int(network_id)) lo_intf = Interface(name="lo0") interfaces_config.add_interface(lo_intf) intf_unit = Unit(name=ifl_num, comment=DMUtils.l3_lo_intf_comment(vn)) lo_intf.add_unit(intf_unit) family = Family() intf_unit.set_family(family) inet = None inet6 = None for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: if not inet6: inet6 = FamilyInet6() family.set_inet6(inet6) addr = Address() inet6.add_address(addr) lo_ip = ip + '/' + '128' else: if not inet: inet = FamilyInet() family.set_inet(inet) addr = Address() inet.add_address(addr) lo_ip = ip + '/' + '32' addr.set_name(lo_ip) addr.set_comment(DMUtils.lo0_ip_comment(subnet)) ri.add_interface(Interface(name="lo0." + ifl_num, comment=DMUtils.lo0_ri_intf_comment(vn))) self.policy_config = policy_config self.interfaces_config = interfaces_config self.route_targets |= import_targets | export_targets self.ri_config = ri_config
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) is_dci = ri_conf.get("is_dci_network", False) connected_dci_network = ri_conf.get("connected_dci_network") interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) is_internal_vn = True if '_contrail_lr_internal_vn_' in vn.name else False is_dci_vn = True if '_contrail_dci_internal_vn_' in vn.name else False encapsulation_priorities = \ ri_conf.get("encapsulation_priorities") or ["MPLSoGRE"] ri = RoutingInstance(name=ri_name) if vn: is_nat = True if fip_map else False ri.set_comment(DMUtils.vn_ri_comment(vn, is_l2, is_l2_l3, is_nat, router_external)) self.ri_map[ri_name] = ri ri.set_virtual_network_id(str(network_id)) ri.set_vxlan_id(str(vni)) ri.set_virtual_network_is_internal(is_internal_vn or is_dci_vn) ri.set_is_public_network(router_external) if is_l2_l3: ri.set_virtual_network_mode('l2-l3') elif is_l2: ri.set_virtual_network_mode('l2') else: ri.set_virtual_network_mode('l3') has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: ri.set_routing_instance_type("vrf") if fip_map is None: for interface in interfaces: self.add_ref_to_list(ri.get_interfaces(), interface.name) if prefixes: for prefix in prefixes: ri.add_static_routes(self.get_route_for_cidr(prefix)) ri.add_prefixes(self.get_subnet_for_cidr(prefix)) else: if encapsulation_priorities[0] == "VXLAN": ri.set_routing_instance_type("virtual-switch") elif (any(x in encapsulation_priorities for x in ["MPLSoGRE", "MPLSoUDP"])): ri.set_routing_instance_type("evpn") if is_internal_vn: self.internal_vn_ris.append(ri) if is_dci_vn: self.dci_vn_ris.append(ri) if is_internal_vn or router_external or is_dci_vn: self.add_bogus_lo0(ri, network_id, vn) if self.is_gateway() and is_l2_l3: self.add_irb_config(ri_conf) self.attach_irb(ri_conf, ri) if fip_map is not None: self.add_ref_to_list(ri.get_interfaces(), interfaces[0].name) public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri_public = RoutingInstance(name=public_vrf) self.ri_map[public_vrf] = ri_public self.add_ref_to_list(ri_public.get_interfaces(), interfaces[1].name) floating_ips = [] for fip in fips: ri_public.add_static_routes( Route(prefix=fip, prefix_len=32, next_hop=interfaces[1].name, comment=DMUtils.fip_egress_comment())) floating_ips.append(FloatingIpMap(floating_ip=fip + "/32")) ri_public.add_floating_ip_list(FloatingIpList( public_routing_instance=public_vrf, floating_ips=floating_ips)) # add firewall config for public VRF if router_external and is_l2 is False: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) if has_ipv4_prefixes and not self.inet4_forwarding_filter: # create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( self.firewall_config, "inet") if has_ipv6_prefixes and not self.inet6_forwarding_filter: # create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( self.firewall_config, "inet6") if has_ipv4_prefixes: # add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.inet4_forwarding_filter.get_terms() terms = [term] + (terms or []) self.inet4_forwarding_filter.set_terms(terms) if has_ipv6_prefixes: # add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert before the last term terms = self.inet6_forwarding_filter.get_terms() terms = [term] + (terms or []) self.inet6_forwarding_filter.set_terms(terms) # add firewall config for DCI Network if is_dci: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) self.dci_forwarding_filter[vn.uuid] = self.add_inet_vrf_filter( self.firewall_config, ri_name) # add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.dci_forwarding_filter[vn.uuid].get_terms() terms = [term] + (terms or []) self.dci_forwarding_filter[vn.uuid].set_terms(terms) if fip_map is not None: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) f = FirewallFilter( name=DMUtils.make_private_vrf_filter_name(ri_name)) f.set_comment(DMUtils.vn_firewall_comment(vn, "private")) self.firewall_config.add_firewall_filters(f) term = Term(name=DMUtils.make_vrf_term_name(ri_name)) from_ = From() for fip_user_ip in fip_map.keys(): from_.add_source_address(self.get_subnet_for_cidr(fip_user_ip)) term.set_from(from_) term.set_then(Then(routing_instance=[ri_name])) f.add_terms(term) irb_intf, li_map = self.set_default_pi('irb', 'irb') intf_name = 'irb.' + str(network_id) intf_unit = self.set_default_li(li_map, intf_name, network_id) intf_unit.set_comment(DMUtils.vn_irb_fip_inet_comment(vn)) intf_unit.set_family("inet") intf_unit.add_firewall_filters( DMUtils.make_private_vrf_filter_name(ri_name)) self.add_ref_to_list(ri.get_routing_interfaces(), intf_name) if gateways is not None: for (ip, gateway) in gateways: ri.add_gateways(GatewayRoute( ip_address=self.get_subnet_for_cidr(ip), gateway=self.get_subnet_for_cidr(gateway))) # add L2 EVPN and BD config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): vlan = None if encapsulation_priorities[0] == "VXLAN": vlan = Vlan(name=DMUtils.make_bridge_name(vni), vxlan_id=vni) vlan.set_comment(DMUtils.vn_bd_comment(vn, "VXLAN")) self.vlan_map[vlan.get_name()] = vlan for interface in interfaces: self.add_ref_to_list(vlan.get_interfaces(), interface.name) if is_l2_l3: # network_id is unique, hence irb irb_intf = "irb." + str(network_id) self.add_ref_to_list(vlan.get_interfaces(), irb_intf) elif (any(x in encapsulation_priorities for x in ["MPLSoGRE", "MPLSoUDP"])): self.init_evpn_config(encapsulation_priorities[1]) self.evpn.set_comment( DMUtils.vn_evpn_comment(vn, encapsulation_priorities[1])) for interface in interfaces: self.add_ref_to_list(self.evpn.get_interfaces(), interface.name) self.build_l2_evpn_interface_config(interfaces, vn, vlan) if (not is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): self.init_evpn_config() if not is_internal_vn and not is_dci_vn: # add vlans self.add_ri_vlan_config(ri_name, vni) if (not is_l2 and not is_l2_l3 and gateways): ifl_num = 1000 + int(network_id) lo_intf, li_map = self.set_default_pi('lo0', 'loopback') intf_name = 'lo0.' + str(ifl_num) intf_unit = self.set_default_li(li_map, intf_name, ifl_num) intf_unit.set_comment(DMUtils.l3_lo_intf_comment(vn)) for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: lo_ip = ip + '/' + '128' else: lo_ip = ip + '/' + '32' self.add_ip_address(intf_unit, lo_ip) self.add_ref_to_list(ri.get_loopback_interfaces(), intf_name) # fip services config if fip_map is not None: nat_rules = NatRules(allow_overlapping_nat_pools=True, name=DMUtils.make_services_set_name(ri_name), comment=DMUtils.service_set_comment(vn)) ri.set_nat_rules(nat_rules) snat_rule = NatRule( name=DMUtils.make_snat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment(vn, "SNAT"), direction="input", translation_type="basic-nat44") snat_rule.set_comment(DMUtils.snat_rule_comment()) nat_rules.add_rules(snat_rule) dnat_rule = NatRule( name=DMUtils.make_dnat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment(vn, "DNAT"), direction="output", translation_type="dnat-44") dnat_rule.set_comment(DMUtils.dnat_rule_comment()) nat_rules.add_rules(dnat_rule) nat_rules.set_inside_interface(interfaces[0].name) nat_rules.set_outside_interface(interfaces[1].name) for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] # private ip snat_rule.add_source_addresses(self.get_subnet_for_cidr(pip)) # public ip snat_rule.add_source_prefixes(self.get_subnet_for_cidr(fip)) # public ip dnat_rule.add_destination_addresses( self.get_subnet_for_cidr(fip)) # private ip dnat_rule.add_destination_prefixes( self.get_subnet_for_cidr(pip)) self.add_ref_to_list(ri.get_ingress_interfaces(), interfaces[0].name) self.add_ref_to_list(ri.get_egress_interfaces(), interfaces[1].name) for target in import_targets: self.add_to_list(ri.get_import_targets(), target) for target in export_targets: self.add_to_list(ri.get_export_targets(), target)
def add_routing_instance(self, ri_conf): ri_name = ri_conf.get("ri_name") vn = ri_conf.get("vn") is_l2 = ri_conf.get("is_l2", False) is_l2_l3 = ri_conf.get("is_l2_l3", False) import_targets = ri_conf.get("import_targets", set()) export_targets = ri_conf.get("export_targets", set()) prefixes = ri_conf.get("prefixes", []) gateways = ri_conf.get("gateways", []) router_external = ri_conf.get("router_external", False) interfaces = ri_conf.get("interfaces", []) vni = ri_conf.get("vni", None) fip_map = ri_conf.get("fip_map", None) network_id = ri_conf.get("network_id", None) is_internal_vn = True if '_contrail_lr_internal_vn_' in vn.name else False highest_encapsulation_priority = \ ri_conf.get("highest_encapsulation_priority") or "MPLSoGRE" self.routing_instances[ri_name] = ri_conf self.ri_config = self.ri_config or [] self.policy_config = self.policy_config or\ Policy(comment=DMUtils.policy_options_comment()) ri = RoutingInstance(name=ri_name) if vn: is_nat = True if fip_map else False ri.set_comment( DMUtils.vn_ri_comment(vn, is_l2, is_l2_l3, is_nat, router_external)) self.ri_config.append(ri) ri.set_virtual_network_id(str(network_id)) ri.set_vxlan_id(str(vni)) ri.set_virtual_network_is_internal(is_internal_vn) ri.set_is_public_network(router_external) if is_l2_l3: ri.set_virtual_network_mode('l2-l3') elif is_l2: ri.set_virtual_network_mode('l2') else: ri.set_virtual_network_mode('l3') has_ipv6_prefixes = DMUtils.has_ipv6_prefixes(prefixes) has_ipv4_prefixes = DMUtils.has_ipv4_prefixes(prefixes) if not is_l2: ri.set_routing_instance_type("vrf") if fip_map is None: for interface in interfaces: ri.add_interfaces(LogicalInterface(name=interface.name)) if prefixes: for prefix in prefixes: ri.add_static_routes(self.get_route_for_cidr(prefix)) ri.add_prefixes(self.get_subnet_for_cidr(prefix)) else: if highest_encapsulation_priority == "VXLAN": ri.set_routing_instance_type("virtual-switch") elif highest_encapsulation_priority in ["MPLSoGRE", "MPLSoUDP"]: ri.set_routing_instance_type("evpn") if is_internal_vn: self.internal_vn_ris.append(ri) self.add_bogus_lo0(ri, network_id, vn) if self.is_spine() and is_l2_l3: self.add_irb_config(ri_conf) self.attach_irb(ri_conf, ri) if fip_map is not None: ri.add_interfaces(LogicalInterface(name=interfaces[0].name)) public_vrf_ips = {} for pip in fip_map.values(): if pip["vrf_name"] not in public_vrf_ips: public_vrf_ips[pip["vrf_name"]] = set() public_vrf_ips[pip["vrf_name"]].add(pip["floating_ip"]) for public_vrf, fips in public_vrf_ips.items(): ri.add_interfaces(LogicalInterface(name=interfaces[1].name)) floating_ips = [] for fip in fips: ri.add_static_routes( Route(prefix=fip, prefix_len=32, next_hop=interfaces[1].name, comment=DMUtils.fip_egress_comment())) floating_ips.append(FloatingIpMap(floating_ip=fip + "/32")) ri.add_floating_ip_list( FloatingIpList(public_routing_instance=public_vrf, floating_ips=floating_ips)) # add policies for export route targets if self.is_spine(): p = PolicyRule(name=DMUtils.make_export_name(ri_name)) p.set_comment(DMUtils.vn_ps_comment(vn, "Export")) then = Then() p.add_term(Term(name="t1", then=then)) for route_target in export_targets: then.add_community(DMUtils.make_community_name(route_target)) then.set_accept_or_reject(True) self.policy_config.add_policy_rule(p) # add policies for import route targets p = PolicyRule(name=DMUtils.make_import_name(ri_name)) p.set_comment(DMUtils.vn_ps_comment(vn, "Import")) # add term switch policy from_ = From() term = Term(name=DMUtils.get_switch_policy_name(), fromxx=from_) p.add_term(term) from_.add_community(DMUtils.get_switch_policy_name()) term.set_then(Then(accept_or_reject=True)) from_ = From() term = Term(name="t1", fromxx=from_) p.add_term(term) for route_target in import_targets: from_.add_community(DMUtils.make_community_name(route_target)) if not is_internal_vn: self.add_vni_option(vni or network_id, route_target) term.set_then(Then(accept_or_reject=True)) self.policy_config.add_policy_rule(p) # add firewall config for public VRF if router_external and is_l2 is False: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) if has_ipv4_prefixes and not self.inet4_forwarding_filter: # create single instance inet4 filter self.inet4_forwarding_filter = self.add_inet_public_vrf_filter( self.firewall_config, "inet") if has_ipv6_prefixes and not self.inet6_forwarding_filter: # create single instance inet6 filter self.inet6_forwarding_filter = self.add_inet_public_vrf_filter( self.firewall_config, "inet6") if has_ipv4_prefixes: # add terms to inet4 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet4") # insert before the last term terms = self.inet4_forwarding_filter.get_terms() terms = [term] + (terms or []) self.inet4_forwarding_filter.set_terms(terms) if has_ipv6_prefixes: # add terms to inet6 filter term = self.add_inet_filter_term(ri_name, prefixes, "inet6") # insert before the last term terms = self.inet6_forwarding_filter.get_terms() terms = [term] + (terms or []) self.inet6_forwarding_filter.set_terms(terms) if fip_map is not None: self.firewall_config = self.firewall_config or Firewall( comment=DMUtils.firewall_comment()) f = FirewallFilter( name=DMUtils.make_private_vrf_filter_name(ri_name)) f.set_comment(DMUtils.vn_firewall_comment(vn, "private")) self.firewall_config.add_firewall_filters(f) term = Term(name=DMUtils.make_vrf_term_name(ri_name)) from_ = From() for fip_user_ip in fip_map.keys(): from_.add_source_address(fip_user_ip) term.set_from(from_) term.set_then(Then(routing_instance=[ri_name])) f.add_terms(term) irb_intf = PhysicalInterface(name='irb', interface_type='irb') self.interfaces_config.append(irb_intf) intf_unit = LogicalInterface( name="irb." + str(network_id), unit=network_id, comment=DMUtils.vn_irb_fip_inet_comment(vn)) irb_intf.add_logical_interfaces(intf_unit) intf_unit.set_family("inet") intf_unit.add_firewall_filters( DMUtils.make_private_vrf_filter_name(ri_name)) ri.add_routing_interfaces(intf_unit) if gateways is not None: for (ip, gateway) in gateways: ri.add_gateways( GatewayRoute(ip_address=self.get_subnet_for_cidr(ip), gateway=self.get_subnet_for_cidr(gateway))) # add L2 EVPN and BD config if (is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): vlan = None if self.is_spine(): if highest_encapsulation_priority == "VXLAN": self.vlans_config = self.vlans_config or [] vlan = Vlan(name=DMUtils.make_bridge_name(vni), vxlan_id=vni, vlan_or_bridge_domain=False) vlan.set_comment(DMUtils.vn_bd_comment(vn, "VXLAN")) self.vlans_config.append(vlan) for interface in interfaces: vlan.add_interfaces( LogicalInterface(name=interface.name)) if is_l2_l3: # network_id is unique, hence irb irb_intf = "irb." + str(network_id) vlan.add_interfaces(LogicalInterface(name=irb_intf)) elif highest_encapsulation_priority in [ "MPLSoGRE", "MPLSoUDP" ]: self.evpn = Evpn( encapsulation=highest_encapsulation_priority) self.evpn.set_comment( DMUtils.vn_evpn_comment( vn, highest_encapsulation_priority)) for interface in interfaces: self.evpn.add_interfaces( LogicalInterface(name=interface.name)) else: # add vlan config vlan = self.add_vlan_config(ri_name, vni, is_l2_l3, "irb." + str(network_id)) self.interfaces_config = self.interfaces_config or [] self.build_l2_evpn_interface_config(self.interfaces_config, interfaces, vn, vlan) if (not is_l2 and vni is not None and self.is_family_configured(self.bgp_params, "e-vpn")): self.evpn = self.build_evpn_config() # add vlans self.add_ri_vlan_config(ri, vni) if (not is_l2 and not is_l2_l3 and gateways): self.interfaces_config = self.interfaces_config or [] ifl_num = 1000 + int(network_id) lo_intf = PhysicalInterface(name="lo0", interface_type='loopback') self.interfaces_config.append(lo_intf) intf_unit = LogicalInterface( name="lo0." + str(ifl_num), unit=ifl_num, comment=DMUtils.l3_lo_intf_comment(vn)) lo_intf.add_logical_interfaces(intf_unit) for (lo_ip, _) in gateways: subnet = lo_ip (ip, _) = lo_ip.split('/') if ':' in lo_ip: lo_ip = ip + '/' + '128' else: lo_ip = ip + '/' + '32' intf_unit.add_ip_list( IpType(address=lo_ip, comment=DMUtils.lo0_ip_comment(subnet))) ri.add_loopback_interfaces( LogicalInterface(name="lo0." + str(ifl_num), comment=DMUtils.lo0_ri_intf_comment(vn))) # fip services config if fip_map is not None: nat_rules = NatRules(allow_overlapping_nat_pools=True, name=DMUtils.make_services_set_name(ri_name), comment=DMUtils.service_set_comment(vn)) ri.set_nat_rules(nat_rules) snat_rule = NatRule(name=DMUtils.make_snat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment( vn, "SNAT"), direction="input", translation_type="basic-nat44") snat_rule.set_comment(DMUtils.snat_rule_comment()) nat_rules.add_rules(snat_rule) dnat_rule = NatRule(name=DMUtils.make_dnat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment( vn, "DNAT"), direction="output", translation_type="dnat-44") dnat_rule.set_comment(DMUtils.dnat_rule_comment()) nat_rules.add_rules(dnat_rule) nat_rules.set_inside_interface(interfaces[0].name) nat_rules.set_outside_interface(interfaces[1].name) for pip, fip_vn in fip_map.items(): fip = fip_vn["floating_ip"] # private ip snat_rule.add_source_addresses(self.get_subnet_for_cidr(pip)) # public ip snat_rule.add_source_prefixes(self.get_subnet_for_cidr(fip)) # public ip dnat_rule.add_destination_addresses( self.get_subnet_for_cidr(fip)) # private ip dnat_rule.add_destination_prefixes( self.get_subnet_for_cidr(pip)) intf_unit = LogicalInterface( name=interfaces[0].name, unit=interfaces[0].unit, comment=DMUtils.service_intf_comment("Ingress")) intf_unit.set_family("inet") ri.add_service_interfaces(intf_unit) intf_unit = LogicalInterface( name=interfaces[1].name, unit=interfaces[1].unit, comment=DMUtils.service_intf_comment("Egress")) intf_unit.set_family("inet") ri.add_service_interfaces(intf_unit) for target in import_targets: ri.add_import_targets(target) for target in export_targets: ri.add_export_targets(target)