cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
2023
Views
0
Helpful
10
Replies

EMM script with CDP

Rafael Mendes
Level 2
Level 2

Hello Everyone.

I have the topology bellow.

6500-1(DATACENTER 1) ------ LAN TO LAN 1 ------- Nexus 7K-1(DATACENTER 2)

6500-2(DATACENTER 1) ------ LAN TO LAN 2 ------- Nexus 7K-2(DATACENTER 2)

Lan to Lan 1 is used for vlan 3, Lan to Lan 2 is used for the other vlans(spanning-tree environment).

Obs: My 6500 does not contains the VSS feature, so, its not a Port Channel interface.

I need create a EMM script for verify the cdp neighbors, if the neighbor disappear, the switch need to shutdown the port conected to the neighbor(the spanning-tree comes up and redirects the traffic for the other link), its possible?

Tks,

Rafael

1 Accepted Solution

Accepted Solutions

It's possible to do what you want, but you will need some non-trivial logic in Tcl to compare the current CDP list to the previous one to see if a neighbor went away.  It becomes a bit simpler if you can statically code your CDP neighbors and ports.  In that case, a script like this would work:

::cisco::eem::event_register_timer watchdog time 10

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

array set arr_einfo [event_reqinfo]


if [catch {cli_open} result] {
    error $result $errorInfo
} else {
    array set cli1 $result
}

if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
    error $_cli_result $errorInfo
}

if [catch {cli_exec $cli1(fd) "show cdp nei"} _cli_result] {
    error $_cli_result $errorInfo
}

set _regexp_result [regexp {device1} $_cli_result]
if {$_regexp_result == 0} {
    if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "int te1/1"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
        error $_cli_result $errorInfo
    }

} else {
    set _regexp_result [regexp {device2} $_cli_result]
    if {$_regexp_result == 0} {
        if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "int te1/2"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

    }
}

# Close open cli before exit.
catch {cli_close $cli1(fd) $cli1(tty_id)} result

Replace "device1" and "device2" with your actual device names as they appear in show cdp nei.  And replace the interface names.  Note: this script is one-way.  Once a port is shut down, you'd have to manually re-enable it.

View solution in original post

10 Replies 10

Joe Clarke
Cisco Employee
Cisco Employee

What version of code is the 6500 running?  You may not have the CDP event detector in order to do this easily.

Hi Joseph,

Cisco IOS Software, s72033_rp Software (s72033_rp-IPSERVICESK9_WAN-M), Version 12.2(33)SXH6, RELEASE SOFTWARE (fc1)

It's possible to do what you want, but you will need some non-trivial logic in Tcl to compare the current CDP list to the previous one to see if a neighbor went away.  It becomes a bit simpler if you can statically code your CDP neighbors and ports.  In that case, a script like this would work:

::cisco::eem::event_register_timer watchdog time 10

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

array set arr_einfo [event_reqinfo]


if [catch {cli_open} result] {
    error $result $errorInfo
} else {
    array set cli1 $result
}

if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
    error $_cli_result $errorInfo
}

if [catch {cli_exec $cli1(fd) "show cdp nei"} _cli_result] {
    error $_cli_result $errorInfo
}

set _regexp_result [regexp {device1} $_cli_result]
if {$_regexp_result == 0} {
    if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "int te1/1"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
        error $_cli_result $errorInfo
    }

} else {
    set _regexp_result [regexp {device2} $_cli_result]
    if {$_regexp_result == 0} {
        if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "int te1/2"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

    }
}

# Close open cli before exit.
catch {cli_close $cli1(fd) $cli1(tty_id)} result

Replace "device1" and "device2" with your actual device names as they appear in show cdp nei.  And replace the interface names.  Note: this script is one-way.  Once a port is shut down, you'd have to manually re-enable it.

Tks.

So, for the configuration in 6500, i need apply this script like below?

conf t

tclsh

::cisco::eem::event_register_timer watchdog time 10

namespace import ::cisco::eem::*
namespace import ::cisco::lib::*

array set arr_einfo [event_reqinfo]


if [catch {cli_open} result] {
    error $result $errorInfo
} else {
    array set cli1 $result
}

if [catch {cli_exec $cli1(fd) "enable"} _cli_result] {
    error $_cli_result $errorInfo
}

if [catch {cli_exec $cli1(fd) "show cdp nei"} _cli_result] {
    error $_cli_result $errorInfo
}

set _regexp_result [regexp {device1} $_cli_result]
if {$_regexp_result == 0} {
    if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "int te1/1"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
        error $_cli_result $errorInfo
    }

    if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
        error $_cli_result $errorInfo
    }

} else {
    set _regexp_result [regexp {device2} $_cli_result]
    if {$_regexp_result == 0} {
        if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "int te1/2"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

    }
}

# Close open cli before exit.
catch {cli_close $cli1(fd) $cli1(tty_id)} result

exit

its correct?

tks.

No, you have to register the policy with the EEM server.  You need to copy the script to your switch (after modifying the parts I told you about), then configure:

event manager directory user policy disk0:

(This should be wherever you copied the script.)

event manager policy tm_cdp_watch.tcl

(This assumes you named the policy tm_cdp_watch.tcl.)

Ok,

After modifying the script:

1 - I will copy the tm_cdp_watch.tcl script to my switch disk0:/tm_cdp_watch.tcl

2 - Register the Policy directory using the command "event manager directory user policy disk0:"

3 - Enable the script tcl policy using the command "event manager policy tm_cdp_watch.tcl"

Its ok?

In the script, you put two neighbors per switch, but i will have only one neighbor per 6500(one 6500 to one 7K) so i need exclude the second neighbor and the second interface to the script, how i can do this?

Only excludind this parts(below)?

 else {
    set _regexp_result [regexp {device2} $_cli_result]
    if {$_regexp_result == 0} {
        if [catch {cli_exec $cli1(fd) "config t"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "int te1/2"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "shut"} _cli_result] {
            error $_cli_result $errorInfo
        }

        if [catch {cli_exec $cli1(fd) "end"} _cli_result] {
            error $_cli_result $errorInfo
        }

Yeah, remove that block and you should be fine for your one neighbor.

Ok, tks.

More one question(sorry, rs) if i shutdown the port on 6500-1, in the other side(7K-1) the port does not come to down because its directly connected in the ISP equipment(layer 1 only), because this, i need shutdown the port on 7K too for prevent "assimetric" traffic.

In ths case, the script for 7K is the same?

No.  What you want to do cannot be done on the N7K today.  There is no supported way to do this kind of programmatic logic in an event-driven way yet.  NX-OS 7.0 will offer support for this.

Ok.

Tks!

I appreciate your help!

Getting Started

Find answers to your questions by entering keywords or phrases in the Search bar above. New here? Use these resources to familiarize yourself with the community: