diff options
26 files changed, 1282 insertions, 2 deletions
diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index adb8be36d3..5d492249d3 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -83,13 +83,13 @@ static void nhrp_request_stop(void)  	debugf(NHRP_DEBUG_COMMON, "Exiting...");  	frr_early_fini(); -	nhrp_shortcut_terminate(); +	vrf_terminate();  	nhrp_nhs_terminate();  	nhrp_zebra_terminate();  	vici_terminate();  	evmgr_terminate(); -	vrf_terminate();  	nhrp_vc_terminate(); +	nhrp_shortcut_terminate();  	debugf(NHRP_DEBUG_COMMON, "Done."); diff --git a/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json new file mode 100644 index 0000000000..a94dd9fecf --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/nhrp_cache.json @@ -0,0 +1,40 @@ +{ +    "attr": { +        "entriesCount": 3 +    }, +    "table": [ +        { +            "interface": "r1-gre0", +            "type": "dynamic", +            "protocol": "176.16.1.4", +            "nbma": "192.168.2.4", +            "claimed_nbma": "192.168.2.4", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r1-gre0", +            "type": "local", +            "protocol": "176.16.1.1", +            "nbma": "192.168.1.1", +            "claimed_nbma": "192.168.1.1", +            "used": false, +            "timeout": false, +            "auth": false, +            "identity": "-" +        }, +        { +            "interface": "r1-gre0", +            "type": "dynamic", +            "protocol": "176.16.1.5", +            "nbma": "192.168.2.5", +            "claimed_nbma": "192.168.2.5", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r1/nhrp_route.json b/tests/topotests/nhrp_redundancy/r1/nhrp_route.json new file mode 100644 index 0000000000..b5f3e29e74 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/nhrp_route.json @@ -0,0 +1,48 @@ +{ +    "176.16.1.4\/32": [ +        { +            "prefix": "176.16.1.4\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r1-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.5\/32": [ +        { +            "prefix": "176.16.1.5\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r1-gre0", +                    "active": true +                } +            ] +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r1/nhrpd.conf b/tests/topotests/nhrp_redundancy/r1/nhrpd.conf new file mode 100644 index 0000000000..ad48ce3769 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/nhrpd.conf @@ -0,0 +1,9 @@ +!debug nhrp all +nhrp nflog-group 1 +interface r1-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source r1-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r1/zebra.conf b/tests/topotests/nhrp_redundancy/r1/zebra.conf new file mode 100644 index 0000000000..0f11563f57 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r1/zebra.conf @@ -0,0 +1,12 @@ +ip forwarding +interface r1-eth0 + ip address 192.168.1.1/24 +! +ip route 192.168.2.0/24 192.168.1.6 +interface r1-gre0 + ip address 176.16.1.1/32 + no link-detect + ipv6 nd suppress-ra +! +ip route 4.4.4.0/24 176.16.1.4 +ip route 5.5.5.0/24 176.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json new file mode 100644 index 0000000000..91557a1918 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/nhrp_cache.json @@ -0,0 +1,40 @@ +{ +    "attr": { +        "entriesCount": 3 +    }, +    "table": [ +        { +            "interface": "r2-gre0", +            "type": "local", +            "protocol": "176.16.1.2", +            "nbma": "192.168.1.2", +            "claimed_nbma": "192.168.1.2", +            "used": false, +            "timeout": false, +            "auth": false, +            "identity": "-" +        }, +        { +            "interface": "r2-gre0", +            "type": "dynamic", +            "protocol": "176.16.1.4", +            "nbma": "192.168.2.4", +            "claimed_nbma": "192.168.2.4", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r2-gre0", +            "type": "dynamic", +            "protocol": "176.16.1.5", +            "nbma": "192.168.2.5", +            "claimed_nbma": "192.168.2.5", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r2/nhrp_route.json b/tests/topotests/nhrp_redundancy/r2/nhrp_route.json new file mode 100644 index 0000000000..f1fa6e54c1 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/nhrp_route.json @@ -0,0 +1,48 @@ +{ +    "176.16.1.4\/32": [ +        { +            "prefix": "176.16.1.4\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r2-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.5\/32": [ +        { +            "prefix": "176.16.1.5\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r2-gre0", +                    "active": true +                } +            ] +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r2/nhrpd.conf b/tests/topotests/nhrp_redundancy/r2/nhrpd.conf new file mode 100644 index 0000000000..4d63f07d1f --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/nhrpd.conf @@ -0,0 +1,9 @@ +!debug nhrp all +nhrp nflog-group 1 +interface r2-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source r2-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r2/zebra.conf b/tests/topotests/nhrp_redundancy/r2/zebra.conf new file mode 100644 index 0000000000..1a9c4ff915 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r2/zebra.conf @@ -0,0 +1,12 @@ +ip forwarding +interface r2-eth0 + ip address 192.168.1.2/24 +! +ip route 192.168.2.0/24 192.168.1.6 +interface r2-gre0 + ip address 176.16.1.2/32 + no link-detect + ipv6 nd suppress-ra +! +ip route 4.4.4.0/24 176.16.1.4 +ip route 5.5.5.0/24 176.16.1.5 diff --git a/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json new file mode 100644 index 0000000000..ef3ab690bc --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/nhrp_cache.json @@ -0,0 +1,40 @@ +{ +    "attr": { +        "entriesCount": 3 +    }, +    "table": [ +        { +            "interface": "r3-gre0", +            "type": "dynamic", +            "protocol": "176.16.1.4", +            "nbma": "192.168.2.4", +            "claimed_nbma": "192.168.2.4", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r3-gre0", +            "type": "local", +            "protocol": "176.16.1.3", +            "nbma": "192.168.1.3", +            "claimed_nbma": "192.168.1.3", +            "used": false, +            "timeout": false, +            "auth": false, +            "identity": "-" +        }, +        { +            "interface": "r3-gre0", +            "type": "dynamic", +            "protocol": "176.16.1.5", +            "nbma": "192.168.2.5", +            "claimed_nbma": "192.168.2.5", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r3/nhrp_route.json b/tests/topotests/nhrp_redundancy/r3/nhrp_route.json new file mode 100644 index 0000000000..3d548c08fd --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/nhrp_route.json @@ -0,0 +1,48 @@ +{ +    "176.16.1.4\/32": [ +        { +            "prefix": "176.16.1.4\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r3-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.5\/32": [ +        { +            "prefix": "176.16.1.5\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r3-gre0", +                    "active": true +                } +            ] +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r3/nhrpd.conf b/tests/topotests/nhrp_redundancy/r3/nhrpd.conf new file mode 100644 index 0000000000..87cc2161f8 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/nhrpd.conf @@ -0,0 +1,9 @@ +!debug nhrp all +nhrp nflog-group 1 +interface r3-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp redirect + tunnel source r3-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r3/zebra.conf b/tests/topotests/nhrp_redundancy/r3/zebra.conf new file mode 100644 index 0000000000..980cfbcaab --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r3/zebra.conf @@ -0,0 +1,12 @@ +ip forwarding +interface r3-eth0 + ip address 192.168.1.3/24 +! +ip route 192.168.2.0/24 192.168.1.6 +interface r3-gre0 + ip address 176.16.1.3/32 + no link-detect + ipv6 nd suppress-ra +! +ip route 4.4.4.0/24 176.16.1.4 +ip route 5.5.5.0/24 176.16.1.5
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json new file mode 100644 index 0000000000..f87ebcf5fc --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrp_cache.json @@ -0,0 +1,51 @@ +{ +    "attr": { +        "entriesCount": 4 +    }, +    "table": [ +        { +            "interface": "r4-gre0", +            "type": "nhs", +            "protocol": "176.16.1.2", +            "nbma": "192.168.1.2", +            "claimed_nbma": "192.168.1.2", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r4-gre0", +            "type": "local", +            "protocol": "176.16.1.4", +            "nbma": "192.168.2.4", +            "claimed_nbma": "192.168.2.4", +            "used": false, +            "timeout": false, +            "auth": false, +            "identity": "-" +        }, +        { +            "interface": "r4-gre0", +            "type": "nhs", +            "protocol": "176.16.1.3", +            "nbma": "192.168.1.3", +            "claimed_nbma": "192.168.1.3", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r4-gre0", +            "type": "nhs", +            "protocol": "176.16.1.1", +            "nbma": "192.168.1.1", +            "claimed_nbma": "192.168.1.1", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_route.json b/tests/topotests/nhrp_redundancy/r4/nhrp_route.json new file mode 100644 index 0000000000..4f1faee7a7 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrp_route.json @@ -0,0 +1,71 @@ +{ +    "176.16.1.1\/32": [ +        { +            "prefix": "176.16.1.1\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.2\/32": [ +        { +            "prefix": "176.16.1.2\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.3\/32": [ +        { +            "prefix": "176.16.1.3\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json b/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json new file mode 100644 index 0000000000..f8efff2059 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrp_route_shortcut.json @@ -0,0 +1,118 @@ +{ +    "5.5.5.5\/32": [ +        { +            "prefix": "5.5.5.5\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "ip": "176.16.1.5", +                    "afi": "ipv4", +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.1\/32": [ +        { +            "prefix": "176.16.1.1\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.2\/32": [ +        { +            "prefix": "176.16.1.2\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.3\/32": [ +        { +            "prefix": "176.16.1.3\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.5\/32": [ +        { +            "prefix": "176.16.1.5\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r4-gre0", +                    "active": true +                } +            ] +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r4/nhrpd.conf b/tests/topotests/nhrp_redundancy/r4/nhrpd.conf new file mode 100644 index 0000000000..8a52f3386e --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/nhrpd.conf @@ -0,0 +1,11 @@ +!debug nhrp all +interface r4-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp registration no-unique + ip nhrp nhs dynamic nbma 192.168.1.1  + ip nhrp nhs dynamic nbma 192.168.1.2 + ip nhrp nhs dynamic nbma 192.168.1.3 + ip nhrp shortcut + tunnel source r4-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r4/zebra.conf b/tests/topotests/nhrp_redundancy/r4/zebra.conf new file mode 100644 index 0000000000..e4a9a6f80f --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r4/zebra.conf @@ -0,0 +1,16 @@ +ip forwarding +interface r4-eth0 + ip address 192.168.2.4/24 +! +ip route 192.168.1.0/24 192.168.2.6 +interface r4-gre0 + ip address 176.16.1.4/32 + no link-detect + ipv6 nd suppress-ra +! +interface r4-eth1 + ip address 4.4.4.4/24 +! +ip route 0.0.0.0/0 176.16.1.1 50 +ip route 0.0.0.0/0 176.16.1.2 60 +ip route 0.0.0.0/0 176.16.1.3 70
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json b/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json new file mode 100644 index 0000000000..bc041c6014 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/nhrp_cache.json @@ -0,0 +1,51 @@ +{ +    "attr": { +        "entriesCount": 4 +    }, +    "table": [ +        { +            "interface": "r5-gre0", +            "type": "nhs", +            "protocol": "176.16.1.2", +            "nbma": "192.168.1.2", +            "claimed_nbma": "192.168.1.2", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r5-gre0", +            "type": "nhs", +            "protocol": "176.16.1.3", +            "nbma": "192.168.1.3", +            "claimed_nbma": "192.168.1.3", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r5-gre0", +            "type": "nhs", +            "protocol": "176.16.1.1", +            "nbma": "192.168.1.1", +            "claimed_nbma": "192.168.1.1", +            "used": false, +            "timeout": true, +            "auth": false, +            "identity": "" +        }, +        { +            "interface": "r5-gre0", +            "type": "local", +            "protocol": "176.16.1.5", +            "nbma": "192.168.2.5", +            "claimed_nbma": "192.168.2.5", +            "used": false, +            "timeout": false, +            "auth": false, +            "identity": "-" +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrp_route.json b/tests/topotests/nhrp_redundancy/r5/nhrp_route.json new file mode 100644 index 0000000000..1d1c16ffb8 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/nhrp_route.json @@ -0,0 +1,71 @@ +{ +    "176.16.1.1\/32": [ +        { +            "prefix": "176.16.1.1\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r5-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.2\/32": [ +        { +            "prefix": "176.16.1.2\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r5-gre0", +                    "active": true +                } +            ] +        } +    ], +    "176.16.1.3\/32": [ +        { +            "prefix": "176.16.1.3\/32", +            "protocol": "nhrp", +            "vrfId": 0, +            "vrfName": "default", +            "selected": true, +            "destSelected": true, +            "distance": 10, +            "metric": 0, +            "installed": true, +            "internalNextHopNum": 1, +            "internalNextHopActiveNum": 1, +            "nexthops": [ +                { +                    "fib": true, +                    "directlyConnected": true, +                    "interfaceName": "r5-gre0", +                    "active": true +                } +            ] +        } +    ] +}
\ No newline at end of file diff --git a/tests/topotests/nhrp_redundancy/r5/nhrpd.conf b/tests/topotests/nhrp_redundancy/r5/nhrpd.conf new file mode 100644 index 0000000000..7241ed592d --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/nhrpd.conf @@ -0,0 +1,11 @@ +!debug nhrp all +interface r5-gre0 + ip nhrp holdtime 10 + ip nhrp network-id 42 + ip nhrp nhs dynamic nbma 192.168.1.1 + ip nhrp nhs dynamic nbma 192.168.1.2 + ip nhrp nhs dynamic nbma 192.168.1.3 + ip nhrp registration no-unique + ip nhrp shortcut + tunnel source r5-eth0 +exit diff --git a/tests/topotests/nhrp_redundancy/r5/zebra.conf b/tests/topotests/nhrp_redundancy/r5/zebra.conf new file mode 100644 index 0000000000..9b1e1c0646 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r5/zebra.conf @@ -0,0 +1,16 @@ +ip forwarding +interface r5-eth0 + ip address 192.168.2.5/24 +! +ip route 192.168.1.0/24 192.168.2.6 +interface r5-gre0 + ip address 176.16.1.5/32 + no link-detect + ipv6 nd suppress-ra +! +interface r5-eth1 + ip address 5.5.5.5/24 +! +ip route 0.0.0.0/0 176.16.1.1 50 +ip route 0.0.0.0/0 176.16.1.2 60 +ip route 0.0.0.0/0 176.16.1.3 70 diff --git a/tests/topotests/nhrp_redundancy/r6/zebra.conf b/tests/topotests/nhrp_redundancy/r6/zebra.conf new file mode 100644 index 0000000000..63a37cd5bf --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r6/zebra.conf @@ -0,0 +1,7 @@ +ip forwarding +interface r6-eth0 + ip address 192.168.1.6/24 +! +interface r6-eth1 + ip address 192.168.2.6/24 +exit diff --git a/tests/topotests/nhrp_redundancy/r7/zebra.conf b/tests/topotests/nhrp_redundancy/r7/zebra.conf new file mode 100644 index 0000000000..5747b40956 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/r7/zebra.conf @@ -0,0 +1,4 @@ +interface r7-eth0 + ip address 4.4.4.7/24 +! +ip route 0.0.0.0/0 4.4.4.4 diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot new file mode 100644 index 0000000000..c169436db0 --- /dev/null +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.dot @@ -0,0 +1,103 @@ +## Color coding: +######################### +##  Main FRR: #f08080  red +##  Switches: #d0e0d0  gray +##  RIP:      #19e3d9  Cyan +##  RIPng:    #fcb314  dark yellow +##  OSPFv2:   #32b835  Green +##  OSPFv3:   #19e3d9  Cyan +##  ISIS IPv4 #fcb314  dark yellow +##  ISIS IPv6 #9a81ec  purple +##  BGP IPv4  #eee3d3  beige +##  BGP IPv6  #fdff00  yellow +##### Colors (see http://www.color-hex.com/) + +graph template { +  label="nhrp-topo-redundant-nhs"; + +  # Routers +  r1 [ +    shape=doubleoctagon, +    label="NHS 1", +    fillcolor="#f08080", +    style=filled, +  ]; +  r2 [ +    shape=doubleoctagon +    label="NHS 2", +    fillcolor="#f08080", +    style=filled, +  ]; +  r3 [ +    shape=doubleoctagon +    label="NHS 3", +    fillcolor="#f08080", +    style=filled, +  ]; +  r4 [ +    shape=doubleoctagon +    label="NHC 1", +    fillcolor="#f08080", +    style=filled, +  ]; +  r5 [ +    shape=doubleoctagon +    label="NHC 2", +    fillcolor="#f08080", +    style=filled, +  ]; +  r6 [ +    shape=doubleoctagon +    label="router", +    fillcolor="#f08080", +    style=filled, +  ]; +  r7 [ +    shape=doubleoctagon +    label="host", +    fillcolor="#f08080", +    style=filled, +  ]; + +  # Switches +  sw1 [ +    shape=oval, +    label="sw1\n192.168.1.0/24", +    fillcolor="#d0e0d0", +    style=filled, +  ]; +  sw2 [ +    shape=oval, +    label="sw2\n192.168.2.0/24", +    fillcolor="#d0e0d0", +    style=filled, +  ]; +  sw3 [ +    shape=oval, +    label="sw3\n4.4.4.0/24", +    fillcolor="#d0e0d0", +    style=filled, +  ]; +  sw4 [ +    shape=oval, +    label="sw4\n5.5.5.0/24", +    fillcolor="#d0e0d0", +    style=filled, +  ]; + +  # Connections +  r1 -- sw1 [label="eth0"]; +  r2 -- sw1 [label="eth0"]; +  r3 -- sw1 [label="eth0"]; +  r6 -- sw1 [label="eth0"]; + +  r4 -- sw2 [label="eth0"]; +  r5 -- sw2 [label="eth0"]; +  r6 -- sw2 [label="eth1"]; + +  r4 -- sw3 [label="eth1"]; +  r7 -- sw3 [label="eth0"]; + +  r5 -- sw4 [label="eth1"]; + +} diff --git a/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py new file mode 100644 index 0000000000..81a22ebfaf --- /dev/null +++ b/tests/topotests/nhrp_redundancy/test_nhrp_redundancy.py @@ -0,0 +1,423 @@ +#!/usr/bin/env python +# SPDX-License-Identifier: GPL-2.0-or-later +# +# test_nhrp_redundancy.py +# +# Copyright 2024, LabN Consulting, L.L.C. +# Dave LeRoy +# + +import os +import sys +import json +from time import sleep +from functools import partial +import pytest + +# pylint: disable=C0413 +# Import topogen and topotest helpers +from lib import topotest +from lib.topogen import Topogen, TopoRouter, get_topogen +from lib.topolog import logger +from lib.common_config import ( +    required_linux_kernel_version, +    shutdown_bringup_interface, +    retry, +) + +""" +test_nhrp_redundancy.py: Test NHS redundancy for NHRP +""" + +TOPOLOGY = """ ++------------+                  +------------+                   +------------+                +|            |                  |            |                   |            |                +|            |                  |            |                   |            |                +|   NHS 1    |                  |   NHS 2    |                   |    NHS 3   |                +|            |                  |            |                   |            |                ++-----+------+                  +-----+------+                   +-----+------+                +      |.1                             |.2                              |.3                     +      |                               |                                |                       +      |                               |            192.168.1.0/24      |                       +------+-------------------------------+------------------+-------------+------                 +                                                         |                                     +                                                         |.6                                   +         GRE P2MP between all NHS and NHC          +-----+------+                              +               172.16.1.x/32                       |            |                              +                                                   |            |                              +                                                   |   Router   |                              +                                                   |            |                              +                                                   +-----+------+                              +                                                         |                                     +                                                         |                                     +                               ---------+----------------+-------------+------                 +                                        |          192.168.2.0/24      |                       +                                        |                              |                       +                       |                |.4                            |.5                     ++------------+         |        +-------+----+                  +------+-----+     |           +|            |         |        |            |                  |            |     |           +|            |         +--------+            |                  |            |     |           +|    Host    |.7       |        |    NHC 1   |                  |    NHC 2   +-----+5.5.5.0/24 +|            +---------+        |            |                  |            |     |           ++------------+         |        +------------+                  +------------+     |           +                       |                                                           |           +                  4.4.4.0/24                                                                   +""" + +# Save the Current Working Directory to find configuration files. +CWD = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.join(CWD, "../")) + +# Required to instantiate the topology builder class. + +pytestmark = [pytest.mark.nhrpd] + + +def build_topo(tgen): +    "Build function" + +    # Create 7 routers +    for routern in range(1, 8): +        tgen.add_router("r{}".format(routern)) + +    # Interconnect routers 1, 2, 3, 6 +    switch = tgen.add_switch("s1") +    switch.add_link(tgen.gears["r1"]) +    switch.add_link(tgen.gears["r2"]) +    switch.add_link(tgen.gears["r3"]) +    switch.add_link(tgen.gears["r6"]) + +    # Interconnect routers 4, 5, 6 +    switch = tgen.add_switch("s2") +    switch.add_link(tgen.gears["r4"]) +    switch.add_link(tgen.gears["r5"]) +    switch.add_link(tgen.gears["r6"]) + +    # Connect router 4, 7 +    switch = tgen.add_switch("s3") +    switch.add_link(tgen.gears["r4"]) +    switch.add_link(tgen.gears["r7"]) + +    # Connect router 5 +    switch = tgen.add_switch("s4") +    switch.add_link(tgen.gears["r5"]) + + +def _populate_iface(): +    tgen = get_topogen() +    cmds_tot_hub = [ +        "ip tunnel add {0}-gre0 mode gre ttl 64 key 42 dev {0}-eth0 local 192.168.1.{1} remote 0.0.0.0", +        "ip link set dev {0}-gre0 up", +        "echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu", +        "echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6", +        "echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6", +        "iptables -A FORWARD -i {0}-gre0 -o {0}-gre0 -m hashlimit --hashlimit-upto 4/minute --hashlimit-burst 1 --hashlimit-mode srcip,dstip --hashlimit-srcmask 24 --hashlimit-dstmask 24 --hashlimit-name loglimit-0 -j NFLOG --nflog-group 1 --nflog-range 128", +    ] + +    cmds_tot = [ +        "ip tunnel add {0}-gre0 mode gre ttl 64 key 42 dev {0}-eth0 local 192.168.2.{1} remote 0.0.0.0", +        "ip link set dev {0}-gre0 up", +        "echo 0 > /proc/sys/net/ipv4/ip_forward_use_pmtu", +        "echo 1 > /proc/sys/net/ipv6/conf/{0}-eth0/disable_ipv6", +        "echo 1 > /proc/sys/net/ipv6/conf/{0}-gre0/disable_ipv6", +    ] + +    for cmd in cmds_tot_hub: +        # Router 1 +        input = cmd.format("r1", "1") +        logger.info("input: " + input) +        output = tgen.net["r1"].cmd(input) +        logger.info("output: " + output) + +        # Router 2 +        input = cmd.format("r2", "2") +        logger.info("input: " + input) +        output = tgen.net["r2"].cmd(input) +        logger.info("output: " + output) + +        # Router 3 +        input = cmd.format("r3", "3") +        logger.info("input: " + input) +        output = tgen.net["r3"].cmd(input) +        logger.info("output: " + output) + +    for cmd in cmds_tot: +        input = cmd.format("r4", "4") +        logger.info("input: " + input) +        output = tgen.net["r4"].cmd(input) +        logger.info("output: " + output) + +        input = cmd.format("r5", "5") +        logger.info("input: " + input) +        output = tgen.net["r5"].cmd(input) +        logger.info("output: " + output) + + +def _verify_iptables(): +    tgen = get_topogen() +    # Verify iptables is installed. Required for shortcuts +    rc, _, _ = tgen.net["r1"].cmd_status("iptables") +    return False if rc == 127 else True + + +def setup_module(mod): +    logger.info("NHRP Redundant NHS:\n {}".format(TOPOLOGY)) + +    result = required_linux_kernel_version("5.0") +    if result is not True: +        pytest.skip("Kernel requirements are not met") + +    tgen = Topogen(build_topo, mod.__name__) +    tgen.start_topology() + +    # Starting Routers +    router_list = tgen.routers() +    _populate_iface() + +    for rname, router in router_list.items(): +        router.load_config( +            TopoRouter.RD_ZEBRA, +            os.path.join(CWD, "{}/zebra.conf".format(rname)), +        ) +        if rname in ("r1", "r2", "r3", "r4", "r5"): +            router.load_config( +                TopoRouter.RD_NHRP, os.path.join(CWD, "{}/nhrpd.conf".format(rname)) +            ) + +    # Initialize all routers. +    tgen.start_router() + + +def teardown_module(_mod): +    "Teardown the pytest environment" +    tgen = get_topogen() +    tgen.stop_topology() + + +def test_protocols_convergence(): +    """ +    Assert that all protocols have converged before checking for the NHRP +    statuses as they depend on it. +    """ +    tgen = get_topogen() +    if tgen.routers_have_failure(): +        pytest.skip(tgen.errors) + +    logger.info("Checking NHRP cache and IPv4 routes for convergence") +    router_list = tgen.routers() + +    # Check NHRP cache on servers and clients +    for rname, router in router_list.items(): + +        json_file = "{}/{}/nhrp_cache.json".format(CWD, router.name) +        if not os.path.isfile(json_file): +            logger.info("skipping file {}".format(json_file)) +            continue + +        expected = json.loads(open(json_file).read()) +        test_func = partial( +            topotest.router_json_cmp, router, "show ip nhrp cache json", expected +        ) +        _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + +        output = router.vtysh_cmd("show ip nhrp cache") +        logger.info(output) + +        assertmsg = '"{}" JSON output mismatches'.format(router.name) +        assert result is None, assertmsg + +    # Check NHRP IPV4 routes on servers and clients +    for rname, router in router_list.items(): + +        json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) +        if not os.path.isfile(json_file): +            logger.info("skipping file {}".format(json_file)) +            continue + +        expected = json.loads(open(json_file).read()) +        test_func = partial( +            topotest.router_json_cmp, router, "show ip route nhrp json", expected +        ) +        _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + +        output = router.vtysh_cmd("show ip route nhrp") +        logger.info(output) + +        assertmsg = '"{}" JSON output mismatches'.format(router.name) +        assert result is None, assertmsg + +    # Test connectivity from 1 NHRP server to all clients +    pingrouter = tgen.gears["r1"] +    logger.info("Check Ping IPv4 from  R1 to R4 = 176.16.1.4)") +    output = pingrouter.run("ping 176.16.1.4 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R1 to R4 should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R1 to R4 OK") + +    logger.info("Check Ping IPv4 from  R1 to R5 = 176.16.1.5)") +    output = pingrouter.run("ping 176.16.1.5 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R1 to R5 should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R1 to R5 OK") + +    # Test connectivity from 1 NHRP client to all servers +    pingrouter = tgen.gears["r4"] +    logger.info("Check Ping IPv4 from  R4 to R1 = 176.16.1.1)") +    output = pingrouter.run("ping 176.16.1.1 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R4 to R1 should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R4 to R1 OK") + +    logger.info("Check Ping IPv4 from  R4 to R2 = 176.16.1.2)") +    output = pingrouter.run("ping 176.16.1.2 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R4 to R2 should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R4 to R2 OK") + +    logger.info("Check Ping IPv4 from  R4 to R3 = 176.16.1.3)") +    output = pingrouter.run("ping 176.16.1.3 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R4 to R3 should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R4 to R3 OK") + + +@retry(retry_timeout=30, initial_wait=5) +def verify_shortcut_path(): +    """ +    Verifying that traffic flows through shortcut path +    """ +    tgen = get_topogen() +    pingrouter = tgen.gears["r7"] +    logger.info("Check Ping IPv4 from  R7 to R5 = 5.5.5.5") + +    output = pingrouter.run("ping 5.5.5.5 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R7 to R5 should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R7 to R5 OK") + + +def test_redundancy_shortcut(): +    """ +    Assert that if shortcut created and then NHS goes down, there is no traffic disruption +    Stop traffic and verify next time traffic started, shortcut is initiated by backup NHS +    """ +    tgen = get_topogen() +    if tgen.routers_have_failure(): +        pytest.skip(tgen.errors) + +    if not _verify_iptables(): +        pytest.skip("iptables not installed") + +    logger.info("Testing NHRP shortcuts with redundant servers") + +    # Verify R4 nhrp routes before shortcut creation +    router = tgen.gears["r4"] +    json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) +    assertmsg = "No nhrp_route file found" +    assert os.path.isfile(json_file), assertmsg + +    expected = json.loads(open(json_file).read()) +    test_func = partial( +        topotest.router_json_cmp, router, "show ip route nhrp json", expected +    ) +    _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + +    output = router.vtysh_cmd("show ip route nhrp") +    logger.info(output) + +    assertmsg = '"{}" JSON output mismatches'.format(router.name) +    assert result is None, assertmsg + +    # Initiate shortcut by pinging between clients +    pingrouter = tgen.gears["r7"] +    logger.info("Check Ping IPv4 from  R7 to R5 via shortcut = 5.5.5.5") + +    output = pingrouter.run("ping 5.5.5.5 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R7 to R5 via shortcut should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R7 to R5 via shortcut OK") + +    # Now check that NHRP shortcut route installed +    json_file = "{}/{}/nhrp_route_shortcut.json".format(CWD, router.name) +    assertmsg = "No nhrp_route file found" +    assert os.path.isfile(json_file), assertmsg + +    expected = json.loads(open(json_file).read()) +    test_func = partial( +        topotest.router_json_cmp, router, "show ip route nhrp json", expected +    ) +    _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + +    output = router.vtysh_cmd("show ip route nhrp") +    logger.info(output) + +    assertmsg = '"{}" JSON output mismatches'.format(router.name) +    assert result is None, assertmsg + +    # Bring down primary GRE interface and verify shortcut is not disturbed +    logger.info("Bringing down R1, primary NHRP server.") +    shutdown_bringup_interface(tgen, "r1", "r1-gre0", False) + +    # Verify shortcut is still active +    pingrouter = tgen.gears["r7"] +    logger.info("Check Ping IPv4 from  R7 to R5 via shortcut = 5.5.5.5") + +    output = pingrouter.run("ping 5.5.5.5 -f -c 1000") +    logger.info(output) +    if "1000 packets transmitted, 1000 received" not in output: +        assertmsg = "expected ping IPv4 from R7 to R5 via shortcut should be ok" +        assert 0, assertmsg +    else: +        logger.info("Check Ping IPv4 from R7 to R5 via shortcut OK") + +    # Now verify shortcut is purged with lack of traffic +    json_file = "{}/{}/nhrp_route.json".format(CWD, router.name) +    assertmsg = "No nhrp_route file found" +    assert os.path.isfile(json_file), assertmsg + +    expected = json.loads(open(json_file).read()) +    test_func = partial( +        topotest.router_json_cmp, router, "show ip route nhrp json", expected +    ) +    _, result = topotest.run_and_expect(test_func, None, count=40, wait=0.5) + +    output = router.vtysh_cmd("show ip route nhrp") +    logger.info(output) + +    assertmsg = '"{}" JSON output mismatches'.format(router.name) +    assert result is None, assertmsg + + +def test_memory_leak(): +    "Run the memory leak test and report results." +    tgen = get_topogen() +    if not tgen.is_memleak_enabled(): +        pytest.skip("Memory leak test/report is disabled") + +    tgen.report_memory_leaks() + + +if __name__ == "__main__": +    args = ["-s"] + sys.argv[1:] +    sys.exit(pytest.main(args))  | 
