Skip to main content

I am looking for for BGP protocol which will show below details:

 

device name

NeighborAddress

outbound Interface description

peerDeviceName

 peerVrf

peer outbound Interface description

sessionState: neighbor.sessionState

peerType (Internal/External)

 

The one I created, but its not loading:

import "@fwd/L3/Interface Utilities"; //getL3Interfaces(device: Device)



getPeerInfo(neighbor, sourceRouterId) =

  max(foreach device in network.devices

      where device.name == neighbor.peerDeviceName

      let l3IfaceList = getL3Interfaces(device)

      foreach networkInstance in device.networkInstances

      foreach protocol in networkInstance.protocols

      where isPresent(protocol.bgp)

      let bgp = protocol.bgp

      foreach neighbor in bgp.neighbors

      where neighbor.peerRouterId == sourceRouterId

      let outIface = max(foreach l3Iface in l3IfaceList

                         foreach address in l3Iface.ipv4.addresses

                         where neighbor.neighborAddress in

                               ipSubnet(address.ip, address.prefixLength)

                         select l3Iface)

      select outIface);



foreach device in network.devices

let l3IfaceList = getL3Interfaces(device)

  foreach networkInstance in device.networkInstances

  foreach protocol in networkInstance.protocols

  where isPresent(protocol.bgp)

  let bgp = protocol.bgp

  foreach neighbor in bgp.neighbors

  where neighbor.enabled //

where isPresent(neighbor.sessionState)//

  let peerInfo = getPeerInfo(neighbor, bgp.routerId)

  let outIface = max(foreach l3Iface in l3IfaceList

                     foreach address in l3Iface.ipv4.addresses

                     where neighbor.neighborAddress in

                           ipSubnet(address.ip, address.prefixLength)

                     select l3Iface)

                               

select {

    "device name": device.name,

    networkInstanceName: networkInstance.name,

    neighborNeighborAddress: neighbor.neighborAddress,

    "outbound Interface": outIface?.name,

    peerDeviceName: neighbor.peerDeviceName,

    peerVrf: neighbor.peerVrf,

    peerRouterId: neighbor.peerRouterId,

    "peer outbound Interface": peerInfo?.name,

    sessionState: neighbor.sessionState,

    enabled: neighbor.enabled,

    description: neighbor.description,

    peerAS: neighbor.peerAS,

    localAS: bgp.asNumber,

    peerType: neighbor.peerType

  }

 

@mayur.lad 

Just a quick glance, this looks like a good approach. I would recommend limiting the query to a single device and removing some of the filters.  See what data you are getting to see if the data you are hoping to get is actually there.

Another thing to do would be to make that user function “getPeerInfo” as a separate query.  The put in a specific neighbor and see what you can get.

I’m not seeing something that should obviously give you a problem.

We have submitted a feature request to get the output interface added to the data model so you wouldn’t have to go through all of this.  Unfortunately we don’t have an estimate for when that will become available.

I’ll try this against a network I have that is running BGP and see if I can find an issue.


@mayur.lad This query worked for me with no modification.  The only change I made was to limit the query to one device so I just saw the neighbors for that one single device.

I did remove that filter and just ran it on this network of over 8k devices.  It took about 2 and a half minutes, but I still received a result.

Now I believe that in the network I am looking at, the peering is with the directly connected interface IP.  It would be different if you were peering with the loopback address.  Your query is looking for neighbor addresses that match subnets on your local interfaces.  If you peer to a loopback, then you would never match.  In that case you may need to look for how you route to the peer ip address.

The backend already has this information, that is why we request that it get added to the data model instead of having to calculate it again.  That means that hopefully this is just a workaround until that data model item is added.


Hi Mayur 

The NQE you wrote is timing out.

Can you try the below NQE and see if it works - it looks up the peer outgoing interfaces in a different way: We already know the peer device, vrf and ip, so it is more efficient to match on just those things than to work through each BGP neighbor in your original script. There are also cases where your original query may have not found the peer outgoing interface but this one does.
 

import "@fwd/L3/Interface Utilities"; //getL3Interfaces(device: Device)

getPeerInfo(name, vrf, ip) =
max(foreach device in network.devices
where device.name == name
foreach instance in device.networkInstances
where vrf == instance.name
foreach interface in getL3Interfaces(device)
foreach ipAddr in interface.ipv4.addresses
where ipAddr.ip == ip
select interface.name);

foreach device in network.devices
let l3IfaceList = getL3Interfaces(device)
foreach networkInstance in device.networkInstances
foreach protocol in networkInstance.protocols
where isPresent(protocol.bgp)
let bgp = protocol.bgp
foreach neighbor in bgp.neighbors
where neighbor.enabled //
where isPresent(neighbor.sessionState) //
let peerDeviceName = neighbor.peerDeviceName
let peerVrf = neighbor.peerVrf
let peerIp = neighbor.neighborAddress
let peerInfo = getPeerInfo(peerDeviceName, peerVrf, peerIp)
let outIface = max(foreach l3Iface in l3IfaceList
foreach address in l3Iface.ipv4.addresses
where neighbor.neighborAddress in
ipSubnet(address.ip, address.prefixLength)
select l3Iface)
select {
"device name": device.name,
networkInstanceName: networkInstance.name,
neighborNeighborAddress: neighbor.neighborAddress,
"outbound Interface": outIface?.name,
peerDeviceName,
peerVrf: neighbor.peerVrf,
peerRouterId: neighbor.peerRouterId,
"peer outbound Interface": peerInfo,
sessionState: neighbor.sessionState,
enabled: neighbor.enabled,
description: neighbor.description,
peerAS: neighbor.peerAS,
localAS: bgp.asNumber,
peerType: neighbor.peerType
}

 


I also received a much quicker response if I added.

where neighbor.sessionState == BgpSessionState.ESTABLISHED

This makes sense, since if it is not Established, then the interface connecting to the unEstablished peer may be down.


Hi Mayur 

The NQE you wrote is timing out.

Can you try the below NQE and see if it works - it looks up the peer outgoing interfaces in a different way: We already know the peer device, vrf and ip, so it is more efficient to match on just those things than to work through each BGP neighbor in your original script. There are also cases where your original query may have not found the peer outgoing interface but this one does.
 

import "@fwd/L3/Interface Utilities"; //getL3Interfaces(device: Device)

getPeerInfo(name, vrf, ip) =
max(foreach device in network.devices
where device.name == name
foreach instance in device.networkInstances
where vrf == instance.name
foreach interface in getL3Interfaces(device)
foreach ipAddr in interface.ipv4.addresses
where ipAddr.ip == ip
select interface.name);

foreach device in network.devices
let l3IfaceList = getL3Interfaces(device)
foreach networkInstance in device.networkInstances
foreach protocol in networkInstance.protocols
where isPresent(protocol.bgp)
let bgp = protocol.bgp
foreach neighbor in bgp.neighbors
where neighbor.enabled //
where isPresent(neighbor.sessionState) //
let peerDeviceName = neighbor.peerDeviceName
let peerVrf = neighbor.peerVrf
let peerIp = neighbor.neighborAddress
let peerInfo = getPeerInfo(peerDeviceName, peerVrf, peerIp)
let outIface = max(foreach l3Iface in l3IfaceList
foreach address in l3Iface.ipv4.addresses
where neighbor.neighborAddress in
ipSubnet(address.ip, address.prefixLength)
select l3Iface)
select {
"device name": device.name,
networkInstanceName: networkInstance.name,
neighborNeighborAddress: neighbor.neighborAddress,
"outbound Interface": outIface?.name,
peerDeviceName,
peerVrf: neighbor.peerVrf,
peerRouterId: neighbor.peerRouterId,
"peer outbound Interface": peerInfo,
sessionState: neighbor.sessionState,
enabled: neighbor.enabled,
description: neighbor.description,
peerAS: neighbor.peerAS,
localAS: bgp.asNumber,
peerType: neighbor.peerType
}

 

I also received a much quicker response if I added.

where neighbor.sessionState == BgpSessionState.ESTABLISHED

This makes sense, since if it is not Established, then the interface connecting to the unEstablished peer may be down.

I tried this and it worked, Thank you very much !!!


Reply