Support looking up named route table in routing rule

The user may need to define the named route table in the routing rule
besides the table id, add support for that.

The commit fixes
https://github.com/linux-system-roles/network/issues/506.

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
This commit is contained in:
Wen Liang 2022-09-22 13:38:44 -04:00 committed by Fernando Fernández Mancera
parent f5a01f94bf
commit cfbd14cd8a
4 changed files with 81 additions and 2 deletions

View file

@ -581,7 +581,10 @@ The IP configuration supports the following options:
- `suppress_prefixlength` -
Reject routing decisions that have a prefix length of the specified or less.
- `table` -
The route table to look up for the `to-table` action.
The route table to look up for the `to-table` action. `table` supports both the
numeric table and named table. In order to specify the named table, the users
have to ensure the named table is properly defined in `/etc/iproute2/rt_tables`
or `/etc/iproute2/rt_tables.d/*.conf`.
- `to` -
The destination address of the packet to match (e.g. `192.168.100.58/24`).
- `tos` -

View file

@ -2336,7 +2336,10 @@ class ArgValidator_ListConnections(ArgValidatorList):
VALIDATE_ONE_MODE_INITSCRIPTS = "initscripts"
def validate_route_tables(self, connection, idx):
for r in connection["ip"]["route"]:
rule_route_combined_list = (
connection["ip"]["route"] + connection["ip"]["routing_rule"]
)
for r in rule_route_combined_list:
if isinstance(r["table"], Util.STRING_TYPE):
mapping = IPRouteUtils.get_route_tables_mapping()
if r["table"] in mapping:

View file

@ -19,6 +19,14 @@
state: present
- include_tasks: tasks/assert_device_present.yml
- name: Create a dedicated test file in `/etc/iproute2/rt_tables.d/` and
add a new routing table
lineinfile:
path: /etc/iproute2/rt_tables.d/table.conf
line: "200 custom"
mode: "0644"
create: yes
- name: Configure connection profile and specify the numeric table in
static routes
import_role:
@ -91,6 +99,9 @@
dport: 128 - 256
invert: True
table: 30600
- priority: 200
from: 198.51.100.56/26
table: custom
# the routing rule selector sport and ipproto are not supported by iproute
# since v4.17.0, and the iproute installed in CentOS-7 and RHEL-7 is
# v4.11.0
@ -115,6 +126,13 @@
changed_when: false
when: ansible_distribution_major_version != "7"
- name: Get the routing rule for looking up the table 'custom'
command: ip rule list table custom
register: route_rule_table_custom
ignore_errors: yes
changed_when: false
when: ansible_distribution_major_version != "7"
- name: Get the IPv4 routing rule for the connection "{{ interface }}"
command: nmcli -f ipv4.routing-rules c show "{{ interface }}"
register: connection_route_rule
@ -171,6 +189,16 @@
specified rule"
when: ansible_distribution_major_version != "7"
- name: Assert that the routing rule with 'custom' table lookup matches the
specified rule
assert:
that:
- route_rule_table_custom.stdout is search("200:(\s+)from
198.51.100.56/26 lookup custom")
msg: "the routing rule with 'custom' table lookup does not match the
specified rule"
when: ansible_distribution_major_version != "7"
- name: Assert that the IPv4 routing rule in the connection
"{{ interface }}" matches the specified rule
assert:
@ -191,6 +219,8 @@
0.0.0.0/0 iif iiftest table 30400")
- connection_route_rule.stdout is search("priority 30402 from
0.0.0.0/0 oif oiftest table 30400")
- connection_route_rule.stdout is search("priority 200 from
198.51.100.56/26 table 200")
msg: "the IPv4 routing rule in the connection '{{ interface }}' does
not match the specified rule"
@ -206,6 +236,12 @@
::/0 dport 128-256 table 30600")
msg: "the IPv6 routing rule in the connection '{{ interface }}' does
not match the specified rule"
- name: Remove the dedicated test file in `/etc/iproute2/rt_tables.d/`
file:
state: absent
path: /etc/iproute2/rt_tables.d/table.conf
- import_playbook: down_profile+delete_interface.yml
vars:
profile: "{{ interface }}"

View file

@ -4395,6 +4395,7 @@ class TestValidatorRouteTable(Python26CompatTestCase):
"table": 30400,
},
],
"routing_rule": [],
},
}
]
@ -4650,6 +4651,25 @@ class TestValidatorRoutingRules(Python26CompatTestCase):
}
]
self.validator = network_lsr.argument_validator.ArgValidator_ListConnections()
self.old_getter = (
network_lsr.argument_validator.IPRouteUtils.get_route_tables_mapping
)
network_lsr.argument_validator.IPRouteUtils.get_route_tables_mapping = (
classmethod(
lambda cls: {
"custom": 200,
"eth": 30400,
}
)
)
# the connection index is 0 because there is only one connection profile
# defined here
self.connection_index = 0
def tearDown(self):
network_lsr.argument_validator.IPRouteUtils.get_route_tables_mapping = (
self.old_getter
)
def test_routing_rule_missing_address_family(self):
"""
@ -4831,6 +4851,23 @@ class TestValidatorRoutingRules(Python26CompatTestCase):
self.test_connections,
)
def test_table_found_when_lookup_named_table(self):
"""
Test that the `validate_route_tables()` will find the table id mapping from
`IPRouteUtils.get_route_tables_mapping()`.
"""
self.test_connections[0]["ip"]["routing_rule"][0]["table"] = "custom"
self.validator.validate_route_tables(
self.test_connections[0],
self.connection_index,
)
self.assertEqual(
self.test_connections[0]["ip"]["routing_rule"][0]["table"],
200,
)
class TestValidatorDictBond(Python26CompatTestCase):
def setUp(self):