Merge "Adding DSCP mark and inheritance in OVS and LB tunnels outer header"
This commit is contained in:
commit
2820c25e3a
@ -151,6 +151,36 @@ On the network and compute nodes:
|
|||||||
QoS currently works with ml2 only (SR-IOV, Open vSwitch, and linuxbridge
|
QoS currently works with ml2 only (SR-IOV, Open vSwitch, and linuxbridge
|
||||||
are drivers enabled for QoS).
|
are drivers enabled for QoS).
|
||||||
|
|
||||||
|
DSCP marking on outer header for overlay networks
|
||||||
|
-------------------------------------------------
|
||||||
|
|
||||||
|
When using overlay networks (e.g., VxLAN), the DSCP marking rule only
|
||||||
|
applies to the inner header, and during encapsulation, the DSCP mark is
|
||||||
|
not automatically copied to the outer header.
|
||||||
|
|
||||||
|
#. In order to set the DSCP value of the outer header, modify the ``dscp``
|
||||||
|
configuration option in ``/etc/neutron/plugins/ml2/<agent_name>_agent.ini``
|
||||||
|
where ``<agent_name>`` is the name of the agent being used
|
||||||
|
(e.g., ``openvswitch``):
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
dscp = 8
|
||||||
|
|
||||||
|
#. In order to copy the DSCP field of the inner header to the outer header,
|
||||||
|
change the ``dscp_inherit`` configuration option to true in
|
||||||
|
``/etc/neutron/plugins/ml2/<agent_name>_agent.ini`` where ``<agent_name>``
|
||||||
|
is the name of the agent being used (e.g., ``openvswitch``):
|
||||||
|
|
||||||
|
.. code-block:: ini
|
||||||
|
|
||||||
|
[agent]
|
||||||
|
dscp_inherit = true
|
||||||
|
|
||||||
|
If the ``dscp_inherit`` option is set to true, the previous ``dscp`` option
|
||||||
|
is overwritten.
|
||||||
|
|
||||||
Trusted projects policy.json configuration
|
Trusted projects policy.json configuration
|
||||||
------------------------------------------
|
------------------------------------------
|
||||||
|
|
||||||
|
@ -458,7 +458,8 @@ class OVSBridge(BaseOVS):
|
|||||||
tunnel_type=p_const.TYPE_GRE,
|
tunnel_type=p_const.TYPE_GRE,
|
||||||
vxlan_udp_port=p_const.VXLAN_UDP_PORT,
|
vxlan_udp_port=p_const.VXLAN_UDP_PORT,
|
||||||
dont_fragment=True,
|
dont_fragment=True,
|
||||||
tunnel_csum=False):
|
tunnel_csum=False,
|
||||||
|
tos=None):
|
||||||
attrs = [('type', tunnel_type)]
|
attrs = [('type', tunnel_type)]
|
||||||
# TODO(twilson) This is an OrderedDict solely to make a test happy
|
# TODO(twilson) This is an OrderedDict solely to make a test happy
|
||||||
options = collections.OrderedDict()
|
options = collections.OrderedDict()
|
||||||
@ -475,6 +476,8 @@ class OVSBridge(BaseOVS):
|
|||||||
options['out_key'] = 'flow'
|
options['out_key'] = 'flow'
|
||||||
if tunnel_csum:
|
if tunnel_csum:
|
||||||
options['csum'] = str(tunnel_csum).lower()
|
options['csum'] = str(tunnel_csum).lower()
|
||||||
|
if tos:
|
||||||
|
options['tos'] = str(tos)
|
||||||
attrs.append(('options', options))
|
attrs.append(('options', options))
|
||||||
|
|
||||||
return self.add_port(port_name, *attrs)
|
return self.add_port(port_name, *attrs)
|
||||||
|
@ -26,6 +26,14 @@ agent_opts = [
|
|||||||
help=_("Set new timeout in seconds for new rpc calls after "
|
help=_("Set new timeout in seconds for new rpc calls after "
|
||||||
"agent receives SIGTERM. If value is set to 0, rpc "
|
"agent receives SIGTERM. If value is set to 0, rpc "
|
||||||
"timeout won't be changed")),
|
"timeout won't be changed")),
|
||||||
|
cfg.IntOpt('dscp', min=0, max=63,
|
||||||
|
help=_("The DSCP value to use for outer headers during tunnel "
|
||||||
|
"encapsulation.")),
|
||||||
|
cfg.BoolOpt('dscp_inherit', default=False,
|
||||||
|
help=_("If set to True, the DSCP value of tunnel "
|
||||||
|
"interfaces is overwritten and set to inherit. "
|
||||||
|
"The DSCP value of the inner header is then "
|
||||||
|
"copied to the outer header.")),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,7 +30,11 @@ vxlan_opts = [
|
|||||||
cfg.IntOpt('ttl',
|
cfg.IntOpt('ttl',
|
||||||
help=_("TTL for vxlan interface protocol packets.")),
|
help=_("TTL for vxlan interface protocol packets.")),
|
||||||
cfg.IntOpt('tos',
|
cfg.IntOpt('tos',
|
||||||
help=_("TOS for vxlan interface protocol packets.")),
|
deprecated_for_removal=True,
|
||||||
|
help=_("TOS for vxlan interface protocol packets. This option "
|
||||||
|
"is deprecated in favor of the dscp option in the AGENT "
|
||||||
|
"section and will be removed in a future release. "
|
||||||
|
"To convert the TOS value to DSCP, divide by 4.")),
|
||||||
cfg.StrOpt('vxlan_group', default=DEFAULT_VXLAN_GROUP,
|
cfg.StrOpt('vxlan_group', default=DEFAULT_VXLAN_GROUP,
|
||||||
help=_("Multicast group(s) for vxlan interface. A range of "
|
help=_("Multicast group(s) for vxlan interface. A range of "
|
||||||
"group addresses may be specified by using CIDR "
|
"group addresses may be specified by using CIDR "
|
||||||
|
@ -96,9 +96,6 @@ ovs_opts = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
agent_opts = [
|
agent_opts = [
|
||||||
cfg.IntOpt('polling_interval', default=2,
|
|
||||||
help=_("The number of seconds the agent will wait between "
|
|
||||||
"polling for local device changes.")),
|
|
||||||
cfg.BoolOpt('minimize_polling',
|
cfg.BoolOpt('minimize_polling',
|
||||||
default=True,
|
default=True,
|
||||||
help=_("Minimize polling by monitoring ovsdb for interface "
|
help=_("Minimize polling by monitoring ovsdb for interface "
|
||||||
@ -128,10 +125,6 @@ agent_opts = [
|
|||||||
"outgoing IP packet carrying GRE/VXLAN tunnel.")),
|
"outgoing IP packet carrying GRE/VXLAN tunnel.")),
|
||||||
cfg.BoolOpt('enable_distributed_routing', default=False,
|
cfg.BoolOpt('enable_distributed_routing', default=False,
|
||||||
help=_("Make the l2 agent run in DVR mode.")),
|
help=_("Make the l2 agent run in DVR mode.")),
|
||||||
cfg.IntOpt('quitting_rpc_timeout', default=10,
|
|
||||||
help=_("Set new timeout in seconds for new rpc calls after "
|
|
||||||
"agent receives SIGTERM. If value is set to 0, rpc "
|
|
||||||
"timeout won't be changed")),
|
|
||||||
cfg.BoolOpt('drop_flows_on_start', default=False,
|
cfg.BoolOpt('drop_flows_on_start', default=False,
|
||||||
help=_("Reset flow table on start. Setting this to True will "
|
help=_("Reset flow table on start. Setting this to True will "
|
||||||
"cause brief traffic interruption.")),
|
"cause brief traffic interruption.")),
|
||||||
|
@ -328,8 +328,18 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
|
|||||||
'srcport': (cfg.CONF.VXLAN.udp_srcport_min,
|
'srcport': (cfg.CONF.VXLAN.udp_srcport_min,
|
||||||
cfg.CONF.VXLAN.udp_srcport_max),
|
cfg.CONF.VXLAN.udp_srcport_max),
|
||||||
'dstport': cfg.CONF.VXLAN.udp_dstport,
|
'dstport': cfg.CONF.VXLAN.udp_dstport,
|
||||||
'ttl': cfg.CONF.VXLAN.ttl,
|
'ttl': cfg.CONF.VXLAN.ttl}
|
||||||
'tos': cfg.CONF.VXLAN.tos}
|
if cfg.CONF.VXLAN.tos:
|
||||||
|
args['tos'] = cfg.CONF.VXLAN.tos
|
||||||
|
if cfg.CONF.AGENT.dscp or cfg.CONF.AGENT.dscp_inherit:
|
||||||
|
LOG.warning('The deprecated tos option in group VXLAN '
|
||||||
|
'is set and takes precedence over dscp and '
|
||||||
|
'dscp_inherit in group AGENT.')
|
||||||
|
elif cfg.CONF.AGENT.dscp_inherit:
|
||||||
|
args['tos'] = 'inherit'
|
||||||
|
elif cfg.CONF.AGENT.dscp:
|
||||||
|
args['tos'] = int(cfg.CONF.AGENT.dscp) << 2
|
||||||
|
|
||||||
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.l2_population:
|
if cfg.CONF.VXLAN.l2_population:
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
|
|
||||||
from neutron.conf.agent import common as config
|
from neutron.conf.agent import common as config
|
||||||
|
from neutron.conf.plugins.ml2.drivers import agent
|
||||||
from neutron.conf.plugins.ml2.drivers import ovs_conf
|
from neutron.conf.plugins.ml2.drivers import ovs_conf
|
||||||
|
|
||||||
|
agent.register_agent_opts()
|
||||||
ovs_conf.register_ovs_agent_opts()
|
ovs_conf.register_ovs_agent_opts()
|
||||||
config.register_agent_state_opts_helper(cfg.CONF)
|
config.register_agent_state_opts_helper(cfg.CONF)
|
||||||
|
@ -195,6 +195,11 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
|||||||
self.vxlan_udp_port = agent_conf.vxlan_udp_port
|
self.vxlan_udp_port = agent_conf.vxlan_udp_port
|
||||||
self.dont_fragment = agent_conf.dont_fragment
|
self.dont_fragment = agent_conf.dont_fragment
|
||||||
self.tunnel_csum = agent_conf.tunnel_csum
|
self.tunnel_csum = agent_conf.tunnel_csum
|
||||||
|
self.tos = ('inherit'
|
||||||
|
if agent_conf.dscp_inherit
|
||||||
|
else (int(agent_conf.dscp) << 2
|
||||||
|
if agent_conf.dscp
|
||||||
|
else None))
|
||||||
self.tun_br = None
|
self.tun_br = None
|
||||||
self.patch_int_ofport = constants.OFPORT_INVALID
|
self.patch_int_ofport = constants.OFPORT_INVALID
|
||||||
self.patch_tun_ofport = constants.OFPORT_INVALID
|
self.patch_tun_ofport = constants.OFPORT_INVALID
|
||||||
@ -1460,7 +1465,8 @@ class OVSNeutronAgent(l2population_rpc.L2populationRpcCallBackTunnelMixin,
|
|||||||
tunnel_type,
|
tunnel_type,
|
||||||
self.vxlan_udp_port,
|
self.vxlan_udp_port,
|
||||||
self.dont_fragment,
|
self.dont_fragment,
|
||||||
self.tunnel_csum)
|
self.tunnel_csum,
|
||||||
|
self.tos)
|
||||||
if ofport == ovs_lib.INVALID_OFPORT:
|
if ofport == ovs_lib.INVALID_OFPORT:
|
||||||
LOG.error("Failed to set-up %(type)s tunnel port to %(ip)s",
|
LOG.error("Failed to set-up %(type)s tunnel port to %(ip)s",
|
||||||
{'type': tunnel_type, 'ip': remote_ip})
|
{'type': tunnel_type, 'ip': remote_ip})
|
||||||
|
@ -30,6 +30,7 @@ from neutron.agent.linux import polling
|
|||||||
from neutron.common import utils
|
from neutron.common import utils
|
||||||
from neutron.conf.agent import common as agent_config
|
from neutron.conf.agent import common as agent_config
|
||||||
from neutron.conf import common as common_config
|
from neutron.conf import common as common_config
|
||||||
|
from neutron.conf.plugins.ml2.drivers import agent
|
||||||
from neutron.conf.plugins.ml2.drivers import ovs_conf
|
from neutron.conf.plugins.ml2.drivers import ovs_conf
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants
|
from neutron.plugins.ml2.drivers.openvswitch.agent.common import constants
|
||||||
from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.ovs_ofctl \
|
from neutron.plugins.ml2.drivers.openvswitch.agent.openflow.ovs_ofctl \
|
||||||
@ -69,6 +70,7 @@ class OVSAgentTestFramework(base.BaseOVSLinuxTestCase):
|
|||||||
def _get_config_opts(self):
|
def _get_config_opts(self):
|
||||||
config = cfg.ConfigOpts()
|
config = cfg.ConfigOpts()
|
||||||
config.register_opts(common_config.core_opts)
|
config.register_opts(common_config.core_opts)
|
||||||
|
agent.register_agent_opts(config)
|
||||||
ovs_conf.register_ovs_agent_opts(config)
|
ovs_conf.register_ovs_agent_opts(config)
|
||||||
agent_config.register_interface_opts(config)
|
agent_config.register_interface_opts(config)
|
||||||
agent_config.register_interface_driver_opts_helper(config)
|
agent_config.register_interface_driver_opts_helper(config)
|
||||||
|
@ -223,6 +223,21 @@ class OVSBridgeTestCase(OVSBridgeTestBase):
|
|||||||
options = self.ovs.db_get_val('Interface', port_name, 'options')
|
options = self.ovs.db_get_val('Interface', port_name, 'options')
|
||||||
self.assertEqual("12345", options['dst_port'])
|
self.assertEqual("12345", options['dst_port'])
|
||||||
|
|
||||||
|
def test_add_tunnel_port_tos(self):
|
||||||
|
attrs = {
|
||||||
|
'remote_ip': self.get_test_net_address(1),
|
||||||
|
'local_ip': self.get_test_net_address(2),
|
||||||
|
'tos': 'inherit',
|
||||||
|
}
|
||||||
|
port_name = utils.get_rand_device_name(net_helpers.PORT_PREFIX)
|
||||||
|
self.br.add_tunnel_port(port_name, attrs['remote_ip'],
|
||||||
|
attrs['local_ip'], tos=attrs['tos'])
|
||||||
|
self.assertEqual('gre',
|
||||||
|
self.ovs.db_get_val('Interface', port_name, 'type'))
|
||||||
|
options = self.ovs.db_get_val('Interface', port_name, 'options')
|
||||||
|
for attr, val in attrs.items():
|
||||||
|
self.assertEqual(val, options[attr])
|
||||||
|
|
||||||
def test_add_patch_port(self):
|
def test_add_patch_port(self):
|
||||||
local = utils.get_rand_device_name(net_helpers.PORT_PREFIX)
|
local = utils.get_rand_device_name(net_helpers.PORT_PREFIX)
|
||||||
peer = 'remotepeer'
|
peer = 'remotepeer'
|
||||||
|
@ -583,6 +583,41 @@ class OVS_Lib_Test(base.BaseTestCase):
|
|||||||
|
|
||||||
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
||||||
|
|
||||||
|
def test_add_vxlan_tos_tunnel_port(self):
|
||||||
|
pname = "tap99"
|
||||||
|
local_ip = "1.1.1.1"
|
||||||
|
remote_ip = "9.9.9.9"
|
||||||
|
ofport = 6
|
||||||
|
vxlan_udp_port = "9999"
|
||||||
|
dont_fragment = True
|
||||||
|
tunnel_csum = False
|
||||||
|
tos = 8
|
||||||
|
command = ["--may-exist", "add-port", self.BR_NAME, pname]
|
||||||
|
command.extend(["--", "set", "Interface", pname])
|
||||||
|
command.extend(["type=" + constants.TYPE_VXLAN,
|
||||||
|
"options:dst_port=" + vxlan_udp_port,
|
||||||
|
"options:df_default=true",
|
||||||
|
"options:remote_ip=" + remote_ip,
|
||||||
|
"options:local_ip=" + local_ip,
|
||||||
|
"options:in_key=flow",
|
||||||
|
"options:out_key=flow",
|
||||||
|
"options:tos=" + str(tos)])
|
||||||
|
# Each element is a tuple of (expected mock call, return_value)
|
||||||
|
expected_calls_and_values = [
|
||||||
|
(self._vsctl_mock(*command), None),
|
||||||
|
(self._vsctl_mock("--columns=ofport", "list", "Interface", pname),
|
||||||
|
self._encode_ovs_json(['ofport'], [[ofport]])),
|
||||||
|
]
|
||||||
|
tools.setup_mock_calls(self.execute, expected_calls_and_values)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
self.br.add_tunnel_port(pname, remote_ip, local_ip,
|
||||||
|
constants.TYPE_VXLAN, vxlan_udp_port,
|
||||||
|
dont_fragment, tunnel_csum, tos),
|
||||||
|
ofport)
|
||||||
|
|
||||||
|
tools.verify_mock_calls(self.execute, expected_calls_and_values)
|
||||||
|
|
||||||
def _encode_ovs_json(self, headings, data):
|
def _encode_ovs_json(self, headings, data):
|
||||||
# See man ovs-vsctl(8) for the encoding details.
|
# See man ovs-vsctl(8) for the encoding details.
|
||||||
r = {"data": [],
|
r = {"data": [],
|
||||||
|
@ -392,7 +392,6 @@ class TestLinuxBridgeManager(base.BaseTestCase):
|
|||||||
srcport=(0, 0),
|
srcport=(0, 0),
|
||||||
dstport=None,
|
dstport=None,
|
||||||
ttl=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')
|
||||||
@ -403,7 +402,6 @@ class TestLinuxBridgeManager(base.BaseTestCase):
|
|||||||
srcport=(0, 0),
|
srcport=(0, 0),
|
||||||
dstport=None,
|
dstport=None,
|
||||||
ttl=None,
|
ttl=None,
|
||||||
tos=None,
|
|
||||||
dev=self.lbm.local_int,
|
dev=self.lbm.local_int,
|
||||||
proxy=expected_proxy)
|
proxy=expected_proxy)
|
||||||
|
|
||||||
@ -411,6 +409,27 @@ class TestLinuxBridgeManager(base.BaseTestCase):
|
|||||||
cfg.CONF.set_override('arp_responder', True, 'VXLAN')
|
cfg.CONF.set_override('arp_responder', True, 'VXLAN')
|
||||||
self.test_ensure_vxlan(expected_proxy=True)
|
self.test_ensure_vxlan(expected_proxy=True)
|
||||||
|
|
||||||
|
def test_ensure_vxlan_dscp_inherit_set(self):
|
||||||
|
cfg.CONF.set_override('dscp_inherit', 'True', 'AGENT')
|
||||||
|
seg_id = "12345678"
|
||||||
|
self.lbm.local_int = 'eth0'
|
||||||
|
self.lbm.vxlan_mode = lconst.VXLAN_MCAST
|
||||||
|
with mock.patch.object(ip_lib, 'device_exists', return_value=False):
|
||||||
|
vxlan_dev = FakeIpDevice()
|
||||||
|
with mock.patch.object(vxlan_dev, 'disable_ipv6') as dv6_fn,\
|
||||||
|
mock.patch.object(self.lbm.ip, 'add_vxlan',
|
||||||
|
return_value=vxlan_dev) as add_vxlan_fn:
|
||||||
|
self.assertEqual("vxlan-" + seg_id,
|
||||||
|
self.lbm.ensure_vxlan(seg_id))
|
||||||
|
add_vxlan_fn.assert_called_with("vxlan-" + seg_id, seg_id,
|
||||||
|
group="224.0.0.1",
|
||||||
|
srcport=(0, 0),
|
||||||
|
dstport=None,
|
||||||
|
ttl=None,
|
||||||
|
tos='inherit',
|
||||||
|
dev=self.lbm.local_int)
|
||||||
|
dv6_fn.assert_called_once_with()
|
||||||
|
|
||||||
def test__update_interface_ip_details(self):
|
def test__update_interface_ip_details(self):
|
||||||
gwdict = dict(gateway='1.1.1.1',
|
gwdict = dict(gateway='1.1.1.1',
|
||||||
metric=50)
|
metric=50)
|
||||||
|
@ -1694,7 +1694,7 @@ class TestOvsNeutronAgent(object):
|
|||||||
add_tunnel_port_fn.assert_called_once_with(
|
add_tunnel_port_fn.assert_called_once_with(
|
||||||
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
||||||
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
||||||
self.agent.tunnel_csum)
|
self.agent.tunnel_csum, self.agent.tos)
|
||||||
log_error_fn.assert_called_once_with(
|
log_error_fn.assert_called_once_with(
|
||||||
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
||||||
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
||||||
@ -1739,7 +1739,7 @@ class TestOvsNeutronAgent(object):
|
|||||||
add_tunnel_port_fn.assert_called_once_with(
|
add_tunnel_port_fn.assert_called_once_with(
|
||||||
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
||||||
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
||||||
self.agent.tunnel_csum)
|
self.agent.tunnel_csum, self.agent.tos)
|
||||||
log_error_fn.assert_called_once_with(
|
log_error_fn.assert_called_once_with(
|
||||||
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
||||||
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
||||||
@ -1760,7 +1760,27 @@ class TestOvsNeutronAgent(object):
|
|||||||
add_tunnel_port_fn.assert_called_once_with(
|
add_tunnel_port_fn.assert_called_once_with(
|
||||||
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
||||||
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
||||||
self.agent.tunnel_csum)
|
self.agent.tunnel_csum, self.agent.tos)
|
||||||
|
log_error_fn.assert_called_once_with(
|
||||||
|
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
||||||
|
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
||||||
|
self.assertEqual(0, ofport)
|
||||||
|
|
||||||
|
def test_setup_tunnel_port_error_negative_tos_inherit(self):
|
||||||
|
remote_ip = '1.2.3.4'
|
||||||
|
with mock.patch.object(
|
||||||
|
self.agent.tun_br,
|
||||||
|
'add_tunnel_port',
|
||||||
|
return_value=ovs_lib.INVALID_OFPORT) as add_tunnel_port_fn,\
|
||||||
|
mock.patch.object(self.mod_agent.LOG, 'error') as log_error_fn:
|
||||||
|
self.agent.tos = 'inherit'
|
||||||
|
self.agent.local_ip = '2.3.4.5'
|
||||||
|
ofport = self.agent._setup_tunnel_port(
|
||||||
|
self.agent.tun_br, 'gre-1', remote_ip, n_const.TYPE_GRE)
|
||||||
|
add_tunnel_port_fn.assert_called_once_with(
|
||||||
|
'gre-1', remote_ip, self.agent.local_ip, n_const.TYPE_GRE,
|
||||||
|
self.agent.vxlan_udp_port, self.agent.dont_fragment,
|
||||||
|
self.agent.tunnel_csum, self.agent.tos)
|
||||||
log_error_fn.assert_called_once_with(
|
log_error_fn.assert_called_once_with(
|
||||||
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
_("Failed to set-up %(type)s tunnel port to %(ip)s"),
|
||||||
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
{'type': n_const.TYPE_GRE, 'ip': remote_ip})
|
||||||
|
@ -526,7 +526,7 @@ class TunnelTest(object):
|
|||||||
self.mock_tun_bridge.add_tunnel_port.return_value = tunnel_port
|
self.mock_tun_bridge.add_tunnel_port.return_value = tunnel_port
|
||||||
self.mock_tun_bridge_expected += [
|
self.mock_tun_bridge_expected += [
|
||||||
mock.call.add_tunnel_port('gre-0a000a01', '10.0.10.1', '10.0.0.1',
|
mock.call.add_tunnel_port('gre-0a000a01', '10.0.10.1', '10.0.0.1',
|
||||||
'gre', 4789, True, False),
|
'gre', 4789, True, False, None),
|
||||||
mock.call.setup_tunnel_port('gre', tunnel_port),
|
mock.call.setup_tunnel_port('gre', tunnel_port),
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
features:
|
||||||
|
- The DSCP value for outer headers in openvswitch overlay tunnel ports can
|
||||||
|
now be set through a configuration option ``dscp`` for both OVS and
|
||||||
|
linuxbridge agents.
|
||||||
|
- DSCP can also be inherited from the inner header through a new
|
||||||
|
boolean configuration option ``dscp_inherit`` for both openvswitch and
|
||||||
|
linuxbridge. If this option is set to true, then the value of ``dscp``
|
||||||
|
will be ignored.
|
||||||
|
deprecations:
|
||||||
|
- the ``tos`` configuration option in vxlan group for linuxbridge is
|
||||||
|
deprecated and replaced with the more precise option ``dscp``. The
|
||||||
|
TOS value is made of DSCP and ECN bits. It is not possible to set the
|
||||||
|
ECN value through the TOS value, and ECN is always inherited from the
|
||||||
|
inner in case of tunneling.
|
Loading…
Reference in New Issue
Block a user