cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
1565
Views
0
Helpful
6
Replies

EEM: Get Interface Mode?

yaplej
Level 1
Level 1

Hello there,

Is there an easier method to determine what mode an interface is in (access|trunk) without using the cli from within an EEM applet?

This works but it does not seem to be 100% reliable.  Sometimes the rest of my applet run on a trunk interface for no apparent reason.

 event mat mac-address "^.*$"
action 1.00 if $_mat_notification eq "add"

!!!
!! Excluding trunk interfaces.
!!!
action 1.01 cli command "enable"
action 1.02 cli command "show run interface $_mat_intf_name | i switchport mode"
action 1.03 string match "*trunk*" "$_cli_result"
 action 2.00  if $_string_result eq "0"

I could inverse the login to look for "*access*" instead of "*trunk*" and that might be slightly more reliable but I was hoping for some way to determine the mode that does not require using a vty and config output.

6 Replies 6

Joe Clarke
Cisco Employee
Cisco Employee

The CLI is the easiest way to do this.  SNMP would work, but you'd need to know the index mapping.  I wouldn't use the config, though.  I would do:

action 1.02 cli command "show int $_mat_intf_name switchport | inc Operational Mode:"

action 1.03 string match "*trunk*" $_cli_result

This will properly match the ports that are not explicitly configured for trunking but have negotiated trunking.

That is probably a better solution but we disable negotiation on all ports.

I am leaning towards SNMP but that is going to be a bit more code if I can get it to work.  Would that also be a faster solution?  Currently I have my applet limited to running 5 concurrent processes/threads because I require a VTY early on.  With more than 5 running it exhausts the available VTYs.

Also because it is running on MAC Detection events trunk interfaces can overflow the event queue of 64.  I thought that if I could discard events triggered by trunk interfaces without needing to grab a VTY it could help keep the queue shorter because trunk generated events would be discarded quicker.

Another possibility might be to break the applet into two pieces.  One to detect the mac and determine if the interface is an access port then use syslog or some other custom event to run an applet that runs the rest of my logic and requires the VTY sessions.

I'm not sure it would be that much faster since you'd have to do a few SNMP queries to find the index values you need.  It would certainly complicate your code.

The idea of doing batch processing of the ports to modify is a good idea if you don't need the changes to be real-time.  The other advantage you get from this approach is less chance of losing an event due to limited VTY resources.

I think that by inverting the logic to look explicitly for access ports instead of looking for trunk ports to exclude will resolve my problem with it not being reliable.  I am not sure why my code would sometimes not find the string "trunk" in the running config.  Perhaps the running config can sometimes appear empty/blank?  Anyway I am now looking at the interface operational mode for "access".  If I somehow get no output then it will just exit (safer that way).

This is for real-time interface configuration but missing some events is acceptable in this case from both security and operational perspectives.  I am trying to keep the applet generic but I could improve it by filtering out events generated from my trunk ports in the event detector "event mat mac-address "^.*$" type add".
http://www.cisco.com/c/en/us/td/docs/ios-xml/ios/eem/command/eem-cr-book/eem-cr-e2.html

Never use the config to get operational data.  It's a dangerous practice, and it is more expensive CPU-wise that looking at the operational command.  You should not see any false-positives if you look at pure operational data.

Yes, you could filter with the regexp, but it could be limited if your devices diverge from a common pattern of trunk vs. access ports.

Thanks for all the tips.  

The applet is responsible for configuring our access ports using macros and a web based inventory system.  If we don't have the device in the inventory it gets dumped to an "UNIDENTIFIED" vlan that is outside of our corporate network.  Additional anything inside the corporate network is secured via a port ACL and|or 802.1x.

So spoofing one of our actual devices gets you stuck behind an ACL that is extremely restrictive or stuck on an 802.1x port that will just shun you to the "unauthorized" vlan.

I also don't have to deal with users moving stuff around.  They can have at it.

Still a work in progress though.  I want to add a backup server and possibly caching responses from the server in memory.

event manager environment identityserver     http://10.10.10.10/plugins/identify
event manager scheduler applet thread class default number 5

event manager applet detect-mac
!!!
!! Detect MAC addresses
!!!
event mat mac-address "^.*$" type add
action 1.00 if $_mat_notification eq "add"

!!!
!! Excluding trunk interfaces.
!!!
action 1.01 cli command "enable"
action 1.02 cli command "show int $_mat_intf_name switchport | inc Operational Mode:"
action 1.03 string match "*access*" "$_cli_result"
action 1.04 syslog msg "Interface: $_mat_intf_name Result: $_cli_result"
action 2.00 if $_string_result eq "1"

!!!
!! Here we push this event to the identity server.
!! we need to include the MAC address $_mat_mac_address and possibly the interface if we want to track that.
!! Return should be <macro>:<description>
!!!
action 2.01 cli command "more $identityserver/$_mat_mac_address"
action 2.02 string match "*(I/O error)*" "$_cli_result"

action 3.00 if $_string_result eq "0"
action 3.01 regexp "(.*):" $_cli_result match macro
action 3.02 regexp ":(.*)" $_cli_result match description

action 4.00 else
action 4.01 syslog msg "Call to identity server failed! Result: $_cli_result"
action 4.02 cli command "exit"
action 4.03 exit 1
action 4.04 end

!!!
!! the identity server returns the macro that should be used for this device (computer|printer)
!! if no macro is returned or the macro does not exist the "defaultmacro" is applied if it exists.
!!!
action 4.05 cli command "show run | i macro name $macro"
action 4.06 string match "*$macro*" "$_cli_result"
action 5.00 if $_string_result eq "1"
action 5.01 cli command "config t"
action 5.02 cli command "macro global apply $macro INTERFACE $_mat_intf_name DESCRIPTION $description"
action 5.03 cli command "end"
action 5.04 syslog msg "Interface: $_mat_intf_name, MAC: $_mat_mac_address, Macro: $macro"
action 6.00 else
action 6.01 cli command "show run | i macro name $defaultmacro"
action 6.02 string match "*$defaultmacro*" "$_cli_result"

action 7.00 if $_string_result eq "1"
action 7.01 cli command "config t"
action 7.02 cli command "macro global apply $defaultmacro INTERFACE $_mat_intf_name DESCRIPTION $description"
action 7.03 cli command "end"
action 7.04 end
action 7.05 end
action 7.06 end
action 7.07 cli command "exit"
action 7.08 end
exit