net/frr: Multiple fixes/features (#2633)

This commit is contained in:
Gavin Chappell 2021-11-09 08:07:05 +00:00 committed by GitHub
parent 3b8d729760
commit 7bc794ff48
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 106 additions and 119 deletions

View file

@ -14,6 +14,10 @@ Plugin Changelog
1.23
* Add route-reflector-client to BGP neighbor config
* bugfix: BGP Prefix List "IP version" field appears to be ineffective (#2602)
* feature: IPv6 link-local neighbors require an interface to be specified (#2604)
* feature: multiprotocol BGP sessions are not supported (#2606)
* bugfix: Multiple BGP peers causes config generation error (#2623)
1.22

View file

@ -26,7 +26,14 @@
<id>neighbor.updatesource</id>
<label>Update-Source Interface</label>
<type>select_multiple</type>
<help>Physical name of the interface facing the peer</help>
<help><![CDATA[Physical name of the IPv4 interface facing the peer. Please refer to the <a href="http://docs.frrouting.org/en/stable-7.4/bgp.html#clicmd-[no]neighborPEERupdate-source%3CIFNAME|ADDRESS%3E">FRR documentation</a> for more information.]]></help>
</field>
<field>
<id>neighbor.linklocalinterface</id>
<label>IPv6 link-local interface</label>
<type>dropdown</type>
<advanced>true</advanced>
<help><![CDATA[Interface to use for IPv6 link-local neighbours. Please refer to the <a href="http://docs.frrouting.org/en/stable-7.4/bgp.html#clicmd-[no]neighborPEERinterfaceIFNAME">FRR documentation</a> for more information.]]></help>
</field>
<field>
<id>neighbor.nexthopself</id>
@ -38,6 +45,13 @@
<label>Multi-Hop</label>
<type>checkbox</type>
</field>
<field>
<id>neighbor.multiprotocol</id>
<label>Multi-Protocol</label>
<type>checkbox</type>
<advanced>true</advanced>
<help><![CDATA[Is this neighbour multiprotocol capable per <a href="https://datatracker.ietf.org/doc/html/rfc2283.html">RFC 2283</a>]]></help>
</field>
<field>
<id>neighbor.rrclient</id>
<label>Route Reflector Client</label>

View file

@ -20,7 +20,7 @@
<field>
<id>prefixlist.version</id>
<label>IP Version</label>
<type>select_multiple</type>
<type>dropdown</type>
<help>Set the IP version to use.</help>
</field>
<field>
@ -32,7 +32,7 @@
<field>
<id>prefixlist.action</id>
<label>Action</label>
<type>select_multiple</type>
<type>dropdown</type>
<help>Set permit for match or deny to negate the rule.</help>
</field>
<field>

View file

@ -66,6 +66,15 @@
<enable>/^(?!0).*$/</enable>
</filters>
</updatesource>
<linklocalinterface type="InterfaceField">
<default></default>
<Required>N</Required>
<multiple>N</multiple>
<AllowDynamic>Y</AllowDynamic>
<filters>
<enable>/^(?!0).*$/</enable>
</filters>
</linklocalinterface>
<nexthopself type="BooleanField">
<default>0</default>
<Required>N</Required>
@ -74,6 +83,10 @@
<default>0</default>
<Required>N</Required>
</multihop>
<multiprotocol type="BooleanField">
<default>0</default>
<Required>N</Required>
</multiprotocol>
<rrclient type="BooleanField">
<default>0</default>
<Required>N</Required>

View file

@ -1,5 +1,31 @@
{% if helpers.exists('OPNsense.quagga.bgp.enabled') and OPNsense.quagga.bgp.enabled == '1' %}
{% from 'OPNsense/Macros/interface.macro' import physical_interface %}
{% from 'OPNsense/Macros/interface.macro' import physical_interface %}
{% set addressFamilies = ['ipv4', 'ipv6' ] %}
{% set neighbors = {'ipv4': [], 'ipv6': []} %}
{% set networks = {'ipv4': [], 'ipv6': []} %}
{% 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' %}
{# // the .append() method in Jinja2 returns "None", so filter through default() to suppress #}
{{ neighbors['ipv4'].append(neighbor) | default("", True) }}
{{ neighbors['ipv6'].append(neighbor) | default("", True) }}
{% elif neighbor.enabled == '1' and ':' not in neighbor.address %}
{{ neighbors['ipv4'].append(neighbor) | default("", True) }}
{% elif neighbor.enabled == '1' and ':' in neighbor.address %}
{{ neighbors['ipv6'].append(neighbor) | default("", True) }}
{% endif %}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.quagga.bgp.networks') %}
{% for network in OPNsense.quagga.bgp.networks.split(',') %}
{% if ':' not in network %}
{{ networks['ipv4'].append(network) | default("", True) }}
{% elif ':' in network %}
{{ networks['ipv6'].append(network) | default("", True) }}
{% endif %}
{% endfor %}
{% endif %}
!
! Zebra configuration saved from vty
! 2017/03/03 20:21:04
@ -31,9 +57,12 @@ router bgp {{ OPNsense.quagga.bgp.asnumber }}
{% if 'bfd' in neighbor and neighbor.bfd == '1' %}
neighbor {{ neighbor.address }} bfd
{% endif %}
{% if 'updatesource' in neighbor and neighbor.updatesource != '' %}
{% if ':' not in neighbor.address and 'updatesource' in neighbor and neighbor.updatesource != '' %}
neighbor {{ neighbor.address }} update-source {{ physical_interface(neighbor.updatesource) }}
{% endif %}
{% if ':' in neighbor.address and 'linklocalinterface' in neighbor and neighbor.linklocalinterface != '' %}
neighbor {{ neighbor.address }} interface {{ physical_interface(neighbor.linklocalinterface) }}
{% endif %}
{% if 'multihop' in neighbor and neighbor.multihop == '1' %}
neighbor {{ neighbor.address }} ebgp-multihop
{% endif %}
@ -48,145 +77,72 @@ router bgp {{ OPNsense.quagga.bgp.asnumber }}
{% endif %}
{% endfor %}
{% endif %}
address-family ipv4 unicast
{% if helpers.exists('OPNsense.quagga.bgp.networks') %}
{% for network in OPNsense.quagga.bgp.networks.split(',') %}
{% if ':' not in network %}
network {{ network }}
{% endif %}
{% endfor %}
{% endif %}
{% for addressFamily in addressFamilies %}
address-family {{ addressFamily }} unicast
{% if helpers.exists('OPNsense.quagga.bgp.redistribute') and OPNsense.quagga.bgp.redistribute != '' %}
{% for bgp_redistribute in OPNsense.quagga.bgp.redistribute.split(',') %}
redistribute {{ bgp_redistribute }}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.quagga.bgp.neighbors.neighbor') and ':' not in OPNsense.quagga.bgp.neighbors.neighbor.address %}
{% for neighbor in helpers.toList('OPNsense.quagga.bgp.neighbors.neighbor') %}
{% if neighbor.enabled == '1' and ':' not in neighbor.address %}
{% if 'nexthopself' in neighbor and neighbor.nexthopself == '1' %}
neighbor {{ neighbor.address }} next-hop-self
{% endif %}
{% if 'rrclient' in neighbor and neighbor.rrclient == '1' %}
neighbor {{ neighbor.address }} route-reflector-client
{% endif %}
{% if 'defaultoriginate' in neighbor and neighbor.defaultoriginate == '1' %}
neighbor {{ neighbor.address }} default-originate
{% 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 %}
{% endif %}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.quagga.bgp.neighbors.neighbor') %}
{% for neighbor in helpers.toList('OPNsense.quagga.bgp.neighbors.neighbor') %}
{% if neighbor.enabled == '1' and ':' in neighbor.address %}
no neighbor {{ neighbor.address }} activate
{% endif %}
{% endfor %}
{% endif %}
exit-address-family
!
address-family ipv6 unicast
{% if helpers.exists('OPNsense.quagga.bgp.networks') and ':' in OPNsense.quagga.bgp.networks %}
{% for network in OPNsense.quagga.bgp.networks.split(',') %}
{% if ':' in network %}
{% for network in networks[addressFamily] %}
network {{ network }}
{% endif %}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.quagga.bgp.redistribute') and OPNsense.quagga.bgp.redistribute != '' %}
{% for bgp_redistribute in OPNsense.quagga.bgp.redistribute.split(',') %}
redistribute {{ bgp_redistribute }}
{% endfor %}
{% endif %}
{% if helpers.exists('OPNsense.quagga.bgp.neighbors.neighbor') %}
{% for neighbor in helpers.toList('OPNsense.quagga.bgp.neighbors.neighbor') %}
{% if neighbor.enabled == '1' and ':' in neighbor.address %}
{% endfor %}
{% for neighbor in neighbors[addressFamily] %}
neighbor {{ neighbor.address }} activate
{% if 'nexthopself' in neighbor and neighbor.nexthopself == '1' %}
{% if 'nexthopself' in neighbor and neighbor.nexthopself == '1' %}
neighbor {{ neighbor.address }} next-hop-self
{% endif %}
{% if 'rrclient' in neighbor and neighbor.rrclient == '1' %}
{% endif %}
{% if 'rrclient' in neighbor and neighbor.rrclient == '1' %}
neighbor {{ neighbor.address }} route-reflector-client
{% endif %}
{% if 'defaultoriginate' in neighbor and neighbor.defaultoriginate == '1' %}
{% endif %}
{% if 'defaultoriginate' in neighbor and neighbor.defaultoriginate == '1' %}
neighbor {{ neighbor.address }} default-originate
{% 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' %}
{% 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' %}
{% 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' %}
{% 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' %}
{% 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 %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
{% endif %}
{% endfor %}
exit-address-family
!
{% endfor %}
{% if helpers.exists('OPNsense.quagga.bgp.prefixlists.prefixlist') %}
{% for prefixlist in helpers.sortDictList(OPNsense.quagga.bgp.prefixlists.prefixlist, 'name', 'seqnumber' ) %}
{% if prefixlist.enabled == '1' and ':' not in prefixlist.network %}
{% if prefixlist.enabled == '1' and prefixlist.version == 'IPv4' %}
ip prefix-list {{ prefixlist.name }} seq {{ prefixlist.seqnumber }} {{ prefixlist.action }} {{ prefixlist.network }}
{% endif %}
!
{% if prefixlist.enabled == '1' and ':' in prefixlist.network %}
{% if prefixlist.enabled == '1' and prefixlist.version == 'IPv6' %}
ipv6 prefix-list {{ prefixlist.name }} seq {{ prefixlist.seqnumber }} {{ prefixlist.action }} {{ prefixlist.network }}
{% endif %}
{% endfor %}