Skip to content

Commit

Permalink
DM: VRF instances are configured based on VN forwarding mode
Browse files Browse the repository at this point in the history
- VN forwarding mode {l2, l2_l3} - Configure L2 VRF
- VN forwarding mode {l3, l2_l3} - Configure L3 VRF
- L2 VRF will only have interface config
- IRB interfaces, irb ip allocation is done only if fwd mode is 'l2_l3'
- For all external VNs subnets, add a static route in  global
  forwarding options
- for all L3 vrf instances, static routes with discard nexthops are added.

Change-Id: I860fb6c59b85391e667554d8b57602f24cd14e48
Closes-Bug: #1472699
  • Loading branch information
sbalineni committed Sep 4, 2015
1 parent c9a7a26 commit 140154b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 40 deletions.
37 changes: 23 additions & 14 deletions src/config/device-manager/device_manager/db.py
Expand Up @@ -345,16 +345,13 @@ def push_config(self):
continue
import_set |= ri2.export_targets

if vn_obj.router_external == False:
irb_ips = vn_irb_ip_map.get(vn_id, [])
self.config_manager.add_routing_instance(vrf_name_l3,
import_set,
export_set,
vn_obj.get_prefixes(),
irb_ips,
vn_obj.router_external,
["irb" + "." + str(vn_obj.vn_network_id)])
if vn_obj.forwarding_mode in ['l2', 'l2_l3']:
irb_ips = None
if vn_obj.forwarding_mode == 'l2_l3':
irb_ips = vn_irb_ip_map.get(vn_id, [])
self.config_manager.add_routing_instance(vrf_name_l2,
True,
vn_obj.forwarding_mode == 'l2_l3',
import_set,
export_set,
vn_obj.get_prefixes(),
Expand All @@ -363,16 +360,16 @@ def push_config(self):
interfaces,
vn_obj.vxlan_vni,
None, vn_obj.vn_network_id)
else:

if vn_obj.forwarding_mode in ['l3', 'l2_l3']:
self.config_manager.add_routing_instance(vrf_name_l3,
False,
vn_obj.forwarding_mode == 'l2_l3',
import_set,
export_set,
vn_obj.get_prefixes(),
None,
vn_obj.router_external,
interfaces,
vn_obj.vxlan_vni,
None, vn_obj.vn_network_id)
vn_obj.router_external)

break

Expand All @@ -388,6 +385,8 @@ def push_config(self):
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,
False,
False,
import_set,
set(),
None,
Expand Down Expand Up @@ -709,6 +708,7 @@ def __init__(self, uuid, obj_dict=None):
self.physical_routers = set()
self.router_external = False
self.vxlan_vni = None
self.forwarding_mode = None
self.gateways = None
self.instance_ip_map = {}
self.update(obj_dict)
Expand All @@ -725,6 +725,7 @@ def update(self, obj=None):
self.router_external = False
self.vn_network_id = obj.get('virtual_network_network_id')
self.set_vxlan_vni(obj)
self.forwarding_mode = self.get_forwarding_mode(obj)
self.routing_instances = set([ri['uuid'] for ri in
obj.get('routing_instances', [])])
self.virtual_machine_interfaces = set(
Expand Down Expand Up @@ -772,6 +773,14 @@ def set_vxlan_vni(self, obj=None):
pass
#end set_vxlan_vni

def get_forwarding_mode(self, obj):
default_mode = 'l2_l3'
prop = obj.get('virtual_network_properties')
if prop:
return prop.get('forwarding_mode', default_mode)
return default_mode
#end get_forwarding_mode

def update_instance_ip_map(self):
self.instance_ip_map = {}
for vmi_uuid in self.virtual_machine_interfaces:
Expand Down
69 changes: 43 additions & 26 deletions src/config/device-manager/device_manager/physical_router_config.py
Expand Up @@ -133,16 +133,18 @@ def add_dynamic_tunnels(self, tunnel_source_ip, ip_fabric_nets, bgp_router_ips):

'''
ri_name: routing instance name to be configured on mx
is_l2: a flag used to indicate routing instance type, i.e : l2 or l3
is_l2_l3: VN forwarding mode is of type 'l2_l3' or not
import/export targets: routing instance import, export targets
prefixes: for l3 public vrf static routes, bug#1395938
prefixes: for l3 vrf static routes and for public vrf filter terms
gateways: for l2 evpn, bug#1395944
router_external: this indicates the routing instance configured is for
the public network
interfaces: logical interfaces to be part of vrf
fip_map: contrail instance ip to floating-ip map, used for snat & floating ip support
network_id : this is used for configuraing irb interfaces
'''
def add_routing_instance(self, ri_name, import_targets, export_targets,
def add_routing_instance(self, ri_name, is_l2, is_l2_l3, import_targets, export_targets,
prefixes=[], gateways=[], router_external=False,
interfaces=[], vni=None, fip_map=None, network_id=None):
self.routing_instances[ri_name] = {'import_targets': import_targets,
Expand All @@ -159,7 +161,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
ri = etree.SubElement(ri_config, "instance")
etree.SubElement(ri, "name").text = ri_name
ri_opt = None
if router_external:
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")
Expand All @@ -170,14 +172,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
etree.SubElement(ri, "vrf-import").text = ri_name + "-import"
etree.SubElement(ri, "vrf-export").text = ri_name + "-export"

if vni is None or router_external:
etree.SubElement(ri, "instance-type").text = "vrf"
etree.SubElement(ri, "vrf-table-label") #only for l3
if fip_map is None:
for interface in interfaces:
if_element = etree.SubElement(ri, "interface")
etree.SubElement(if_element, "name").text = interface

if not is_l2:
if ri_opt is None:
ri_opt = etree.SubElement(ri, "routing-options")
if prefixes and fip_map is None:
Expand All @@ -186,6 +181,17 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
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"
etree.SubElement(ri, "vrf-table-label") #only for l3
if fip_map is None:
for interface in interfaces:
if_element = etree.SubElement(ri, "interface")
etree.SubElement(if_element, "name").text = interface
if ri_opt is None:
ri_opt = etree.SubElement(ri, "routing-options")
auto_export = "<auto-export><family><inet><unicast/></inet></family></auto-export>"
ri_opt.append(etree.fromstring(auto_export))
else:
Expand Down Expand Up @@ -314,7 +320,7 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
bd_config = None
interfaces_config = self.interfaces_config
proto_config = self.proto_config
if (router_external==False and vni is not None and
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")
Expand All @@ -326,26 +332,28 @@ def add_routing_instance(self, ri_name, import_targets, export_targets,
for interface in interfaces:
if_element = etree.SubElement(bd, "interface")
etree.SubElement(if_element, "name").text = interface
etree.SubElement(bd, "routing-interface").text = "irb." + str(network_id) #network_id is unique, hence irb
if is_l2_l3:
etree.SubElement(bd, "routing-interface").text = "irb." + str(network_id) #network_id is unique, hence irb
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")
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 = etree.SubElement(family, "inet")
for (irb_ip, gateway) in gateways:
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
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 = etree.SubElement(family, "inet")
for (irb_ip, gateway) in gateways:
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"
Expand Down Expand Up @@ -452,6 +460,15 @@ def set_global_routing_options(self, bgp_params):
etree.SubElement(self.global_routing_options_config, "router-id").text = bgp_params['address']
#end set_global_routing_options

def add_to_global_ri_opts(self, prefix):
if self.global_routing_options_config is None:
self.global_routing_options_config = etree.Element("routing-options")
static_config = etree.SubElement(self.global_routing_options_config, "static")
route_config = etree.SubElement(static_config, "route")
etree.SubElement(route_config, "name").text = prefix
etree.SubElement(route_config, "discard")
#end add_to_global_ri_opts

def is_family_configured(self, params, family_name):
if params is None or params.get('address_families') is None:
return False
Expand Down

0 comments on commit 140154b

Please sign in to comment.