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
This commit is contained in:
parent
6a8277d70e
commit
7593f95a74
|
@ -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)
|
||||
|
|
|
@ -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