diff --git a/src/config/device-manager/device_manager/db.py b/src/config/device-manager/device_manager/db.py
index 84ded59193f..3dcb77a0593 100644
--- a/src/config/device-manager/device_manager/db.py
+++ b/src/config/device-manager/device_manager/db.py
@@ -210,11 +210,9 @@ def push_config(self):
else:
vn_dict[vn_id] = [li.name]
- #for now, assume service port ifls unit numbers are always starts with 0 and goes on
- service_port_id = 1
for vn_id, interfaces in vn_dict.items():
vn_obj = VirtualNetworkDM.get(vn_id)
- if vn_obj is None or vn_obj.vxlan_vni is None:
+ if vn_obj is None or vn_obj.vxlan_vni is None or vn_obj.vn_network_id is None:
continue
export_set = None
import_set = None
@@ -224,7 +222,6 @@ def push_config(self):
if ri_obj is None:
continue
if ri_obj.fq_name[-1] == vn_obj.fq_name[-1]:
- vrf_name = vn_obj.get_vrf_name()
vrf_name_l2 = vn_obj.get_vrf_name(vrf_type='l2')
vrf_name_l3 = vn_obj.get_vrf_name(vrf_type='l3')
export_set = copy.copy(ri_obj.export_targets)
@@ -264,16 +261,19 @@ def push_config(self):
break
if export_set is not None and self.is_junos_service_ports_enabled() and len(vn_obj.instance_ip_map) > 0:
- vrf_name = vrf_name[:123] + '-nat'
- interfaces = []
- service_ports = self.junos_service_ports.get('service_port')
- interfaces.append(service_ports[0] + "." + str(service_port_id))
- service_port_id = service_port_id + 1
- interfaces.append(service_ports[0] + "." + str(service_port_id))
- service_port_id = service_port_id + 1
- self.config_manager.add_routing_instance(vrf_name,
+ service_port_id = 2*vn_obj.vn_network_id - 1
+ if self.is_service_port_id_valid(service_port_id) == False:
+ self._logger.error("DM can't allocate service interfaces for \
+ (vn, vn-id)=(%s,%s)" % (vn_obj.fq_name, vn_obj.vn_network_id))
+ else:
+ vrf_name = vrf_name_l3[:123] + '-nat'
+ interfaces = []
+ service_ports = self.junos_service_ports.get('service_port')
+ interfaces.append(service_ports[0] + "." + str(service_port_id))
+ interfaces.append(service_ports[0] + "." + str(service_port_id + 1))
+ self.config_manager.add_routing_instance(vrf_name,
import_set,
- export_set,
+ set(),
None,
None,
False,
@@ -285,6 +285,13 @@ def push_config(self):
self.uve_send()
# end push_config
+ def is_service_port_id_valid(self, service_port_id):
+ #mx allowed ifl unit number range is (1, 16385) for service ports
+ if service_port_id < 1 or service_port_id > 16384:
+ return False
+ return True
+ #end is_service_port_id_valid
+
def uve_send(self, deleted=False):
pr_trace = UvePhysicalRouterConfig(name=self.name,
ip_address=self.management_ip,
@@ -549,12 +556,19 @@ def __init__(self, uuid, obj_dict=None):
def update(self, obj=None):
if obj is None:
obj = self.read_obj(self.uuid)
+ self.device_owner = obj.get("virtual_machine_interface_device_owner")
self.update_single_ref('logical_interface', obj)
self.update_single_ref('virtual_network', obj)
self.update_single_ref('floating_ip', obj)
self.update_single_ref('instance_ip', obj)
# end update
+ def is_device_owner_bms(self):
+ if not self.device_owner or self.device_owner.lower() == 'physicalrouter':
+ return True
+ return False
+ #end
+
@classmethod
def delete(cls, uuid):
if uuid not in cls._dict:
@@ -593,6 +607,7 @@ def update(self, obj=None):
self.router_external = obj['router_external']
except KeyError:
self.router_external = False
+ self.vn_network_id = obj.get('virtual_network_network_id')
self.set_vxlan_vni(obj)
self.routing_instances = set([ri['uuid'] for ri in
obj.get('routing_instances', [])])
@@ -609,13 +624,16 @@ def update(self, obj=None):
self.gateways.add(subnet['default_gateway'])
# end update
- def get_vrf_name(self, vrf_type=None):
+ def get_vrf_name(self, vrf_type):
+ #this function must be called only after vn gets its vn_id
+ if self.vn_network_id is None:
+ self._logger.error("network id is null for vn: %s" % (self.fq_name[-1]))
+ return '_contrail_' + vrf_type + '_' + self.fq_name[-1]
if vrf_type is None:
- vrf_name = '__contrail__' + self.uuid + '_' + self.fq_name[-1]
- elif vrf_type == 'l2':
- vrf_name = '__contrail__l2_' + self.uuid + '_' + self.fq_name[-1]
+ self._logger.error("vrf type can't be null : %s" % (self.fq_name[-1]))
+ vrf_name = '_contrail_' + str(self.vn_network_id) + '_' + self.fq_name[-1]
else:
- vrf_name = '__contrail__l3_' + self.uuid + '_' + self.fq_name[-1]
+ vrf_name = '_contrail_' + vrf_type + '_' + str(self.vn_network_id) + '_' + self.fq_name[-1]
#mx has limitation for vrf name, allowed max 127 chars
return vrf_name[:127]
#end
@@ -639,7 +657,7 @@ def update_instance_ip_map(self):
self.instance_ip_map = {}
for vmi_uuid in self.virtual_machine_interfaces:
vmi = VirtualMachineInterfaceDM.get(vmi_uuid)
- if vmi is None:
+ if vmi is None or vmi.is_device_owner_bms() == False:
continue
if vmi.floating_ip is not None and vmi.instance_ip is not None:
fip = FloatingIpDM.get(vmi.floating_ip)
@@ -649,7 +667,7 @@ def update_instance_ip_map(self):
instance_ip = inst_ip.instance_ip_address
floating_ip = fip.floating_ip_address
public_vn = VirtualNetworkDM.get(fip.public_network)
- if public_vn is None:
+ if public_vn is None or public_vn.vn_network_id is None:
continue
public_vrf_name = public_vn.get_vrf_name(vrf_type='l3')
self.instance_ip_map[instance_ip] = {'floating_ip': floating_ip,
diff --git a/src/config/device-manager/device_manager/physical_router_config.py b/src/config/device-manager/device_manager/physical_router_config.py
index 00be8639c17..2dc5b86bdc2 100644
--- a/src/config/device-manager/device_manager/physical_router_config.py
+++ b/src/config/device-manager/device_manager/physical_router_config.py
@@ -183,23 +183,23 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
if_element = etree.SubElement(ri, "interface")
etree.SubElement(if_element, "name").text = interface
+ if ri_opt is None:
+ ri_opt = etree.SubElement(ri, "routing-options")
if prefixes and fip_map is None:
- if ri_opt is None:
- ri_opt = etree.SubElement(ri, "routing-options")
- static_config = etree.SubElement(ri_opt, "static")
+ static_config = etree.SubElement(ri_opt, "static")
for prefix in prefixes:
route_config = etree.SubElement(static_config, "route")
etree.SubElement(route_config, "name").text = prefix
etree.SubElement(route_config, "discard")
- auto_export = ""
- ri_opt.append(etree.fromstring(auto_export))
+ 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")
+ 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]
@@ -234,7 +234,11 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
comm = etree.SubElement(then, "community")
etree.SubElement(comm, "add")
etree.SubElement(comm, "community-name").text = route_target.replace(':', '_')
- etree.SubElement(then, "accept")
+ 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")
@@ -253,45 +257,62 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
# add firewall config for public VRF
forwarding_options_config = self.forwarding_options_config
firewall_config = self.firewall_config
- if router_external or fip_map is not None:
- forwarding_options_config = self.forwarding_options_config or etree.Element("forwarding-options")
- fo = etree.SubElement(forwarding_options_config, "family")
- inet = etree.SubElement(fo, "inet")
- f = etree.SubElement(inet, "filter")
- #mx has limitation for filter names, allowed max 63 chars
- etree.SubElement(f, "input").text = "redirect_to_" + ri_name[:46] + "_vrf"
+ if router_external:
+ if self.forwarding_options_config is None:
+ forwarding_options_config = etree.Element("forwarding-options")
+ fo = etree.SubElement(forwarding_options_config, "family")
+ inet = etree.SubElement(fo, "inet")
+ f = etree.SubElement(inet, "filter")
+ etree.SubElement(f, "input").text = "redirect_to_public_vrf_filter"
+ 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 = "redirect_to_public_vrf_filter"
+ self.inet_forwarding_filter = f
+ term = etree.SubElement(f, "term")
+ etree.SubElement(term, "name").text= "default-term"
+ then_ = etree.SubElement(term, "then")
+ etree.SubElement(then_, "accept")
+
+ term = etree.Element("term")
+ etree.SubElement(term, "name").text= "term-" + ri_name[:59]
+ if prefixes:
+ from_ = etree.SubElement(term, "from")
+ etree.SubElement(from_, "destination-address").text = ';'.join(prefixes)
+ then_ = etree.SubElement(term, "then")
+ etree.SubElement(then_, "routing-instance").text = ri_name
+ #insert after 'name' element but before the last term
+ self.inet_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 = "redirect_to_" + ri_name[:46] + "_vrf"
term = etree.SubElement(f, "term")
- etree.SubElement(term, "name").text= "t1"
- if fip_map is not None:
- from_ = etree.SubElement(term, "from")
- etree.SubElement(from_, "destination-address").text = ';'.join(fip_map.keys())
- elif prefixes:
- from_ = etree.SubElement(term, "from")
- etree.SubElement(from_, "destination-address").text = ';'.join(prefixes)
+ etree.SubElement(term, "name").text= "term-" + ri_name[:59]
+ 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= "t2"
+ etree.SubElement(term, "name").text= "default-term"
then_ = etree.SubElement(term, "then")
etree.SubElement(then_, "accept")
- if fip_map is not None:
- interfaces_config = self.interfaces_config or etree.Element("interfaces")
- irb_intf = etree.SubElement(interfaces_config, "interface")
- etree.SubElement(irb_intf, "name").text = "irb"
- intf_unit = etree.SubElement(irb_intf, "unit")
- etree.SubElement(intf_unit, "name").text = str(private_vni)
- family = etree.SubElement(intf_unit, "family")
- inet = etree.SubElement(family, "inet")
- f = etree.SubElement(inet, "filter")
- input = etree.SubElement(f, "input")
- etree.SubElement(input, "filter-name").text = "redirect_to_" + ri_name[:46] + "_vrf"
+ interfaces_config = self.interfaces_config or etree.Element("interfaces")
+ irb_intf = etree.SubElement(interfaces_config, "interface")
+ etree.SubElement(irb_intf, "name").text = "irb"
+ intf_unit = etree.SubElement(irb_intf, "unit")
+ etree.SubElement(intf_unit, "name").text = str(private_vni)
+ family = etree.SubElement(intf_unit, "family")
+ inet = etree.SubElement(family, "inet")
+ f = etree.SubElement(inet, "filter")
+ iput = etree.SubElement(f, "input")
+ etree.SubElement(iput, "filter-name").text = "redirect_to_" + ri_name[:46] + "_vrf"
# add L2 EVPN and BD config
bd_config = None
@@ -359,29 +380,29 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
services_config = self.services_config or etree.Element("services")
service_name = 'sv-' + ri_name
#mx has limitation for service-set and nat-rule name length, allowed max 63 chars
- service_name = service_name[:56]
+ service_name = service_name[:23]
service_set = etree.SubElement(services_config, "service-set")
etree.SubElement(service_set, "name").text = service_name
- rule_count = len(fip_map)
- for rule_id in range(0, rule_count):
- nat_rule = etree.SubElement(service_set, "nat-rules")
- etree.SubElement(nat_rule, "name").text = service_name + "-sn-" + str(rule_id)
- nat_rule = etree.SubElement(service_set, "nat-rules")
- etree.SubElement(nat_rule, "name").text = service_name + "-dn-" + str(rule_id)
+ nat_rule = etree.SubElement(service_set, "nat-rules")
+ etree.SubElement(nat_rule, "name").text = service_name + "-sn-rule"
+ nat_rule = etree.SubElement(service_set, "nat-rules")
+ etree.SubElement(nat_rule, "name").text = service_name + "-dn-rule"
next_hop_service = etree.SubElement(service_set, "next-hop-service")
etree.SubElement(next_hop_service , "inside-service-interface").text = interfaces[0]
etree.SubElement(next_hop_service , "outside-service-interface").text = interfaces[1]
nat = etree.SubElement(services_config, "nat")
+ snat_rule = etree.SubElement(nat, "rule")
+ etree.SubElement(snat_rule, "name").text = service_name + "-sn-rule"
+ etree.SubElement(snat_rule, "match-direction").text = "input"
+ dnat_rule = etree.SubElement(nat, "rule")
+ etree.SubElement(dnat_rule, "name").text = service_name + "-dn-rule"
+ etree.SubElement(dnat_rule, "match-direction").text = "output"
- rule_id = 0
for pip, fip_vn in fip_map.items():
fip = fip_vn["floating_ip"]
- rule = etree.SubElement(nat, "rule")
- etree.SubElement(rule, "name").text = service_name + "-sn-" + str(rule_id)
- etree.SubElement(rule, "match-direction").text = "input"
- term = etree.SubElement(rule, "term")
- etree.SubElement(term, "name").text = "t1"
+ term = etree.SubElement(snat_rule, "term")
+ etree.SubElement(term, "name").text = "term_" + pip.replace('.', '_')
from_ = etree.SubElement(term, "from")
src_addr = etree.SubElement(from_, "source-address")
etree.SubElement(src_addr, "name").text = pip + "/32" # private ip
@@ -391,11 +412,8 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
translation_type = etree.SubElement(translated, "translation-type")
etree.SubElement(translation_type, "basic-nat44")
- rule = etree.SubElement(nat, "rule")
- etree.SubElement(rule, "name").text = service_name + "-dn-" + str(rule_id)
- etree.SubElement(rule, "match-direction").text = "output"
- term = etree.SubElement(rule, "term")
- etree.SubElement(term, "name").text = "t1"
+ term = etree.SubElement(dnat_rule, "term")
+ etree.SubElement(term, "name").text = "term_" + fip.replace('.', '_')
from_ = etree.SubElement(term, "from")
src_addr = etree.SubElement(from_, "destination-address")
etree.SubElement(src_addr, "name").text = fip + "/32" #public ip
@@ -404,7 +422,6 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
etree.SubElement(translated , "destination-prefix").text = pip + "/32" #source ip
translation_type = etree.SubElement(translated, "translation-type")
etree.SubElement(translation_type, "dnat-44")
- rule_id = rule_id + 1
interfaces_config = self.interfaces_config or etree.Element("interfaces")
si_intf = etree.SubElement(interfaces_config, "interface")
@@ -511,6 +528,7 @@ def reset_bgp_config(self):
self.services_config = None
self.policy_config = None
self.firewall_config = None
+ self.inet_forwarding_filter = None
self.forwarding_options_config = None
self.global_routing_options_config = None
self.proto_config = None