Skip to main content

The MTU query that comes canned in Forward Networks was pretty cool. However, I just wanted the MTU info on links that contained an LLDP or CDP neighbor entry, b/c I just don’t care about the MTU of of access devices, just the infrastructure links.

I tried to also modify to not pull MTU on Mgmt Interfaces (ma1, MA1, mgmt0)  However, I’m still pulling some ‘ma1’ interfaces! Oh well .I just sort it out later, but if anyone sees the issue, chime in.

/**
* @intent Return the MTU of interfaces that contain a CDP or LLDP neighbor
* @description rcariddi 6/30/2023 Find All links of CDP/LLDP, make sure each side of the link matches. This allows us to ignore non infrastructure links
* If we want all values, remove the line: where isPresent(interface1.cdp) || isPresent(interface1.lldp)
**/

foreach device1 in network.devices
foreach interface1 in device1.interfaces
where isPresent(interface1.mtu)
where isPresent(interface1.cdp) || isPresent(interface1.lldp)
where toLowerCase(interface1.name) not in e"ma*", "mgmt0", "bond0"]

foreach link in interface1.links
where device1.name < link.deviceName || (device1.name == link.deviceName && interface1.name < link.ifaceName)
foreach device2 in network.devices
where device2.name == link.deviceName
foreach interface2 in device2.interfaces
where isPresent(interface2.mtu)
where isPresent(interface2.cdp) || isPresent(interface2.lldp)
where toLowerCase(interface2.name) not in e"ma*", "mgmt0", "bond0"]

where interface2.name == link.ifaceName
where isPresent(interface2.mtu)
select {
violation: interface1.mtu != interface2.mtu,
Device1: device1.name,
Interface1: interface1.name,
Mtu1: interface1.mtu,
Device2: device2.name,
Interface2: interface2.name,
Mtu2: interface2.mtu
}

Questions/Enhancements - rcariddi@gmail.com

I apologize that you did not get a reply in so long.

 

I think the reason you have “ma1” results for the interface2 is because your second set of interface filters includes this:

interface2.name !="ma"

If you add the 1 for “ma1” it should filter those out.  That is an easy “stare and compare” mistake.

 

There is a way to write those lines that would make them a bit easier to read.

 Let’s take the first one:

where interface1.name != "Ma1" || interface1.name != "ma1" || interface1.name != "mgmt0"

and let’s make this a bit easier to read.

where interface1.name not in e"Ma1", "ma1", "mgmt0"]

Here we are replacing the != with “not in”.  Then make a list.  The “in” is what is comparing the interface1.name to a list.

You can do the same with the second one:

where interface2.name != "Ma1" || interface2.name !="ma" ||interface2.name != "bond0" || interface2.name == link.ifaceName

And do the same change to make a list of names.

where interface2.name not in >"Ma1", "ma1", "bond0", link.ifaceName]

Notice that link.ifaceName is part of the list.  If you hover over the ifaceName part you will see that it is a String.  That way this variable is the same “type” as the other text in quotes.  If you hover over them it should also show you that the “type” is String.

Hope this helps.


Just to pile on some other changes.  You have upper case Ma1 and lower case ma1.

 

You could change the case of the interface name and then just have lower case names in the list.

For example:

change this:

where interface1.name not in n"Ma1", "ma1", "mgmt0"]

to: 

where toLowerCase(interface1.name) not in i"ma1", "mgmt0"]

Or, change this:

where interface2.name not in i"Ma1", "ma1", "bond0", link.ifaceName]

to:

where toLowerCase(interface2.name) not in i"ma1", "bond0", toLowerCase(link.ifaceName)]

 

Another thing is if you have similar names.  Or the case where you want to just use “ma” instead of “ma1”.  You would need to replace “ma1” with “ma*”.  The asterisk turns this into a Glob.  But you can’t just do a list of Globs in the same manor.  Each Glob needs to be evaluated one at a time.  Which means you need to use a loop to make that evaluation.

It will look something like this:

ifaceGlobList = n"ma*", "mgmt*"];

where length (foreach ifaceGlob in ifaceGlobList where matches(toLowerCase(interface1.name), ifaceGlob) select 1) == 0

This Multi-Glob matching is a handy tool.  You should try that line with both “== 0” and “> 0” to see how they react.  I’ll tell you that in this case if the interface does match the glob the value will be 1, which does not ==0, which means matches are excluded.  You will get the opposite behavior with “> 0”.

Since there were more interfaces in the second list, let’s do the same example:

change the interface2.name check to this for Glob checking

ifaceGlobList2 = r"ma*", "bond*", link.ifaceName];

where length (foreach ifaceGlob in ifaceGlobList2 where matches(toLowerCase(interface2.name), toLowerCase(ifaceGlob)) select 1) == 0

Tyson -

Great tips (fixes) much appreciated.  I’ve implemented and am getting much ‘tighter’ results.

Also good to know for some other scripts I have. I have to look into the GLOB, but the other recommendations were perfect. 

Thank you again!
Rich 


Reply