Merge "Replace "ip route" command in "dvr_local_router""
This commit is contained in:
commit
b17a5dacd6
@ -19,6 +19,7 @@ import netaddr
|
|||||||
from neutron_lib import constants as lib_constants
|
from neutron_lib import constants as lib_constants
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
|
from pyroute2.netlink import exceptions as pyroute2_exc
|
||||||
|
|
||||||
from neutron.agent.l3 import dvr_fip_ns
|
from neutron.agent.l3 import dvr_fip_ns
|
||||||
from neutron.agent.l3 import dvr_router_base
|
from neutron.agent.l3 import dvr_router_base
|
||||||
@ -800,16 +801,17 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
|||||||
|
|
||||||
def _update_fip_route_table_with_next_hop_routes(self, operation, route,
|
def _update_fip_route_table_with_next_hop_routes(self, operation, route,
|
||||||
fip_ns_name, tbl_index):
|
fip_ns_name, tbl_index):
|
||||||
cmd = ['ip', 'route', operation, 'to', route['destination'],
|
cmd = (ip_lib.add_ip_route if operation == 'replace' else
|
||||||
'via', route['nexthop'], 'table', tbl_index]
|
ip_lib.delete_ip_route)
|
||||||
ip_wrapper = ip_lib.IPWrapper(namespace=fip_ns_name)
|
try:
|
||||||
if ip_wrapper.netns.exists(fip_ns_name):
|
cmd(fip_ns_name, route['destination'], via=route['nexthop'],
|
||||||
ip_wrapper.netns.execute(cmd, check_exit_code=False,
|
table=tbl_index, proto='boot')
|
||||||
privsep_exec=True)
|
except priv_ip_lib.NetworkNamespaceNotFound:
|
||||||
else:
|
|
||||||
LOG.debug("The FIP namespace %(ns)s does not exist for "
|
LOG.debug("The FIP namespace %(ns)s does not exist for "
|
||||||
"router %(id)s",
|
"router %(id)s",
|
||||||
{'ns': fip_ns_name, 'id': self.router_id})
|
{'ns': fip_ns_name, 'id': self.router_id})
|
||||||
|
except (OSError, pyroute2_exc.NetlinkError):
|
||||||
|
pass
|
||||||
|
|
||||||
def _check_if_route_applicable_to_fip_namespace(self, route,
|
def _check_if_route_applicable_to_fip_namespace(self, route,
|
||||||
agent_gateway_port):
|
agent_gateway_port):
|
||||||
|
@ -1500,14 +1500,14 @@ def ip_monitor(namespace, queue, event_stop, event_started):
|
|||||||
|
|
||||||
|
|
||||||
def add_ip_route(namespace, cidr, device=None, via=None, table=None,
|
def add_ip_route(namespace, cidr, device=None, via=None, table=None,
|
||||||
metric=None, scope=None, **kwargs):
|
metric=None, scope=None, proto='static', **kwargs):
|
||||||
"""Add an IP route"""
|
"""Add an IP route"""
|
||||||
if table:
|
if table:
|
||||||
table = IP_RULE_TABLES.get(table, table)
|
table = IP_RULE_TABLES.get(table, table)
|
||||||
ip_version = common_utils.get_ip_version(cidr or via)
|
ip_version = common_utils.get_ip_version(cidr or via)
|
||||||
privileged.add_ip_route(namespace, cidr, ip_version,
|
privileged.add_ip_route(namespace, cidr, ip_version,
|
||||||
device=device, via=via, table=table,
|
device=device, via=via, table=table,
|
||||||
metric=metric, scope=scope, **kwargs)
|
metric=metric, scope=scope, proto=proto, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
|
def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
|
||||||
@ -1517,6 +1517,12 @@ def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
|
|||||||
for device in (d for d in devices if d['index'] == index):
|
for device in (d for d in devices if d['index'] == index):
|
||||||
return get_attr(device, 'IFLA_IFNAME')
|
return get_attr(device, 'IFLA_IFNAME')
|
||||||
|
|
||||||
|
def get_proto(proto_number):
|
||||||
|
if proto_number in rtnl.rt_proto:
|
||||||
|
return rtnl.rt_proto[proto_number]
|
||||||
|
elif str(proto_number) in constants.IP_PROTOCOL_NUM_TO_NAME_MAP:
|
||||||
|
return constants.IP_PROTOCOL_NUM_TO_NAME_MAP[str(proto_number)]
|
||||||
|
|
||||||
table = table if table else 'main'
|
table = table if table else 'main'
|
||||||
table = IP_RULE_TABLES.get(table, table)
|
table = IP_RULE_TABLES.get(table, table)
|
||||||
routes = privileged.list_ip_routes(namespace, ip_version, device=device,
|
routes = privileged.list_ip_routes(namespace, ip_version, device=device,
|
||||||
@ -1532,6 +1538,7 @@ def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
|
|||||||
table = int(get_attr(route, 'RTA_TABLE'))
|
table = int(get_attr(route, 'RTA_TABLE'))
|
||||||
metric = (get_attr(route, 'RTA_PRIORITY') or
|
metric = (get_attr(route, 'RTA_PRIORITY') or
|
||||||
IP_ROUTE_METRIC_DEFAULT[ip_version])
|
IP_ROUTE_METRIC_DEFAULT[ip_version])
|
||||||
|
proto = get_proto(route['proto'])
|
||||||
value = {
|
value = {
|
||||||
'table': IP_RULE_TABLES_NAMES.get(table, table),
|
'table': IP_RULE_TABLES_NAMES.get(table, table),
|
||||||
'source_prefix': get_attr(route, 'RTA_PREFSRC'),
|
'source_prefix': get_attr(route, 'RTA_PREFSRC'),
|
||||||
@ -1540,6 +1547,7 @@ def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
|
|||||||
'device': get_device(int(get_attr(route, 'RTA_OIF')), devices),
|
'device': get_device(int(get_attr(route, 'RTA_OIF')), devices),
|
||||||
'via': get_attr(route, 'RTA_GATEWAY'),
|
'via': get_attr(route, 'RTA_GATEWAY'),
|
||||||
'metric': metric,
|
'metric': metric,
|
||||||
|
'proto': proto,
|
||||||
}
|
}
|
||||||
|
|
||||||
ret.append(value)
|
ret.append(value)
|
||||||
|
@ -720,11 +720,12 @@ def _make_pyroute2_route_args(namespace, ip_version, cidr, device, via, table,
|
|||||||
|
|
||||||
@privileged.default.entrypoint
|
@privileged.default.entrypoint
|
||||||
def add_ip_route(namespace, cidr, ip_version, device=None, via=None,
|
def add_ip_route(namespace, cidr, ip_version, device=None, via=None,
|
||||||
table=None, metric=None, scope=None, **kwargs):
|
table=None, metric=None, scope=None, proto='static',
|
||||||
|
**kwargs):
|
||||||
"""Add an IP route"""
|
"""Add an IP route"""
|
||||||
kwargs.update(_make_pyroute2_route_args(
|
kwargs.update(_make_pyroute2_route_args(
|
||||||
namespace, ip_version, cidr, device, via, table, metric, scope,
|
namespace, ip_version, cidr, device, via, table, metric, scope,
|
||||||
'static'))
|
proto))
|
||||||
try:
|
try:
|
||||||
with get_iproute(namespace) as ip:
|
with get_iproute(namespace) as ip:
|
||||||
ip.route('replace', **kwargs)
|
ip.route('replace', **kwargs)
|
||||||
|
@ -919,7 +919,8 @@ class IpRouteCommandTestCase(functional_base.BaseSudoTestCase):
|
|||||||
'scope': scope,
|
'scope': scope,
|
||||||
'device': 'test_device',
|
'device': 'test_device',
|
||||||
'via': via,
|
'via': via,
|
||||||
'metric': metric}
|
'metric': metric,
|
||||||
|
'proto': 'static'}
|
||||||
try:
|
try:
|
||||||
utils.wait_until_true(fn, timeout=5)
|
utils.wait_until_true(fn, timeout=5)
|
||||||
except utils.WaitTimeout:
|
except utils.WaitTimeout:
|
||||||
|
@ -22,6 +22,7 @@ from neutron_lib import constants as n_cons
|
|||||||
from oslo_utils import uuidutils
|
from oslo_utils import uuidutils
|
||||||
from pyroute2.ipdb import routes as ipdb_routes
|
from pyroute2.ipdb import routes as ipdb_routes
|
||||||
from pyroute2.iproute import linux as iproute_linux
|
from pyroute2.iproute import linux as iproute_linux
|
||||||
|
from pyroute2.netlink import rtnl
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from neutron.agent.linux import ip_lib
|
from neutron.agent.linux import ip_lib
|
||||||
@ -476,7 +477,7 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
|||||||
self.device.link.set_up()
|
self.device.link.set_up()
|
||||||
|
|
||||||
def _check_routes(self, cidrs, table=None, gateway=None, metric=None,
|
def _check_routes(self, cidrs, table=None, gateway=None, metric=None,
|
||||||
scope=None):
|
scope=None, proto='static'):
|
||||||
table = table or iproute_linux.DEFAULT_TABLE
|
table = table or iproute_linux.DEFAULT_TABLE
|
||||||
if not scope:
|
if not scope:
|
||||||
scope = 'universe' if gateway else 'link'
|
scope = 'universe' if gateway else 'link'
|
||||||
@ -503,6 +504,7 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
|||||||
self.assertEqual(metric,
|
self.assertEqual(metric,
|
||||||
ip_lib.get_attr(route, 'RTA_PRIORITY'))
|
ip_lib.get_attr(route, 'RTA_PRIORITY'))
|
||||||
self.assertEqual(scope, route['scope'])
|
self.assertEqual(scope, route['scope'])
|
||||||
|
self.assertEqual(rtnl.rt_proto[proto], route['proto'])
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
self.fail('CIDR %s not found in the list of routes' % cidr)
|
self.fail('CIDR %s not found in the list of routes' % cidr)
|
||||||
@ -533,16 +535,17 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
|||||||
% gateway)
|
% gateway)
|
||||||
|
|
||||||
def _add_route_device_and_check(self, table=None, metric=None,
|
def _add_route_device_and_check(self, table=None, metric=None,
|
||||||
scope='link'):
|
scope='link', proto='static'):
|
||||||
cidrs = ['192.168.0.0/24', '172.90.0.0/16', '10.0.0.0/8',
|
cidrs = ['192.168.0.0/24', '172.90.0.0/16', '10.0.0.0/8',
|
||||||
'2001:db8::/64']
|
'2001:db8::/64']
|
||||||
for cidr in cidrs:
|
for cidr in cidrs:
|
||||||
ip_version = common_utils.get_ip_version(cidr)
|
ip_version = common_utils.get_ip_version(cidr)
|
||||||
priv_ip_lib.add_ip_route(self.namespace, cidr, ip_version,
|
priv_ip_lib.add_ip_route(self.namespace, cidr, ip_version,
|
||||||
device=self.device_name, table=table,
|
device=self.device_name, table=table,
|
||||||
metric=metric, scope=scope)
|
metric=metric, scope=scope, proto=proto)
|
||||||
|
|
||||||
self._check_routes(cidrs, table=table, metric=metric, scope=scope)
|
self._check_routes(cidrs, table=table, metric=metric, scope=scope,
|
||||||
|
proto=proto)
|
||||||
|
|
||||||
def test_add_route_device(self):
|
def test_add_route_device(self):
|
||||||
self._add_route_device_and_check(table=None)
|
self._add_route_device_and_check(table=None)
|
||||||
@ -565,6 +568,18 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
|||||||
def test_add_route_device_scope_host(self):
|
def test_add_route_device_scope_host(self):
|
||||||
self._add_route_device_and_check(scope='host')
|
self._add_route_device_and_check(scope='host')
|
||||||
|
|
||||||
|
def test_add_route_device_proto_static(self):
|
||||||
|
self._add_route_device_and_check(proto='static') # default
|
||||||
|
|
||||||
|
def test_add_route_device_proto_redirect(self):
|
||||||
|
self._add_route_device_and_check(proto='redirect')
|
||||||
|
|
||||||
|
def test_add_route_device_proto_kernel(self):
|
||||||
|
self._add_route_device_and_check(proto='kernel')
|
||||||
|
|
||||||
|
def test_add_route_device_proto_boot(self):
|
||||||
|
self._add_route_device_and_check(proto='boot')
|
||||||
|
|
||||||
def test_add_route_via_ipv4(self):
|
def test_add_route_via_ipv4(self):
|
||||||
cidrs = ['192.168.0.0/24', '172.90.0.0/16', '10.0.0.0/8']
|
cidrs = ['192.168.0.0/24', '172.90.0.0/16', '10.0.0.0/8']
|
||||||
int_cidr = '192.168.20.1/24'
|
int_cidr = '192.168.20.1/24'
|
||||||
|
Loading…
Reference in New Issue
Block a user