Skip to content

Commit

Permalink
Policy-based routing for NetworkManager
Browse files Browse the repository at this point in the history
Adding the option to send rules as a dictionary, we seem to need the
table_id when using nmconnections. As a dict, it's atleast feasible
to try looking up an id from a name in the templates.

We're not attempting to find the table name from a string in this
iteration. So if using nmconnections the table name needs to be
swapped for id.

It looks like the older network-scripts rules on EL-systems start
priority at 32765 and decrement as more are added, so we're mimicking
that behavior. It is also possible to override with a priority added
to the dict rule.

Also making old rule_RedHat.j2 template compatible with dicts.

Basing this on previous templates and documentation [1]
[1] https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/9/html/configuring_and_managing_networking/configuring-policy-based-routing-to-define-alternative-routes_configuring-and-managing-networking
  • Loading branch information
eb4x committed Jan 18, 2023
1 parent 0bfaf3b commit bc11343
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 3 deletions.
8 changes: 8 additions & 0 deletions handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,14 @@
- Check active bond interface state
- Check active bridge interface state

# The order handlers execute are based on the order they're arranged here.
# We want to do a controlled bounce of interfaces before we do any restart.
- name: Restart NetworkManager
become: true
service:
name: NetworkManager
state: restarted

- name: Bounce network devices
become: true
command: >
Expand Down
12 changes: 12 additions & 0 deletions tasks/redhat.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
tags: package
when: not interfaces_use_networkmanager

- name: RedHat | install NM-dispatcher-routing-rules
become: true
package:
name: NetworkManager-dispatcher-routing-rules
state: '{{ interfaces_pkg_state }}'
tags: package
when:
- interfaces_use_networkmanager
- not interfaces_use_nmconnection
- interfaces_route_tables | length > 0
notify: Restart NetworkManager

# CentOS 8 cloud images ship with ifcfg files for ens3 and eth0. ifcfg-ens3
# seems to be a relic from the image build process, and causes the network
# service to fail. ifcfg-eth0 is useful for most virtual machines, but if a
Expand Down
21 changes: 20 additions & 1 deletion templates/bond_nmconnection.j2
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,33 @@ method=disabled
{% set _ = route_options.append(option) %}
{% endif %}
{% endfor %}
{# TODO: dev #}
{% if 'gateway' in route %}
route{{ loop.index }}={{ (route.network ~'/'~ route.netmask) | ipaddr('network/prefix') }},{{ route.gateway }}
{% endif %}
{# TODO: dev, table #}
{% if 'table' in route %}
{# networkmanager wants a table id, so we need to find it in interfaces_route_tables #}
{% set table_id = (interfaces_route_tables | selectattr('name', 'equalto', route.table) | first).id %}
{% set _ = route_options.append('table=' ~ table_id) %}
{% endif %}
{% if route_options | length %}
route{{ loop.index }}_options={{ route_options | join(',') }}
{% endif %}
{% endfor %}
{% for rule in item.rules | default([]) %}
{% if rule is mapping %}
{# networkmanager wants a table id, so we need to find it in interfaces_route_tables #}
{% set table_id = (interfaces_route_tables | selectattr('name', 'equalto', rule.table) | first).id %}
{% if rule.to is defined %}
routing-rule{{ loop.index }}=priority {{ rule.priority | default(32765 - loop.index0) }} to {{ rule.to }} table {{ table_id }}
{% endif %}
{% if rule.from is defined %}
routing-rule{{ loop.index }}=priority {{ rule.priority | default(32765 - loop.index0) }} from {{ rule.from }} table {{ table_id }}
{% endif %}
{% else %}
routing-rule{{ loop.index }}=priority {{ 32765 - loop.index0 }} {{ rule }}
{% endif %}
{% endfor %}
{% if item.dnsnameservers is defined %}
dns={{ item.dnsnameservers | join(',') }}
{% endif %}
Expand Down
21 changes: 20 additions & 1 deletion templates/bridge_nmconnection.j2
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,33 @@ method=disabled
{% set _ = route_options.append(option) %}
{% endif %}
{% endfor %}
{# TODO: dev #}
{% if 'gateway' in route %}
route{{ loop.index }}={{ (route.network ~'/'~ route.netmask) | ipaddr('network/prefix') }},{{ route.gateway }}
{% endif %}
{# TODO: dev, table #}
{% if 'table' in route %}
{# networkmanager wants a table id, so we need to find it in interfaces_route_tables #}
{% set table_id = (interfaces_route_tables | selectattr('name', 'equalto', route.table) | first).id %}
{% set _ = route_options.append('table=' ~ table_id) %}
{% endif %}
{% if route_options | length %}
route{{ loop.index }}_options={{ route_options | join(',') }}
{% endif %}
{% endfor %}
{% for rule in item.rules | default([]) %}
{% if rule is mapping %}
{# networkmanager wants a table id, so we need to find it in interfaces_route_tables #}
{% set table_id = (interfaces_route_tables | selectattr('name', 'equalto', rule.table) | first).id %}
{% if rule.to is defined %}
routing-rule{{ loop.index }}=priority {{ rule.priority | default(32765 - loop.index0) }} to {{ rule.to }} table {{ table_id }}
{% endif %}
{% if rule.from is defined %}
routing-rule{{ loop.index }}=priority {{ rule.priority | default(32765 - loop.index0) }} from {{ rule.from }} table {{ table_id }}
{% endif %}
{% else %}
routing-rule{{ loop.index }}=priority {{ 32765 - loop.index0 }} {{ rule }}
{% endif %}
{% endfor %}
{% if item.dnsnameservers is defined %}
dns={{ item.dnsnameservers | join(',') }}
{% endif %}
Expand Down
21 changes: 20 additions & 1 deletion templates/ethernet_nmconnection.j2
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,33 @@ method=disabled
{% set _ = route_options.append(option) %}
{% endif %}
{% endfor %}
{# TODO: dev #}
{% if 'gateway' in route %}
route{{ loop.index }}={{ (route.network ~'/'~ route.netmask) | ipaddr('network/prefix') }},{{ route.gateway }}
{% endif %}
{# TODO: dev, table #}
{% if 'table' in route %}
{# networkmanager wants a table id, so we need to find it in interfaces_route_tables #}
{% set table_id = (interfaces_route_tables | selectattr('name', 'equalto', route.table) | first).id %}
{% set _ = route_options.append('table=' ~ table_id) %}
{% endif %}
{% if route_options | length %}
route{{ loop.index }}_options={{ route_options | join(',') }}
{% endif %}
{% endfor %}
{% for rule in item.rules | default([]) %}
{% if rule is mapping %}
{# networkmanager wants a table id, so we need to find it in interfaces_route_tables #}
{% set table_id = (interfaces_route_tables | selectattr('name', 'equalto', rule.table) | first).id %}
{% if rule.to is defined %}
routing-rule{{ loop.index }}=priority {{ rule.priority | default(32765 - loop.index0) }} to {{ rule.to }} table {{ table_id }}
{% endif %}
{% if rule.from is defined %}
routing-rule{{ loop.index }}=priority {{ rule.priority | default(32765 - loop.index0) }} from {{ rule.from }} table {{ table_id }}
{% endif %}
{% else %}
routing-rule{{ loop.index }}=priority {{ 32765 - loop.index0 }} {{ rule }}
{% endif %}
{% endfor %}
{% if item.dnsnameservers is defined %}
dns={{ item.dnsnameservers | join(',') }}
{% endif %}
Expand Down
9 changes: 9 additions & 0 deletions templates/rule_RedHat.j2
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# {{ ansible_managed }}

{% for rule in item.rules %}
{% if rule is mapping %}
{% if rule.to is defined %}
to {{ rule.to }} table {{ rule.table }}
{% endif %}
{% if rule.from is defined %}
from {{ rule.from }} table {{ rule.table }}
{% endif %}
{% else %}
{{ rule }}
{% endif %}
{% endfor %}

0 comments on commit bc11343

Please sign in to comment.