nautobot / nautobot-app-bgp-models

Nautobot BGP models plugin
https://docs.nautobot.com/projects/bgp-models/en/latest/
Other
18 stars 8 forks source link

Peer Endpoint and Peer Group Contexts #26

Closed mzbroch closed 1 year ago

mzbroch commented 2 years ago

Current implementation of BGP Plugin models does not allow to link a Peer Endpoint to a specific address family. This results in some limitations, especially around peer customizations or overrides at the address-family level, including enable/disabling specific endpoints under specific Address Families.

In the refactor, I propose PeerEndpointContext and PeerGroupContext models removing this limitation.

Use cases solved:

Following, are the example device configurations and sample modeling:

jcy-bb-01#show run | s r b
router bgp 65251
 bgp router-id 10.0.10.3
 bgp log-neighbor-changes
 neighbor INTERNAL peer-group
 neighbor 1.1.1.1 remote-as 1
 neighbor 1.1.1.1 peer-group INTERNAL
 neighbor 1.2.3.4 remote-as 1234
 neighbor 10.10.0.5 remote-as 65251
 neighbor 10.10.0.13 remote-as 65251
 neighbor 10.10.0.18 remote-as 65252
 !
 address-family ipv4
  network 1.2.3.4 mask 255.255.255.252
  redistribute connected
  redistribute static
  neighbor INTERNAL route-map EXAMPLE-IN in
  neighbor INTERNAL route-map EXAMPLE-OUT out
  neighbor INTERNAL maximum-prefix 1000
  neighbor 1.1.1.1 activate
  neighbor 1.2.3.4 activate
  neighbor 1.2.3.4 send-community extended
  neighbor 1.2.3.4 route-map TEST-IN in
  neighbor 1.2.3.4 maximum-prefix 5000
  neighbor 10.10.0.5 activate
  neighbor 10.10.0.13 activate
  neighbor 10.10.0.18 activate
  maximum-paths 20
 exit-address-family
 !
 address-family ipv6
  neighbor INTERNAL route-map TEST in
  neighbor 1.1.1.1 activate
  neighbor 1.1.1.1 route-map TEST-OVERRIDE in
  neighbor 1.2.3.4 activate
  neighbor 1.2.3.4 send-community
  neighbor 1.2.3.4 capability orf prefix-list both
  neighbor 1.2.3.4 route-map TEST-IPV6-IN in
  neighbor 1.2.3.4 maximum-prefix 1000000
 exit-address-family
jcy-bb-01#

Modelled as following (partial, not all instances but to show general idea about Peer Group Contexts / Peer Endpoint Contexts):

>>> asn_1 = AutonomousSystem.objects.create(asn=1) 
>>> asn_1234 = AutonomousSystem.objects.create(asn=1234)
>>> asn_65251 = AutonomousSystem.objects.create(asn=65251)
>>> cisco_bgp_instance = BGPRoutingInstance.objects.create(device=Device.objects.first() )

>>> cisco_bgp_instance.router_id = IPAddress.objects.first()
>>> cisco_bgp_instance.autonomous_system = asn_65251

>>> pg_INTERNAL = PeerGroup.objects.create(routing_instance=cisco_bgp_instance, name="INTERNAL")

# Create Peer endpoint 1.1.1.1 and assign it to peer group INTERNAL:
>>> peer_endpoint_1_1_1_1 = PeerEndpoint.objects.create(routing_instance=cisco_bgp_instance, ip=IPAddress.objects.all(address="1.1.1.1/32").first(), peer_group=pg_INTERNAL)

# Create two other endpoints without Peer Group:
>>> peer_endpoint_1_2_3_4 = PeerEndpoint.objects.create(routing_instance=cisco_bgp_instance, ip=IPAddress.objects.all(address="1.2.3.4/32").first(), remote_autonomous_system=AutonomousSystem.objects.get(asn=1234))
>>> peer_endpoint_10_10_0_5 = PeerEndpoint.objects.create(routing_instance=cisco_bgp_instance, ip=IPAddress.objects.all(address="10.10.0.5/32").first(), remote_autonomous_system=AutonomousSystem.objects.get(asn=65251))

# Create IPV4 Address Family
>>> local_af_ipv4 = AddressFamily.objects.create(afi_safi=AFISAFIChoices.AFI_IPV4, routing_instance=cisco_bgp_instance)

# Configure Peer Group INTERNAL under Address Family IPv4:
>>> peer_group_context = PeerGroupContext.objects.create(peer_group=pg_INTERNAL, address_family=local_af_ipv4)
>>> peer_group_context.import_policy = "EXAMPLE-IN"
>>> peer_group_context.export_policy = "EXAMPLE-OUT"

# Configure Peer Endpoint 1.1.1.1 under Address Family IPv6:
>>> local_af_ipv6 = AddressFamily(afi_safi=AFISAFIChoices.AFI_IPV6_LU, routing_instance=cisco_bgp_instance)
>>> peer_endpoint_context = PeerEndpointContext.objects.create(peer_endpoint=peer_endpoint_1_1_1_1, address_family=local_af_ipv6)
>>> peer_endpoint_context.import_policy = "TEST-OVERRIDE"

Other valid configuration use cases : Arista LEAF

router general
   router-id ipv4 <IP router ID>

router bgp <ASN as dot>
   bgp asn notation asdot
   update wait-install
   no bgp default ipv4-unicast
   timers bgp 5 15
   distance bgp 20 200 200
   maximum-paths 4 ecmp 4
   neighbor default send-community
   neighbor EVPN-OVERLAY-LEAF peer group
   neighbor EVPN-OVERLAY-SPINE peer group
   neighbor EVPN-OVERLAY-SPINE remote-as <ASN of spines>
   neighbor EVPN-OVERLAY-SPINE update-source Loopback0
   neighbor EVPN-OVERLAY-SPINE bfd
   neighbor EVPN-OVERLAY-SPINE ebgp-multihop 3
   neighbor EVPN-OVERLAY-SPINE maximum-routes 0
   neighbor IPv4-UNDERLAY-MLAG-PEER peer group
   neighbor IPv4-UNDERLAY-MLAG-PEER remote-as <ASN of other leaf node>
   neighbor IPv4-UNDERLAY-MLAG-PEER next-hop-self
   neighbor IPv4-UNDERLAY-MLAG-PEER maximum-routes 256000 warning-only
   neighbor IPv4-UNDERLAY-SPINE peer group
   neighbor IPv4-UNDERLAY-SPINE remote-as <AS of spines>
   neighbor IPv4-UNDERLAY-SPINE maximum-routes 256000 warning-only
   neighbor <IP neighbor spine1 loopback> peer group EVPN-OVERLAY-SPINE
   neighbor <IP neighbor spine2 loopback> peer group EVPN-OVERLAY-SPINE
   neighbor <IP neighbor spine3 loopback> peer group EVPN-OVERLAY-SPINE
   neighbor <IP neighbor spine1 link1> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine1 link2> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine1 link3> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine2 link1> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine2 link2> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine2 link3> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine3 link1> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine3 link2> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor spine3 link3> peer group IPv4-UNDERLAY-SPINE
   neighbor <IP neighbor other leaf node> peer group IPv4-UNDERLAY-MLAG-PEER
   !
   address-family evpn
      neighbor EVPN-OVERLAY-SPINE activate
      host-flap detection window 20.0 threshold 4 expiry timeout 30.0 seconds
   !
   address-family ipv4
      neighbor IPv4-UNDERLAY-MLAG-PEER activate
      neighbor IPv4-UNDERLAY-SPINE activate
      network <local IP/network>
      network <local IP/network>
   !
   address-family ipv6
      no neighbor EVPN-OVERLAY-LEAF activate
   !
   address-family rt-membership
      neighbor EVPN-OVERLAY-SPINE activate
   !
   vrf <MGMT VRF>
      rd <(vrf specific) ASN as dot>:<number>
      route-target import evpn <number>:<number>
      route-target export evpn <number:<number>
      neighbor <IP neighbor spine1> remote-as <ASN spine>
      neighbor <IP neighbor spine1> update-source Ethernet33/7
      neighbor <IP neighbor spine2> remote-as <ASN spine>
      neighbor <IP neighbor spine2> update-source Ethernet34/7
      neighbor <IP neighbor spine3> remote-as <ASN spine>
      neighbor <IP neighbor spine3> update-source Ethernet35/7
      neighbor <IP neighbor other leaf node> remote-as <ASN of other leaf node>
      neighbor <IP neighbor other leaf node> next-hop-self
      !
      address-family ipv4
         neighbor <IP neighbor spine1> activate
         neighbor <IP neighbor spine2> activate
         neighbor <IP neighbor spine3> activate
         neighbor <IP neighbor other leaf node> activate
         network <local IP/network>

Arista SPINE

router general
   router-id ipv4 <IP router ID>

peer-filter LEAF-AS-RANGE
   10 match as-range <ASN range start>-<ASN range end> result accept

router bgp <ASN as dot>
   bgp asn notation asdot
   update wait-for-convergence
   update wait-install
   no bgp default ipv4-unicast
   timers bgp 5 15
   distance bgp 20 200 200
   maximum-paths 128
   bgp listen range <IP address range overlay peers> peer-group EVPN-OVERLAY-LEAF peer-filter LEAF-AS-RANGE
   bgp listen range <IP address range underlay peers> peer-group IPv4-UNDERLAY-LEAF peer-filter LEAF-AS-RANGE
   neighbor default send-community
   neighbor EVPN-OVERLAY-LEAF peer group
   neighbor EVPN-OVERLAY-LEAF update-source Loopback0
   neighbor EVPN-OVERLAY-LEAF bfd
   neighbor EVPN-OVERLAY-LEAF ebgp-multihop 3
   neighbor EVPN-OVERLAY-LEAF maximum-routes 0
   neighbor INBAND_PG peer group
   neighbor INBAND_PG local-as <ASN in vrf> no-prepend replace-as
   neighbor IPv4-UNDERLAY-LEAF peer group
   neighbor IPv4-UNDERLAY-LEAF maximum-routes 12000 warning-only
   !
   address-family evpn
      bgp next-hop-unchanged
      neighbor EVPN-OVERLAY-LEAF activate
   !
   address-family ipv4
      neighbor IPv4-UNDERLAY-LEAF activate
      network <local IP/network>
   !
   address-family ipv6
      no neighbor EVPN-OVERLAY-LEAF activate
   !
   address-family rt-membership
      neighbor EVPN-OVERLAY-LEAF activate
   !
   vrf <MGMT VRF>
   rd <(vrf specific) ASN as dot>:<number>
   neighbor <IP neighbor A> peer group INBAND_PG
   neighbor <IP neighbor A> remote-as <remote ASN as dot>
   neighbor <IP neighbor A> update-source Ethernet1/7
   neighbor <IP neighbor B> peer group INBAND_PG
   neighbor <IP neighbor B> remote-as <remote ASN as dot>
   neighbor <IP neighbor B> update-source Ethernet17/7
   neighbor <IP neighbor C> peer group INBAND_PG
   neighbor <IP neighbor C> remote-as <remote ASN as dot>
   neighbor <IP neighbor C> update-source Ethernet2/7
   neighbor <IP neighbor D> peer group INBAND_PG
   neighbor <IP neighbor D> remote-as <remote ASN as dot>
   neighbor <IP neighbor D> update-source Ethernet18/7
   !
   address-family ipv4
      neighbor <IP neighbor A> activate
      neighbor <IP neighbor B> activate
      neighbor <IP neighbor C> activate
      neighbor <IP neighbor D> activate
      network <local inband management IP/network>
mzbroch commented 2 years ago

Proposal for PeerEndpointContext model implemented in the PR https://github.com/nautobot/nautobot-plugin-bgp-models/pull/33

glennmatthews commented 1 year ago

Similar (IOS XR):

router bgp {{ host.asn }} vrf {{ vrf }}
 neighbor-group {{ group }}
  address-family ipv4 unicast
    route-policy {{ import_policy }} in
    multipath
glennmatthews commented 1 year ago

some earlier prototype code: https://github.com/nautobot/nautobot-plugin-bgp-models/blob/8ea4d5f2a62e800fe1007cf0ba59f84a00cc82a1/nautobot_bgp_models/models.py#L716

glennmatthews commented 1 year ago

More generally openconfig-bgp supports the following config levels:

      BGP
        |
        +-> [ global BGP configuration ]
          +-> AFI / SAFI global
        +-> peer group
          +-> [ peer group config ]
          +-> AFI / SAFI [ per-AFI overrides ]
        +-> neighbor
          +-> [ neighbor config ]
          +-> [ optional pointer to peer-group ]
          +-> AFI / SAFI [ per-AFI overrides ]

where the BGP container itself lives under a network-instance that might be a VRF, e.g.:

  <config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
    <network-instances xmlns="http://openconfig.net/yang/network-instance">
      <network-instance>
        <name>vrf1</name>
        <protocols>
          <protocol>
            <name>bgp</name>
            <identifier>BGP</identifier>
             <bgp xmlns="http://openconfig.net/yang/bgp">
              <global>
                <config xmlns="">
                  <as>100</as>
                  <router-id>2.2.2.2</router-id>
                </config>
              </global>
            </bgp>
           </protocol>
        </protocols>
      </network-instance>
    </network-instances>
  </config>