Merge "Set a default IP route metric in ip_lib.list_ip_routes"

This commit is contained in:
Zuul 2020-02-19 04:15:07 +00:00 committed by Gerrit Code Review
commit 241877c58b
4 changed files with 16 additions and 5 deletions

View File

@ -76,6 +76,13 @@ DEFAULT_GW_PATTERN = re.compile(r"via (\S+)")
METRIC_PATTERN = re.compile(r"metric (\S+)")
DEVICE_NAME_PATTERN = re.compile(r"(\d+?): (\S+?):.*")
# NOTE: no metric is interpreted by the kernel as having the highest priority
# (value 0). "ip route" uses the netlink API to communicate with the kernel. In
# IPv6, when the metric value is not set is translated as 1024 as default:
# https://access.redhat.com/solutions/3659171
IP_ROUTE_METRIC_DEFAULT = {constants.IP_VERSION_4: 0,
constants.IP_VERSION_6: 1024}
def remove_interface_suffix(interface):
"""Remove a possible "<if>@<endpoint>" suffix from an interface' name.
@ -1501,6 +1508,8 @@ def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
else:
cidr = constants.IP_ANY[ip_version]
table = int(get_attr(route, 'RTA_TABLE'))
metric = (get_attr(route, 'RTA_PRIORITY') or
IP_ROUTE_METRIC_DEFAULT[ip_version])
value = {
'table': IP_RULE_TABLES_NAMES.get(table, table),
'source_prefix': get_attr(route, 'RTA_PREFSRC'),
@ -1508,7 +1517,7 @@ def list_ip_routes(namespace, ip_version, scope=None, via=None, table=None,
'scope': IP_ADDRESS_SCOPE[int(route['scope'])],
'device': get_device(int(get_attr(route, 'RTA_OIF')), devices),
'via': get_attr(route, 'RTA_GATEWAY'),
'metric': get_attr(route, 'RTA_PRIORITY'),
'metric': metric,
}
ret.append(value)

View File

@ -397,7 +397,8 @@ class LinuxBridgeManager(amb.CommonAgentManagerBase):
if gateway:
# Ensure that the gateway can be updated by changing the metric
metric = 100
if 'metric' in gateway:
ip_version = utils.get_ip_version(gateway['cidr'])
if gateway['metric'] != ip_lib.IP_ROUTE_METRIC_DEFAULT[ip_version]:
metric = gateway['metric'] - 1
dst_device.route.add_gateway(gateway=gateway['via'],
metric=metric)

View File

@ -866,8 +866,8 @@ class IpRouteCommandTestCase(functional_base.BaseSudoTestCase):
scope = ip_lib.IP_ADDRESS_SCOPE[0]
elif not scope:
scope = 'global' if via else 'link'
if ip_version == constants.IP_VERSION_6 and not metric:
metric = 1024
if not metric:
metric = ip_lib.IP_ROUTE_METRIC_DEFAULT[ip_version]
table = table or iproute_linux.DEFAULT_TABLE
table = ip_lib.IP_RULE_TABLES_NAMES.get(table, table)
cmp = {'table': table,

View File

@ -471,7 +471,8 @@ class TestLinuxBridgeManager(base.BaseTestCase):
dv6_fn.assert_not_called()
def test__update_interface_ip_details(self):
gwdict = dict(via='1.1.1.1',
gwdict = dict(cidr='1.1.1.1/24',
via='1.1.1.1',
metric=50)
ipdict = dict(cidr='1.1.1.1/24',
broadcast='1.1.1.255',