Allow to set UDP ports for VXLAN in Linuxbridge agent
Introduce vxlan.{udp_srcport_min, udp_srcport_max and udp_dstport} for setting the port range used for VXLAN communication. Change-Id: I97999988090eee7aee9b533ac1dad2de95b29cbe Closes-Bug: #1483853 DocImpact: vxlan.{udp_srcport_min, udp_srcport_max and udp_dstport} can be used to set UDP port numbers used for VXLAN in LinuxBridge agent.
This commit is contained in:
parent
05c22d6199
commit
d7c4428525
@ -237,7 +237,7 @@ class IPWrapper(SubProcessBase):
|
|||||||
return IPDevice(name, namespace=self.namespace)
|
return IPDevice(name, namespace=self.namespace)
|
||||||
|
|
||||||
def add_vxlan(self, name, vni, group=None, dev=None, ttl=None, tos=None,
|
def add_vxlan(self, name, vni, group=None, dev=None, ttl=None, tos=None,
|
||||||
local=None, port=None, proxy=False):
|
local=None, srcport=None, dstport=None, proxy=False):
|
||||||
cmd = ['add', name, 'type', 'vxlan', 'id', vni]
|
cmd = ['add', name, 'type', 'vxlan', 'id', vni]
|
||||||
if group:
|
if group:
|
||||||
cmd.extend(['group', group])
|
cmd.extend(['group', group])
|
||||||
@ -252,10 +252,13 @@ class IPWrapper(SubProcessBase):
|
|||||||
if proxy:
|
if proxy:
|
||||||
cmd.append('proxy')
|
cmd.append('proxy')
|
||||||
# tuple: min,max
|
# tuple: min,max
|
||||||
if port and len(port) == 2:
|
if srcport:
|
||||||
cmd.extend(['port', port[0], port[1]])
|
if len(srcport) == 2 and srcport[0] <= srcport[1]:
|
||||||
elif port:
|
cmd.extend(['srcport', str(srcport[0]), str(srcport[1])])
|
||||||
raise n_exc.NetworkVxlanPortRangeError(vxlan_range=port)
|
else:
|
||||||
|
raise n_exc.NetworkVxlanPortRangeError(vxlan_range=srcport)
|
||||||
|
if dstport:
|
||||||
|
cmd.extend(['dstport', str(dstport)])
|
||||||
self._as_root([], 'link', cmd)
|
self._as_root([], 'link', cmd)
|
||||||
return (IPDevice(name, namespace=self.namespace))
|
return (IPDevice(name, namespace=self.namespace))
|
||||||
|
|
||||||
|
@ -47,6 +47,18 @@ vxlan_opts = [
|
|||||||
"value must match the value of the 'overlay_ip_version' "
|
"value must match the value of the 'overlay_ip_version' "
|
||||||
"option in the ML2 plug-in configuration file on the "
|
"option in the ML2 plug-in configuration file on the "
|
||||||
"neutron server node(s).")),
|
"neutron server node(s).")),
|
||||||
|
cfg.PortOpt('udp_srcport_min', default=0,
|
||||||
|
help=_("The minimum of the UDP source port range used for "
|
||||||
|
"VXLAN communication.")),
|
||||||
|
cfg.PortOpt('udp_srcport_max', default=0,
|
||||||
|
help=_("The maximum of the UDP source port range used for "
|
||||||
|
"VXLAN communication.")),
|
||||||
|
cfg.PortOpt('udp_dstport',
|
||||||
|
help=_("The UDP port used for VXLAN communication. By "
|
||||||
|
"default, the Linux kernel doesn't use the IANA "
|
||||||
|
"assigned standard value, so if you want to use it, "
|
||||||
|
"this option must be set to 4789. It is not set by "
|
||||||
|
"default because of backward compatibiltiy.")),
|
||||||
cfg.BoolOpt('l2_population', default=False,
|
cfg.BoolOpt('l2_population', default=False,
|
||||||
help=_("Extension to use alongside ml2 plugin's l2population "
|
help=_("Extension to use alongside ml2 plugin's l2population "
|
||||||
"mechanism driver. It enables the plugin to populate "
|
"mechanism driver. It enables the plugin to populate "
|
||||||
|
@ -321,15 +321,17 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
|
|||||||
"VNI %(segmentation_id)s",
|
"VNI %(segmentation_id)s",
|
||||||
{'interface': interface,
|
{'interface': interface,
|
||||||
'segmentation_id': segmentation_id})
|
'segmentation_id': segmentation_id})
|
||||||
args = {'dev': self.local_int}
|
args = {'dev': self.local_int,
|
||||||
|
'srcport': (cfg.CONF.VXLAN.udp_srcport_min,
|
||||||
|
cfg.CONF.VXLAN.udp_srcport_max),
|
||||||
|
'dstport': cfg.CONF.VXLAN.udp_dstport,
|
||||||
|
'ttl': cfg.CONF.VXLAN.ttl,
|
||||||
|
'tos': cfg.CONF.VXLAN.tos}
|
||||||
if self.vxlan_mode == lconst.VXLAN_MCAST:
|
if self.vxlan_mode == lconst.VXLAN_MCAST:
|
||||||
args['group'] = self.get_vxlan_group(segmentation_id)
|
args['group'] = self.get_vxlan_group(segmentation_id)
|
||||||
if cfg.CONF.VXLAN.ttl:
|
|
||||||
args['ttl'] = cfg.CONF.VXLAN.ttl
|
|
||||||
if cfg.CONF.VXLAN.tos:
|
|
||||||
args['tos'] = cfg.CONF.VXLAN.tos
|
|
||||||
if cfg.CONF.VXLAN.l2_population:
|
if cfg.CONF.VXLAN.l2_population:
|
||||||
args['proxy'] = cfg.CONF.VXLAN.arp_responder
|
args['proxy'] = cfg.CONF.VXLAN.arp_responder
|
||||||
|
|
||||||
try:
|
try:
|
||||||
int_vxlan = self.ip.add_vxlan(interface, segmentation_id,
|
int_vxlan = self.ip.add_vxlan(interface, segmentation_id,
|
||||||
**args)
|
**args)
|
||||||
|
@ -496,13 +496,13 @@ class TestIpWrapper(base.BaseTestCase):
|
|||||||
run_as_root=True, namespace=None,
|
run_as_root=True, namespace=None,
|
||||||
log_fail_as_error=True)
|
log_fail_as_error=True)
|
||||||
|
|
||||||
def test_add_vxlan_valid_port_length(self):
|
def test_add_vxlan_valid_srcport_length(self):
|
||||||
retval = ip_lib.IPWrapper().add_vxlan('vxlan0', 'vni0',
|
retval = ip_lib.IPWrapper().add_vxlan('vxlan0', 'vni0',
|
||||||
group='group0',
|
group='group0',
|
||||||
dev='dev0', ttl='ttl0',
|
dev='dev0', ttl='ttl0',
|
||||||
tos='tos0',
|
tos='tos0',
|
||||||
local='local0', proxy=True,
|
local='local0', proxy=True,
|
||||||
port=('1', '2'))
|
srcport=(1, 2))
|
||||||
self.assertIsInstance(retval, ip_lib.IPDevice)
|
self.assertIsInstance(retval, ip_lib.IPDevice)
|
||||||
self.assertEqual(retval.name, 'vxlan0')
|
self.assertEqual(retval.name, 'vxlan0')
|
||||||
self.execute.assert_called_once_with([], 'link',
|
self.execute.assert_called_once_with([], 'link',
|
||||||
@ -511,17 +511,47 @@ class TestIpWrapper(base.BaseTestCase):
|
|||||||
'group0', 'dev', 'dev0',
|
'group0', 'dev', 'dev0',
|
||||||
'ttl', 'ttl0', 'tos', 'tos0',
|
'ttl', 'ttl0', 'tos', 'tos0',
|
||||||
'local', 'local0', 'proxy',
|
'local', 'local0', 'proxy',
|
||||||
'port', '1', '2'],
|
'srcport', '1', '2'],
|
||||||
run_as_root=True, namespace=None,
|
run_as_root=True, namespace=None,
|
||||||
log_fail_as_error=True)
|
log_fail_as_error=True)
|
||||||
|
|
||||||
def test_add_vxlan_invalid_port_length(self):
|
def test_add_vxlan_invalid_srcport_length(self):
|
||||||
wrapper = ip_lib.IPWrapper()
|
wrapper = ip_lib.IPWrapper()
|
||||||
self.assertRaises(n_exc.NetworkVxlanPortRangeError,
|
self.assertRaises(n_exc.NetworkVxlanPortRangeError,
|
||||||
wrapper.add_vxlan, 'vxlan0', 'vni0', group='group0',
|
wrapper.add_vxlan, 'vxlan0', 'vni0', group='group0',
|
||||||
dev='dev0', ttl='ttl0', tos='tos0',
|
dev='dev0', ttl='ttl0', tos='tos0',
|
||||||
local='local0', proxy=True,
|
local='local0', proxy=True,
|
||||||
port=('1', '2', '3'))
|
srcport=('1', '2', '3'))
|
||||||
|
|
||||||
|
def test_add_vxlan_invalid_srcport_range(self):
|
||||||
|
wrapper = ip_lib.IPWrapper()
|
||||||
|
self.assertRaises(n_exc.NetworkVxlanPortRangeError,
|
||||||
|
wrapper.add_vxlan, 'vxlan0', 'vni0', group='group0',
|
||||||
|
dev='dev0', ttl='ttl0', tos='tos0',
|
||||||
|
local='local0', proxy=True,
|
||||||
|
srcport=(2000, 1000))
|
||||||
|
|
||||||
|
def test_add_vxlan_dstport(self):
|
||||||
|
retval = ip_lib.IPWrapper().add_vxlan('vxlan0', 'vni0',
|
||||||
|
group='group0',
|
||||||
|
dev='dev0', ttl='ttl0',
|
||||||
|
tos='tos0',
|
||||||
|
local='local0', proxy=True,
|
||||||
|
srcport=(1, 2),
|
||||||
|
dstport=4789)
|
||||||
|
|
||||||
|
self.assertIsInstance(retval, ip_lib.IPDevice)
|
||||||
|
self.assertEqual(retval.name, 'vxlan0')
|
||||||
|
self.execute.assert_called_once_with([], 'link',
|
||||||
|
['add', 'vxlan0', 'type',
|
||||||
|
'vxlan', 'id', 'vni0', 'group',
|
||||||
|
'group0', 'dev', 'dev0',
|
||||||
|
'ttl', 'ttl0', 'tos', 'tos0',
|
||||||
|
'local', 'local0', 'proxy',
|
||||||
|
'srcport', '1', '2',
|
||||||
|
'dstport', '4789'],
|
||||||
|
run_as_root=True, namespace=None,
|
||||||
|
log_fail_as_error=True)
|
||||||
|
|
||||||
def test_add_device_to_namespace(self):
|
def test_add_device_to_namespace(self):
|
||||||
dev = mock.Mock()
|
dev = mock.Mock()
|
||||||
|
@ -392,6 +392,10 @@ class TestLinuxBridgeManager(base.BaseTestCase):
|
|||||||
self.assertEqual("vxlan-" + seg_id, retval)
|
self.assertEqual("vxlan-" + seg_id, retval)
|
||||||
add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
|
add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
|
||||||
group="224.0.0.1",
|
group="224.0.0.1",
|
||||||
|
srcport=(0, 0),
|
||||||
|
dstport=None,
|
||||||
|
ttl=None,
|
||||||
|
tos=None,
|
||||||
dev=self.lbm.local_int)
|
dev=self.lbm.local_int)
|
||||||
dv6_fn.assert_called_once_with()
|
dv6_fn.assert_called_once_with()
|
||||||
cfg.CONF.set_override('l2_population', 'True', 'VXLAN')
|
cfg.CONF.set_override('l2_population', 'True', 'VXLAN')
|
||||||
@ -399,6 +403,10 @@ class TestLinuxBridgeManager(base.BaseTestCase):
|
|||||||
self.lbm.ensure_vxlan(seg_id))
|
self.lbm.ensure_vxlan(seg_id))
|
||||||
add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
|
add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
|
||||||
group="224.0.0.1",
|
group="224.0.0.1",
|
||||||
|
srcport=(0, 0),
|
||||||
|
dstport=None,
|
||||||
|
ttl=None,
|
||||||
|
tos=None,
|
||||||
dev=self.lbm.local_int,
|
dev=self.lbm.local_int,
|
||||||
proxy=expected_proxy)
|
proxy=expected_proxy)
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- UDP ports used by VXLAN in the LinuxBridge agent
|
||||||
|
can be configured now with the VXLAN.udp_srcport_min,
|
||||||
|
VXLAN.udp_srcport_max and VXLAN.udp_dstport config
|
||||||
|
options. To use the IANA assigned port number, set
|
||||||
|
VXLAN.udp_dstport to 4789. The default is not changed
|
||||||
|
from the Linux kernel default 8472.
|
Loading…
Reference in New Issue
Block a user