def build_firewall_filters(self, sg, acl, is_egress=False): if self.is_spine(): return if not sg or not acl or not acl.vnc_obj: return acl = acl.vnc_obj entries = acl.get_access_control_list_entries() if not entries: return rules = entries.get_acl_rule() or [] if not rules: return firewall_config = self.firewall_config or Firewall( DMUtils.firewall_comment()) ff = firewall_config.get_family() or FirewallFamily() firewall_config.set_family(ff) eswitching = ff.get_ethernet_switching() or FirewallEthernet() ff.set_ethernet_switching(eswitching) for rule in rules: if not self.has_terms(rule): continue match = rule.get_match_condition() if not match: continue rule_uuid = rule.get_rule_uuid() dst_addr_match = match.get_dst_address() dst_port_match = match.get_dst_port() ether_type_match = match.get_ethertype() protocol_match = match.get_protocol() src_addr_match = match.get_src_address() src_port_match = match.get_src_port() filter_name = DMUtils.make_sg_filter_name(sg.name, ether_type_match, rule_uuid) f = FirewallFilter(name=filter_name) f.set_comment( DMUtils.sg_firewall_comment(sg.name, ether_type_match, rule_uuid)) # allow arp ether type always self.add_ether_type_term(f, 'arp') # allow dhcp/dns always self.add_dns_dhcp_terms(f) default_term = self.add_filter_term(f, "default-term") self.add_addr_term(default_term, dst_addr_match, False) self.add_addr_term(default_term, src_addr_match, True) self.add_port_term(default_term, dst_port_match, False) # source port match is not needed for now (BMS source port) #self.add_port_term(default_term, src_port_match, True) self.add_protocol_term(default_term, protocol_match) eswitching.add_filter(f) if not eswitching.get_filter(): ff.set_ethernet_switching(None) self.firewall_config = firewall_config
def build_firewall_filters(self, sg, acl, is_egress=False): acl_rule_present = False if not sg or not acl or not acl.vnc_obj: return acl = acl.vnc_obj entries = acl.get_access_control_list_entries() if not entries: return rules = entries.get_acl_rule() or [] if not rules: return self.firewall_config = self.firewall_config or\ Firewall(DMUtils.firewall_comment()) for rule in rules: if not self.has_terms(rule): continue match = rule.get_match_condition() if not match: continue acl_rule_present = True break if acl_rule_present: filter_name = DMUtils.make_sg_firewall_name(sg.name, acl.uuid) f = FirewallFilter(name=filter_name) f.set_comment(DMUtils.make_sg_firewall_comment(sg.name, acl.uuid)) # allow arp ether type always self.add_ether_type_term(f, 'arp') # allow dhcp/dns always self.add_dns_dhcp_terms(f) for rule in rules: if not self.has_terms(rule): continue match = rule.get_match_condition() if not match: continue rule_uuid = rule.get_rule_uuid() dst_addr_match = match.get_dst_address() dst_port_match = match.get_dst_port() ether_type_match = match.get_ethertype() protocol_match = match.get_protocol() src_addr_match = match.get_src_address() src_port_match = match.get_src_port() term = self.add_filter_term(f, rule_uuid) self.add_addr_term(term, dst_addr_match, False) self.add_addr_term(term, src_addr_match, True) self.add_port_term(term, dst_port_match, False) # source port match is not needed for now (BMS source port) #self.add_port_term(term, src_port_match, True) self.add_protocol_term(term, protocol_match) self.firewall_config.add_firewall_filters(f)
def build_firewall_filters(self, sg, acl, is_egress=False): if self.is_spine(): return if not sg or not acl or not acl.vnc_obj: return acl = acl.vnc_obj entries = acl.get_access_control_list_entries() if not entries: return rules = entries.get_acl_rule() or [] if not rules: return firewall_config = self.firewall_config or Firewall( DMUtils.firewall_comment()) ff = firewall_config.get_family() or FirewallFamily() firewall_config.set_family(ff) eswitching = ff.get_ethernet_switching() or FirewallEthernet() ff.set_ethernet_switching(eswitching) for rule in rules: match = rule.get_match_condition() if not match: continue rule_uuid = rule.get_rule_uuid() dst_addr_match = match.get_dst_address() dst_port_match = match.get_dst_port() ether_type_match = match.get_ethertype() protocol_match = match.get_protocol() src_addr_match = match.get_src_address() src_port_match = match.get_src_port() filter_name = DMUtils.make_sg_filter_name(sg.name, ether_type_match, rule_uuid) f = FirewallFilter(name=filter_name) f.set_comment( DMUtils.sg_firewall_comment(sg.name, ether_type_match, rule_uuid)) self.add_addr_term(f, dst_addr_match, False) self.add_addr_term(f, src_addr_match, True) self.add_port_term(f, dst_port_match, False) self.add_port_term(f, src_port_match, False) self.add_ether_type_term(f, ether_type_match) self.add_protocol_term(f, protocol_match) eswitching.add_filter(f) self.firewall_config = firewall_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) 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( comment=DMUtils.routing_instances_comment()) policy_config = self.policy_config or PolicyOptions( comment=DMUtils.policy_options_comment()) ri = Instance(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)) 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", comment=DMUtils.public_vrf_route_comment()) ])) 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, comment=DMUtils.fip_ingress_comment())) 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, comment=DMUtils.fip_egress_comment())) # 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.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)) ps.set_comment(DMUtils.vn_ps_comment(vn, "Import")) 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(DMUtils.forwarding_options_comment())) firewall_config = self.firewall_config or Firewall( 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( 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( DMUtils.firewall_comment()) f = FirewallFilter( name=DMUtils.make_private_vrf_filter_name(ri_name)) f.set_comment(DMUtils.vn_firewall_comment(vn, "private")) 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( comment=DMUtils.interfaces_comment()) irb_intf = Interface(name="irb") interfaces_config.add_interface(irb_intf) intf_unit = Unit(name=str(network_id), comment=DMUtils.vn_irb_fip_inet_comment(vn)) 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.set_comment(DMUtils.vn_bd_comment(vn, "VXLAN")) 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() evpn.set_comment( DMUtils.vn_evpn_comment(vn, highest_enapsulation_priority)) for interface in interfaces: evpn.add_interface(Interface(name=interface.name)) 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) 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: (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(lo_ip)) ri.add_interface( Interface(name="lo0." + ifl_num, comment=DMUtils.lo0_ri_intf_comment(vn))) # fip services config services_config = self.services_config if fip_map is not None: services_config = self.services_config or Services() services_config.set_comment(DMUtils.services_comment()) service_name = DMUtils.make_services_set_name(ri_name) service_set = ServiceSet(name=service_name) service_set.set_comment(DMUtils.service_set_comment(vn)) 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), comment=DMUtils.service_set_nat_rule_comment( vn, "SNAT"))) service_set.add_nat_rules( NATRules(name=DMUtils.make_dnat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment( vn, "DNAT"))) 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='') nat.set_comment(DMUtils.nat_comment()) services_config.add_nat(nat) snat_rule = Rule(name=DMUtils.make_snat_rule_name(ri_name), match_direction="input") snat_rule.set_comment(DMUtils.snat_rule_comment()) nat.add_rule(snat_rule) dnat_rule = Rule(name=DMUtils.make_dnat_rule_name(ri_name), match_direction="output") dnat_rule.set_comment(DMUtils.dnat_rule_comment()) 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( comment=DMUtils.interfaces_comment()) si_intf = Interface(name=interfaces[0].ifd_name, comment=DMUtils.service_ifd_comment()) interfaces_config.add_interface(si_intf) intf_unit = Unit(name=interfaces[0].unit, comment=DMUtils.service_intf_comment("Ingress")) 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, comment=DMUtils.service_intf_comment("Egress")) 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", []) 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") si = ri_conf.get("si") 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(comment=DMUtils.routing_instances_comment()) policy_config = self.policy_config or PolicyOptions(comment=DMUtils.policy_options_comment()) ri = Instance(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)) elif si: ri.set_comment(DMUtils.si_ri_comment(si)) 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", comment=DMUtils.public_vrf_route_comment())])) 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) 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: 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, comment=DMUtils.fip_ingress_comment())) 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, comment=DMUtils.fip_egress_comment())) # add policies for export route targets ps = PolicyStatement(name=DMUtils.make_export_name(ri_name)) if vn: ps.set_comment(DMUtils.vn_ps_comment(vn, "Export")) elif si: ps.set_comment(DMUtils.si_ps_comment(si, "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) 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)) if vn: ps.set_comment(DMUtils.vn_ps_comment(vn, "Import")) elif si: ps.set_comment(DMUtils.si_ps_comment(si, "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)) 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(DMUtils.forwarding_options_comment())) firewall_config = self.firewall_config or Firewall(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( 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(DMUtils.firewall_comment()) f = FirewallFilter(name=DMUtils.make_private_vrf_filter_name(ri_name)) f.set_comment(DMUtils.vn_firewall_comment(vn, "private")) 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(comment=DMUtils.interfaces_comment()) irb_intf = Interface(name="irb") interfaces_config.add_interface(irb_intf) intf_unit = Unit(name=str(network_id), comment=DMUtils.vn_irb_fip_inet_comment(vn)) 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.set_comment(DMUtils.vn_bd_comment(vn, "VXLAN")) 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() evpn.set_comment(DMUtils.vn_evpn_comment(vn, highest_enapsulation_priority)) for interface in interfaces: evpn.add_interface(Interface(name=interface.name)) 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) 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))) # fip services config services_config = self.services_config if fip_map is not None: services_config = self.services_config or Services() services_config.set_comment(DMUtils.services_comment()) service_name = DMUtils.make_services_set_name(ri_name) service_set = ServiceSet(name=service_name) service_set.set_comment(DMUtils.service_set_comment(vn)) 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), comment=DMUtils.service_set_nat_rule_comment(vn, "SNAT"))) service_set.add_nat_rules(NATRules(name=DMUtils.make_dnat_rule_name(ri_name), comment=DMUtils.service_set_nat_rule_comment(vn, "DNAT"))) 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='') nat.set_comment(DMUtils.nat_comment()) services_config.add_nat(nat) snat_rule = Rule(name=DMUtils.make_snat_rule_name(ri_name), match_direction="input") snat_rule.set_comment(DMUtils.snat_rule_comment()) nat.add_rule(snat_rule) dnat_rule = Rule(name=DMUtils.make_dnat_rule_name(ri_name), match_direction="output") dnat_rule.set_comment(DMUtils.dnat_rule_comment()) 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(comment=DMUtils.interfaces_comment()) si_intf = Interface(name=interfaces[0].ifd_name, comment=DMUtils.service_ifd_comment()) interfaces_config.add_interface(si_intf) intf_unit = Unit(name=interfaces[0].unit, comment=DMUtils.service_intf_comment("Ingress")) 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, comment=DMUtils.service_intf_comment("Egress")) 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", []) 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)