Merge "VXLAN multicast groups in linuxbridge"

This commit is contained in:
Jenkins 2017-05-30 00:55:21 +00:00 committed by Gerrit Code Review
commit 3c2ce67efe
4 changed files with 97 additions and 1 deletions

View File

@ -58,6 +58,12 @@ vxlan_opts = [
"fully compatible with the allowed-address-pairs "
"extension.")
),
cfg.ListOpt('multicast_ranges',
default=[],
help=_("Optional comma-separated list of "
"<multicast address>:<vni_min>:<vni_max> triples "
"describing how to assign a multicast address to "
"VXLAN according to its VNI ID.")),
]
bridge_opts = [

View File

@ -98,7 +98,30 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
{'brq': bridge, 'net': physnet})
sys.exit(1)
def _is_valid_multicast_range(self, mrange):
try:
addr, vxlan_min, vxlan_max = mrange.split(':')
if int(vxlan_min) > int(vxlan_max):
raise ValueError()
try:
local_ver = netaddr.IPAddress(self.local_ip).version
n_addr = netaddr.IPAddress(addr)
if not n_addr.is_multicast() or n_addr.version != local_ver:
raise ValueError()
except netaddr.core.AddrFormatError:
raise ValueError()
except ValueError:
return False
return True
def validate_vxlan_group_with_local_ip(self):
for r in cfg.CONF.VXLAN.multicast_ranges:
if not self._is_valid_multicast_range(r):
LOG.error("Invalid multicast_range %(r)s. Must be in "
"<multicast address>:<vni_min>:<vni_max> format and "
"addresses must be in the same family as local IP "
"%(loc)s.", {'r': r, 'loc': self.local_ip})
sys.exit(1)
if not cfg.CONF.VXLAN.vxlan_group:
return
try:
@ -186,8 +209,19 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
LOG.warning(_LW("Invalid Segmentation ID: %s, will lead to "
"incorrect vxlan device name"), segmentation_id)
@staticmethod
def _match_multicast_range(segmentation_id):
for mrange in cfg.CONF.VXLAN.multicast_ranges:
addr, vxlan_min, vxlan_max = mrange.split(':')
if int(vxlan_min) <= segmentation_id <= int(vxlan_max):
return addr
def get_vxlan_group(self, segmentation_id):
net = netaddr.IPNetwork(cfg.CONF.VXLAN.vxlan_group)
mcast_addr = self._match_multicast_range(segmentation_id)
if mcast_addr:
net = netaddr.IPNetwork(mcast_addr)
else:
net = netaddr.IPNetwork(cfg.CONF.VXLAN.vxlan_group)
# Map the segmentation ID to (one of) the group address(es)
return str(net.network +
(int(segmentation_id) & int(net.hostmask)))

View File

@ -222,6 +222,45 @@ class TestLinuxBridgeManager(base.BaseTestCase):
vn_id = 257
self.assertEqual('239.1.2.1', self.lbm.get_vxlan_group(vn_id))
def test_get_vxlan_group_with_multicast_address(self):
cfg.CONF.set_override('vxlan_group', '239.1.2.3/32', 'VXLAN')
cfg.CONF.set_override('multicast_ranges',
('224.0.0.10:300:315',
'225.0.0.15:400:600'), 'VXLAN')
vn_id = 300
self.assertEqual('224.0.0.10', self.lbm.get_vxlan_group(vn_id))
vn_id = 500
self.assertEqual('225.0.0.15', self.lbm.get_vxlan_group(vn_id))
vn_id = 315
self.assertEqual('224.0.0.10', self.lbm.get_vxlan_group(vn_id))
vn_id = 4000
# outside of range should fallback to group
self.assertEqual('239.1.2.3', self.lbm.get_vxlan_group(vn_id))
def test__is_valid_multicast_range(self):
bad_ranges = ['224.0.0.10:330:315', 'x:100:200', '10.0.0.1:100:200',
'224.0.0.10:100', '224.0.0.10:100:200:300']
for r in bad_ranges:
self.assertFalse(self.lbm._is_valid_multicast_range(r),
'range %s should have been invalid' % r)
good_ranges = ['224.0.0.10:315:330', '224.0.0.0:315:315']
for r in good_ranges:
self.assertTrue(self.lbm._is_valid_multicast_range(r),
'range %s should have been valid' % r)
# v4 ranges are bad when a v6 local_ip is present
self.lbm.local_ip = '2000::1'
for r in good_ranges:
self.assertFalse(self.lbm._is_valid_multicast_range(r),
'range %s should have been invalid' % r)
def test__match_multicast_range(self):
cfg.CONF.set_override('multicast_ranges',
('224.0.0.10:300:315',
'225.0.0.15:400:600'), 'VXLAN')
self.assertEqual('224.0.0.10', self.lbm._match_multicast_range(307))
self.assertEqual('225.0.0.15', self.lbm._match_multicast_range(407))
self.assertIsNone(self.lbm._match_multicast_range(399))
def test_get_vxlan_group_with_ipv6(self):
cfg.CONF.set_override('local_ip', LOCAL_IPV6, 'VXLAN')
self.lbm.local_ip = LOCAL_IPV6

View File

@ -0,0 +1,17 @@
---
prelude: >
Enable creation of VXLANs with different multicast
addresses allocated by VNI-address mappings.
features:
- The ability to control vni-multicast address
distribution in linuxbridge agent via new config
option - multicast_ranges.
other:
- Example configuration of `multicast_ranges` in
ml2_conf.ini under the `[vxlan]` config. section
multicast_ranges = 224.0.0.10:10:90,225.0.0.15:100:900
For VNI between 10 and 90, the multicast address
224.0.0.0.10 will be used, and for 100 through 900
225.0.0.15 will be used. Other VNI values will get
standard `vxlan_group` address. For more info see RFE
`<https://bugs.launchpad.net/neutron/+bug/1579068>`