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 oslo_log import log as logging
|
||||
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_router_base
|
||||
@ -800,16 +801,17 @@ class DvrLocalRouter(dvr_router_base.DvrRouterBase):
|
||||
|
||||
def _update_fip_route_table_with_next_hop_routes(self, operation, route,
|
||||
fip_ns_name, tbl_index):
|
||||
cmd = ['ip', 'route', operation, 'to', route['destination'],
|
||||
'via', route['nexthop'], 'table', tbl_index]
|
||||
ip_wrapper = ip_lib.IPWrapper(namespace=fip_ns_name)
|
||||
if ip_wrapper.netns.exists(fip_ns_name):
|
||||
ip_wrapper.netns.execute(cmd, check_exit_code=False,
|
||||
privsep_exec=True)
|
||||
else:
|
||||
cmd = (ip_lib.add_ip_route if operation == 'replace' else
|
||||
ip_lib.delete_ip_route)
|
||||
try:
|
||||
cmd(fip_ns_name, route['destination'], via=route['nexthop'],
|
||||
table=tbl_index, proto='boot')
|
||||
except priv_ip_lib.NetworkNamespaceNotFound:
|
||||
LOG.debug("The FIP namespace %(ns)s does not exist for "
|
||||
"router %(id)s",
|
||||
{'ns': fip_ns_name, 'id': self.router_id})
|
||||
except (OSError, pyroute2_exc.NetlinkError):
|
||||
pass
|
||||
|
||||
def _check_if_route_applicable_to_fip_namespace(self, route,
|
||||
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,
|
||||
metric=None, scope=None, **kwargs):
|
||||
metric=None, scope=None, proto='static', **kwargs):
|
||||
"""Add an IP route"""
|
||||
if table:
|
||||
table = IP_RULE_TABLES.get(table, table)
|
||||
ip_version = common_utils.get_ip_version(cidr or via)
|
||||
privileged.add_ip_route(namespace, cidr, ip_version,
|
||||
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,
|
||||
@ -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):
|
||||
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 = IP_RULE_TABLES.get(table, table)
|
||||
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'))
|
||||
metric = (get_attr(route, 'RTA_PRIORITY') or
|
||||
IP_ROUTE_METRIC_DEFAULT[ip_version])
|
||||
proto = get_proto(route['proto'])
|
||||
value = {
|
||||
'table': IP_RULE_TABLES_NAMES.get(table, table),
|
||||
'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),
|
||||
'via': get_attr(route, 'RTA_GATEWAY'),
|
||||
'metric': metric,
|
||||
'proto': proto,
|
||||
}
|
||||
|
||||
ret.append(value)
|
||||
|
@ -720,11 +720,12 @@ def _make_pyroute2_route_args(namespace, ip_version, cidr, device, via, table,
|
||||
|
||||
@privileged.default.entrypoint
|
||||
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"""
|
||||
kwargs.update(_make_pyroute2_route_args(
|
||||
namespace, ip_version, cidr, device, via, table, metric, scope,
|
||||
'static'))
|
||||
proto))
|
||||
try:
|
||||
with get_iproute(namespace) as ip:
|
||||
ip.route('replace', **kwargs)
|
||||
|
@ -919,7 +919,8 @@ class IpRouteCommandTestCase(functional_base.BaseSudoTestCase):
|
||||
'scope': scope,
|
||||
'device': 'test_device',
|
||||
'via': via,
|
||||
'metric': metric}
|
||||
'metric': metric,
|
||||
'proto': 'static'}
|
||||
try:
|
||||
utils.wait_until_true(fn, timeout=5)
|
||||
except utils.WaitTimeout:
|
||||
|
@ -22,6 +22,7 @@ from neutron_lib import constants as n_cons
|
||||
from oslo_utils import uuidutils
|
||||
from pyroute2.ipdb import routes as ipdb_routes
|
||||
from pyroute2.iproute import linux as iproute_linux
|
||||
from pyroute2.netlink import rtnl
|
||||
import testtools
|
||||
|
||||
from neutron.agent.linux import ip_lib
|
||||
@ -476,7 +477,7 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
||||
self.device.link.set_up()
|
||||
|
||||
def _check_routes(self, cidrs, table=None, gateway=None, metric=None,
|
||||
scope=None):
|
||||
scope=None, proto='static'):
|
||||
table = table or iproute_linux.DEFAULT_TABLE
|
||||
if not scope:
|
||||
scope = 'universe' if gateway else 'link'
|
||||
@ -503,6 +504,7 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
||||
self.assertEqual(metric,
|
||||
ip_lib.get_attr(route, 'RTA_PRIORITY'))
|
||||
self.assertEqual(scope, route['scope'])
|
||||
self.assertEqual(rtnl.rt_proto[proto], route['proto'])
|
||||
break
|
||||
else:
|
||||
self.fail('CIDR %s not found in the list of routes' % cidr)
|
||||
@ -533,16 +535,17 @@ class RouteTestCase(functional_base.BaseSudoTestCase):
|
||||
% gateway)
|
||||
|
||||
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',
|
||||
'2001:db8::/64']
|
||||
for cidr in cidrs:
|
||||
ip_version = common_utils.get_ip_version(cidr)
|
||||
priv_ip_lib.add_ip_route(self.namespace, cidr, ip_version,
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
cidrs = ['192.168.0.0/24', '172.90.0.0/16', '10.0.0.0/8']
|
||||
int_cidr = '192.168.20.1/24'
|
||||
|
Loading…
Reference in New Issue
Block a user