From 0f33e2868ca83151ad5e6423182d49d71ac7e308 Mon Sep 17 00:00:00 2001 From: Monviech Date: Tue, 18 Aug 2026 11:13:10 +0200 Subject: [PATCH] net/frr: move peer group policy into address families Peer groups gained an explicit address family selector, but only the activation command was rendered inside the selected address-family block. Policy-related settings such as prefix-lists, route-maps, next-hop-self and default-originate were still emitted in the global peer group section. This caused IPv6-only peer groups to be activated under IPv6 while their policy configuration was generated outside of the IPv6 address-family context, where it would not apply as expected. Move these AF-scoped peer group settings into the address-family loop and keep only session-level settings in the global peer group block. Add small helpers for prefix-list and route-map attachment rendering so the same logic can be shared between normal neighbors and peer groups. --- .../OPNsense/Quagga/Config/bgpd.conf | 124 ++++++++---------- 1 file changed, 54 insertions(+), 70 deletions(-) diff --git a/net/frr/src/opnsense/service/templates/OPNsense/Quagga/Config/bgpd.conf b/net/frr/src/opnsense/service/templates/OPNsense/Quagga/Config/bgpd.conf index 55e2390373..a950ea3ce8 100644 --- a/net/frr/src/opnsense/service/templates/OPNsense/Quagga/Config/bgpd.conf +++ b/net/frr/src/opnsense/service/templates/OPNsense/Quagga/Config/bgpd.conf @@ -5,6 +5,57 @@ {% set neighbors = {'ipv4': [], 'ipv6': []} %} {% set networks = {'ipv4': [], 'ipv6': []} %} +{# Macro helpers #} +{% macro prefixlist_helper(target, item) %} +{% if item.linkedPrefixlistIn|default("") != "" %} +{% for prefixlist in item.linkedPrefixlistIn.split(",") %} +{% set prefixlist_data = helpers.getUUID(prefixlist) %} +{% if prefixlist_data != {} and prefixlist_data.enabled == '1' %} + neighbor {{ target }} prefix-list {{ prefixlist_data.name }} in +{% endif %} +{% endfor %} +{% endif %} +{% if item.linkedPrefixlistOut|default("") != "" %} +{% for prefixlist in item.linkedPrefixlistOut.split(",") %} +{% set prefixlist_data = helpers.getUUID(prefixlist) %} +{% if prefixlist_data != {} and prefixlist_data.enabled == '1' %} + neighbor {{ target }} prefix-list {{ prefixlist_data.name }} out +{% endif %} +{% endfor %} +{% endif %} +{% endmacro %} + +{% macro routemap_helper(target, item) %} +{% if item.linkedRoutemapIn|default("") != "" %} +{% for routemap in item.linkedRoutemapIn.split(",") %} +{% set routemap_data = helpers.getUUID(routemap) %} +{% if routemap_data != {} and routemap_data.enabled == '1' %} + neighbor {{ target }} route-map {{ routemap_data.name }} in +{% endif %} +{% endfor %} +{% endif %} +{% if item.linkedRoutemapOut|default("") != "" %} +{% for routemap in item.linkedRoutemapOut.split(",") %} +{% set routemap_data = helpers.getUUID(routemap) %} +{% if routemap_data != {} and routemap_data.enabled == '1' %} + neighbor {{ target }} route-map {{ routemap_data.name }} out +{% endif %} +{% endfor %} +{% endif %} +{% endmacro %} + +{% macro peergroup_helper(peergroup) %} +{% if peergroup.nexthopself|default('0') == '1' %} + neighbor {{ peergroup.name }} next-hop-self +{% endif %} +{% if peergroup.defaultoriginate|default('0') == '1' %} + neighbor {{ peergroup.name }} default-originate +{% endif %} +{{ prefixlist_helper(peergroup.name, peergroup) }} +{{ routemap_helper(peergroup.name, peergroup) }} +{% endmacro %} + +{# Render template #} {% if helpers.exists('OPNsense.quagga.bgp.neighbors.neighbor') %} {% for neighbor in helpers.toList('OPNsense.quagga.bgp.neighbors.neighbor') %} {% if neighbor.enabled == '1' and neighbor.multiprotocol == '1' %} @@ -67,44 +118,6 @@ router bgp {{ OPNsense.quagga.bgp.asnumber }} {% if peergroup.updatesource %} neighbor {{ peergroup.name }} update-source {{ physical_interface(peergroup.updatesource) }} {% endif %} -{% if peergroup.nexthopself|default('0') == '1' %} - neighbor {{ peergroup.name }} next-hop-self -{% endif %} -{% if peergroup.defaultoriginate|default('0') == '1' %} - neighbor {{ peergroup.name }} default-originate -{% endif %} -{% if peergroup.linkedPrefixlistIn|default("") != "" %} -{% for prefixlist in peergroup.linkedPrefixlistIn.split(",") %} -{% set prefixlist2_data = helpers.getUUID(prefixlist) %} -{% if prefixlist2_data != {} and prefixlist2_data.enabled == '1' %} - neighbor {{ peergroup.name }} prefix-list {{ prefixlist2_data.name }} in -{% endif %} -{% endfor %} -{% endif %} -{% if peergroup.linkedPrefixlistOut|default("") != "" %} -{% for prefixlist in peergroup.linkedPrefixlistOut.split(",") %} -{% set prefixlist_data = helpers.getUUID(prefixlist) %} -{% if prefixlist_data != {} and prefixlist_data.enabled == '1' %} - neighbor {{ peergroup.name }} prefix-list {{ prefixlist_data.name }} out -{% endif %} -{% endfor %} -{% endif %} -{% if peergroup.linkedRoutemapIn|default("") != "" %} -{% for aspath in peergroup.linkedRoutemapIn.split(",") %} -{% set routemap2_data = helpers.getUUID(aspath) %} -{% if routemap2_data != {} and routemap2_data.enabled == '1' %} - neighbor {{ peergroup.name }} route-map {{ routemap2_data.name }} in -{% endif %} -{% endfor %} -{% endif %} -{% if peergroup.linkedRoutemapOut|default("") != "" %} -{% for aspath in peergroup.linkedRoutemapOut.split(",") %} -{% set routemap_data = helpers.getUUID(aspath) %} -{% if routemap_data != {} and routemap_data.enabled == '1' %} - neighbor {{ peergroup.name }} route-map {{ routemap_data.name }} out -{% endif %} -{% endfor %} -{% endif %} {% if peergroup.listenranges %} {% for prefix in peergroup.listenranges.split(',') %} bgp listen range {{ prefix }} peer-group {{ peergroup.name }} @@ -190,6 +203,7 @@ router bgp {{ OPNsense.quagga.bgp.asnumber }} {% for peergroup in helpers.toList('OPNsense.quagga.bgp.peergroups.peergroup') %} {% if peergroup.enabled == '1' and (addressFamily in peergroup.family.split(',')) %} neighbor {{ peergroup.name }} activate +{{ peergroup_helper(peergroup) }} {% endif %} {% endfor %} {% for neighbor in neighbors[addressFamily] %} @@ -216,38 +230,8 @@ router bgp {{ OPNsense.quagga.bgp.asnumber }} {% if 'allowas_in' in neighbor and neighbor.allowas_in %} neighbor {{ neighbor.address }} allowas-in {{ neighbor.allowas_in }} {% endif %} -{% if neighbor.linkedPrefixlistIn|default("") != "" %} -{% for prefixlist in neighbor.linkedPrefixlistIn.split(",") %} -{% set prefixlist2_data = helpers.getUUID(prefixlist) %} -{% if prefixlist2_data != {} and prefixlist2_data.enabled == '1' %} - neighbor {{ neighbor.address }} prefix-list {{ prefixlist2_data.name }} in -{% endif %} -{% endfor %} -{% endif %} -{% if neighbor.linkedPrefixlistOut|default("") != "" %} -{% for prefixlist in neighbor.linkedPrefixlistOut.split(",") %} -{% set prefixlist_data = helpers.getUUID(prefixlist) %} -{% if prefixlist_data != {} and prefixlist_data.enabled == '1' %} - neighbor {{ neighbor.address }} prefix-list {{ prefixlist_data.name }} out -{% endif %} -{% endfor %} -{% endif %} -{% if neighbor.linkedRoutemapIn|default("") != "" %} -{% for aspath in neighbor.linkedRoutemapIn.split(",") %} -{% set routemap2_data = helpers.getUUID(aspath) %} -{% if routemap2_data != {} and routemap2_data.enabled == '1' %} - neighbor {{ neighbor.address }} route-map {{ routemap2_data.name }} in -{% endif %} -{% endfor %} -{% endif %} -{% if neighbor.linkedRoutemapOut|default("") != "" %} -{% for aspath in neighbor.linkedRoutemapOut.split(",") %} -{% set routemap_data = helpers.getUUID(aspath) %} -{% if routemap_data != {} and routemap_data.enabled == '1' %} - neighbor {{ neighbor.address }} route-map {{ routemap_data.name }} out -{% endif %} -{% endfor %} -{% endif %} +{{ prefixlist_helper(neighbor.address, neighbor) }} +{{ routemap_helper(neighbor.address, neighbor) }} {% endfor %} exit-address-family {% endfor %}