Set a default IP route metric in ip_lib.list_ip_routes
By default, if no metric is defined, the kernel interprets the
highest value (0).
The current implementation, using pyroute2, is a translation from
the CLI command "ip route". This command uses the netlink API to
communicate with the kernel. In IPv6, when the metric value is not
set is translated as 1024 as default [1].
[1]https://access.redhat.com/solutions/3659171
Change-Id: I0c5f9e320bbbf314a2d6a22c515bf903de84cdaf
Related-Bug: #1855759
(cherry picked from commit 7593f95a74
)
This commit is contained in:
parent
df7d14990b
commit
f900561550
|
@ -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.
|
||||
|
@ -1504,6 +1511,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'),
|
||||
|
@ -1511,7 +1520,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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue