Skip to content

Commit

Permalink
DM: fixes ported from R2.20
Browse files Browse the repository at this point in the history
Change-Id: Ie5e87314202a45b7863960d9d68a29121d30a22a
Closes-Bug: #1468209
Closes-Bug: #1468145
Closes-Bug: #1468143
Closes-Bug: #1466721
Closes-Bug: #1466719
Closes-Bug: #1466717
Closes-Bug: #1466437
  • Loading branch information
sbalineni committed Jun 25, 2015
1 parent 3c3a4a8 commit 91fbdb6
Show file tree
Hide file tree
Showing 2 changed files with 108 additions and 72 deletions.
58 changes: 38 additions & 20 deletions src/config/device-manager/device_manager/db.py
Expand Up @@ -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
Expand All @@ -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)
Expand Down Expand Up @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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', [])])
Expand All @@ -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
Expand All @@ -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)
Expand All @@ -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,
Expand Down
122 changes: 70 additions & 52 deletions src/config/device-manager/device_manager/physical_router_config.py
Expand Up @@ -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 = "<auto-export><family><inet><unicast/></inet></family></auto-export>"
ri_opt.append(etree.fromstring(auto_export))
auto_export = "<auto-export><family><inet><unicast/></inet></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")
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]
Expand Down Expand Up @@ -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")
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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")
Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 91fbdb6

Please sign in to comment.