Skip to content

Commit

Permalink
PBB EVPN changes
Browse files Browse the repository at this point in the history
Changes included:
 1. Schema changes to make bridge-domain as child of virtua-network

 2. Don't allow VMI to refer to different bridge domain for same vlan tag.
 e.g. Say, VMI refers to BD1 for vlan tag 0, don't allow this VMI to refer to
 another bridge domain(BD2) for vlan tag 0.

 3. Add Unit test case for restricting VMI link to single bridge-domain
 for a given vlan tag

Change-Id: Ic8599153a4a413b118b7e4968d9988b02aa6c539
Related-bug: 1645092
Closes-Bug: 1653941
Closes-Bug: 1653938
  • Loading branch information
bailkeri committed Feb 7, 2017
1 parent f55210d commit 3cbe6fd
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
43 changes: 43 additions & 0 deletions src/config/api-server/tests/test_crud_basic.py
Expand Up @@ -415,6 +415,49 @@ def test_physical_router_credentials(self):
if user_cred_read.password != '**Password Hidden**':
raise Exception("ERROR: physical-router: password should be hidden")
#end test_physical_router_credentials

def test_bridge_domain_with_vmi_ref_multiple_bd(self):
vn1_name = self.id() + '-vn-1'
vn1 = VirtualNetwork(vn1_name)
logger.info('Creating VN %s', vn1_name)
self._vnc_lib.virtual_network_create(vn1)

vmi_name = self.id() + '-port'
logger.info('Creating port %s', vmi_name)
vmi = VirtualMachineInterface(vmi_name, parent_obj=Project())
vmi.add_virtual_network(vn1)
self._vnc_lib.virtual_machine_interface_create(vmi)

bd1_name = self.id() + '-bd-1'
bd1 = BridgeDomain(bd1_name, parent_obj=vn1)
bd1.set_isid(200200)
logger.info('Creating Bridge Domain %s', bd1_name)
self._vnc_lib.bridge_domain_create(bd1)

bd2_name = self.id() + '-bd-2'
bd2 = BridgeDomain(bd2_name, parent_obj=vn1)
bd2.set_isid(300300)
logger.info('Creating Bridge Domain %s', bd2_name)
self._vnc_lib.bridge_domain_create(bd2)

bd_ref_data1 = BridgeDomainMembershipType();
bd_ref_data1.set_vlan_tag(0);

# VMI is referring to two bridge domain(bd1 and bd2) for vlan tag = 0
vmi.add_bridge_domain(bd1, bd_ref_data1);
vmi.add_bridge_domain(bd2, bd_ref_data1);
with ExpectedException(BadRequest) as e:
self._vnc_lib.virtual_machine_interface_update(vmi)

# Link the VMI to two bridge domain for different vlan tags(0, 1)
vmi_obj = self._vnc_lib.virtual_machine_interface_read(id=vmi.uuid)
bd_ref_data1 = BridgeDomainMembershipType(vlan_tag=1);
bd_ref_data2 = BridgeDomainMembershipType(vlan_tag=2);
vmi_obj.add_bridge_domain(bd1, bd_ref_data1);
vmi_obj.add_bridge_domain(bd2, bd_ref_data2);
self._vnc_lib.virtual_machine_interface_update(vmi_obj)
# end test_bridge_domain_with_vmi_ref_multiple_bd

# end class TestCrud

class TestVncCfgApiServer(test_case.ApiServerTestCase):
Expand Down
34 changes: 34 additions & 0 deletions src/config/api-server/vnc_cfg_types.py
Expand Up @@ -776,6 +776,30 @@ def _check_vrouter_link(cls, vmi_data, kvp_dict, obj_dict, db_conn):

# end _check_vrouter_link

@classmethod
def _check_bridge_domain_vmi_association(cls, obj_dict,
db_conn, create):
bridge_domain_links = {}
bd_refs = obj_dict.get('bridge_domain_refs') or []
for bd in bd_refs:
bd_fq_name = bd['to']
bd_uuid = bd.get('uuid')
if not bd_uuid:
bd_uuid = db_conn.fq_name_to_uuid('bridge_domain', bd_fq_name)

bdmt = bd['attr']
vlan_tag = bdmt['vlan_tag']
if vlan_tag in bridge_domain_links:
msg = "Virtual machine interface(%s) already refers to bridge "\
"domain(%s) for vlan tag %d"\
%(obj_dict['uuid'], bd_uuid, vlan_tag)
return (False, msg)

bridge_domain_links[vlan_tag] = bd_uuid

return (True, '')
# end _check_bridge_domain_vmi_association

@classmethod
def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):
vn_dict = obj_dict['virtual_network_refs'][0]
Expand All @@ -795,6 +819,11 @@ def pre_dbe_create(cls, tenant_name, obj_dict, db_conn):

vn_dict = result

(ok, error) = cls._check_bridge_domain_vmi_association(obj_dict,
db_conn, True)
if not ok:
return (False, (400, error))

inmac = None
if 'virtual_machine_interface_mac_addresses' in obj_dict:
mc = obj_dict['virtual_machine_interface_mac_addresses']
Expand Down Expand Up @@ -882,6 +911,11 @@ def pre_dbe_update(cls, id, fq_name, obj_dict, db_conn,
if not ok:
return ok, read_result

(ok, error) = cls._check_bridge_domain_vmi_association(obj_dict,
db_conn, False)
if not ok:
return (False, (400, error))

# check if the vmi is a internal interface of a logical
# router
if (read_result.get('logical_router_back_refs') and
Expand Down
4 changes: 2 additions & 2 deletions src/schema/vnc_cfg.xsd
Expand Up @@ -3030,8 +3030,8 @@ targetNamespace="http://www.contrailsystems.com/2012/VNC-CONFIG/0">
<xsd:element name="virtual-network-bridge-domain"/>
<!--#IFMAP-SEMANTICS-IDL
Link('virtual-network-bridge-domain',
'virtual-network', 'bridge-domain', ['ref'], 'optional', 'CRUD',
'Reference to bridge-domain of this virtual network.') -->
'virtual-network', 'bridge-domain', ['has'], 'optional', 'CRUD',
'bridge-domains configured in a virtual network') -->

<xsd:element name="vlan-tag-based-bridge-domain" type="xsd:boolean"
default="false"/>
Expand Down

0 comments on commit 3cbe6fd

Please sign in to comment.