]> git.proxmox.com Git - mirror_frr.git/commitdiff
tests: zebra netlink testcases
authorJakub Urbańczyk <xthaid@gmail.com>
Mon, 3 Aug 2020 18:23:56 +0000 (20:23 +0200)
committerJakub Urbańczyk <xthaid@gmail.com>
Mon, 10 Aug 2020 19:57:12 +0000 (21:57 +0200)
Signed-off-by: Jakub Urbańczyk <xthaid@gmail.com>
tests/topotests/zebra_netlink/__init__.py [new file with mode: 0644]
tests/topotests/zebra_netlink/r1/sharpd.conf [new file with mode: 0644]
tests/topotests/zebra_netlink/r1/v4_route.json [new file with mode: 0644]
tests/topotests/zebra_netlink/r1/zebra.conf [new file with mode: 0644]
tests/topotests/zebra_netlink/test_zebra_netlink.py [new file with mode: 0755]
zebra/kernel_netlink.c
zebra/kernel_netlink.h
zebra/zebra_vty.c

diff --git a/tests/topotests/zebra_netlink/__init__.py b/tests/topotests/zebra_netlink/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/zebra_netlink/r1/sharpd.conf b/tests/topotests/zebra_netlink/r1/sharpd.conf
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/zebra_netlink/r1/v4_route.json b/tests/topotests/zebra_netlink/r1/v4_route.json
new file mode 100644 (file)
index 0000000..61e9bb2
--- /dev/null
@@ -0,0 +1,2802 @@
+{
+  "2.1.3.7\/32":[
+    {
+      "prefix":"2.1.3.7\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.8\/32":[
+    {
+      "prefix":"2.1.3.8\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.9\/32":[
+    {
+      "prefix":"2.1.3.9\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.10\/32":[
+    {
+      "prefix":"2.1.3.10\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.11\/32":[
+    {
+      "prefix":"2.1.3.11\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.12\/32":[
+    {
+      "prefix":"2.1.3.12\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.13\/32":[
+    {
+      "prefix":"2.1.3.13\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.14\/32":[
+    {
+      "prefix":"2.1.3.14\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.15\/32":[
+    {
+      "prefix":"2.1.3.15\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.16\/32":[
+    {
+      "prefix":"2.1.3.16\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.17\/32":[
+    {
+      "prefix":"2.1.3.17\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.18\/32":[
+    {
+      "prefix":"2.1.3.18\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.19\/32":[
+    {
+      "prefix":"2.1.3.19\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.20\/32":[
+    {
+      "prefix":"2.1.3.20\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.21\/32":[
+    {
+      "prefix":"2.1.3.21\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.22\/32":[
+    {
+      "prefix":"2.1.3.22\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.23\/32":[
+    {
+      "prefix":"2.1.3.23\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.24\/32":[
+    {
+      "prefix":"2.1.3.24\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.25\/32":[
+    {
+      "prefix":"2.1.3.25\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.26\/32":[
+    {
+      "prefix":"2.1.3.26\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.27\/32":[
+    {
+      "prefix":"2.1.3.27\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.28\/32":[
+    {
+      "prefix":"2.1.3.28\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.29\/32":[
+    {
+      "prefix":"2.1.3.29\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.30\/32":[
+    {
+      "prefix":"2.1.3.30\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.31\/32":[
+    {
+      "prefix":"2.1.3.31\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.32\/32":[
+    {
+      "prefix":"2.1.3.32\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.33\/32":[
+    {
+      "prefix":"2.1.3.33\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.34\/32":[
+    {
+      "prefix":"2.1.3.34\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.35\/32":[
+    {
+      "prefix":"2.1.3.35\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.36\/32":[
+    {
+      "prefix":"2.1.3.36\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.37\/32":[
+    {
+      "prefix":"2.1.3.37\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.38\/32":[
+    {
+      "prefix":"2.1.3.38\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.39\/32":[
+    {
+      "prefix":"2.1.3.39\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.40\/32":[
+    {
+      "prefix":"2.1.3.40\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.41\/32":[
+    {
+      "prefix":"2.1.3.41\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.42\/32":[
+    {
+      "prefix":"2.1.3.42\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.43\/32":[
+    {
+      "prefix":"2.1.3.43\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.44\/32":[
+    {
+      "prefix":"2.1.3.44\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.45\/32":[
+    {
+      "prefix":"2.1.3.45\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.46\/32":[
+    {
+      "prefix":"2.1.3.46\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.47\/32":[
+    {
+      "prefix":"2.1.3.47\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.48\/32":[
+    {
+      "prefix":"2.1.3.48\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.49\/32":[
+    {
+      "prefix":"2.1.3.49\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.50\/32":[
+    {
+      "prefix":"2.1.3.50\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.51\/32":[
+    {
+      "prefix":"2.1.3.51\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.52\/32":[
+    {
+      "prefix":"2.1.3.52\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.53\/32":[
+    {
+      "prefix":"2.1.3.53\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.54\/32":[
+    {
+      "prefix":"2.1.3.54\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.55\/32":[
+    {
+      "prefix":"2.1.3.55\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.56\/32":[
+    {
+      "prefix":"2.1.3.56\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.57\/32":[
+    {
+      "prefix":"2.1.3.57\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.58\/32":[
+    {
+      "prefix":"2.1.3.58\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.59\/32":[
+    {
+      "prefix":"2.1.3.59\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.60\/32":[
+    {
+      "prefix":"2.1.3.60\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.61\/32":[
+    {
+      "prefix":"2.1.3.61\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.62\/32":[
+    {
+      "prefix":"2.1.3.62\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.63\/32":[
+    {
+      "prefix":"2.1.3.63\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.64\/32":[
+    {
+      "prefix":"2.1.3.64\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.65\/32":[
+    {
+      "prefix":"2.1.3.65\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.66\/32":[
+    {
+      "prefix":"2.1.3.66\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.67\/32":[
+    {
+      "prefix":"2.1.3.67\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.68\/32":[
+    {
+      "prefix":"2.1.3.68\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.69\/32":[
+    {
+      "prefix":"2.1.3.69\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.70\/32":[
+    {
+      "prefix":"2.1.3.70\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.71\/32":[
+    {
+      "prefix":"2.1.3.71\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.72\/32":[
+    {
+      "prefix":"2.1.3.72\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.73\/32":[
+    {
+      "prefix":"2.1.3.73\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.74\/32":[
+    {
+      "prefix":"2.1.3.74\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.75\/32":[
+    {
+      "prefix":"2.1.3.75\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.76\/32":[
+    {
+      "prefix":"2.1.3.76\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.77\/32":[
+    {
+      "prefix":"2.1.3.77\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.78\/32":[
+    {
+      "prefix":"2.1.3.78\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.79\/32":[
+    {
+      "prefix":"2.1.3.79\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.80\/32":[
+    {
+      "prefix":"2.1.3.80\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.81\/32":[
+    {
+      "prefix":"2.1.3.81\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.82\/32":[
+    {
+      "prefix":"2.1.3.82\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.83\/32":[
+    {
+      "prefix":"2.1.3.83\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.84\/32":[
+    {
+      "prefix":"2.1.3.84\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.85\/32":[
+    {
+      "prefix":"2.1.3.85\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.86\/32":[
+    {
+      "prefix":"2.1.3.86\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.87\/32":[
+    {
+      "prefix":"2.1.3.87\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.88\/32":[
+    {
+      "prefix":"2.1.3.88\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.89\/32":[
+    {
+      "prefix":"2.1.3.89\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.90\/32":[
+    {
+      "prefix":"2.1.3.90\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.91\/32":[
+    {
+      "prefix":"2.1.3.91\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.92\/32":[
+    {
+      "prefix":"2.1.3.92\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.93\/32":[
+    {
+      "prefix":"2.1.3.93\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.94\/32":[
+    {
+      "prefix":"2.1.3.94\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.95\/32":[
+    {
+      "prefix":"2.1.3.95\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.96\/32":[
+    {
+      "prefix":"2.1.3.96\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.97\/32":[
+    {
+      "prefix":"2.1.3.97\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.98\/32":[
+    {
+      "prefix":"2.1.3.98\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.99\/32":[
+    {
+      "prefix":"2.1.3.99\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.100\/32":[
+    {
+      "prefix":"2.1.3.100\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.101\/32":[
+    {
+      "prefix":"2.1.3.101\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.102\/32":[
+    {
+      "prefix":"2.1.3.102\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.103\/32":[
+    {
+      "prefix":"2.1.3.103\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.104\/32":[
+    {
+      "prefix":"2.1.3.104\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.105\/32":[
+    {
+      "prefix":"2.1.3.105\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ],
+  "2.1.3.106\/32":[
+    {
+      "prefix":"2.1.3.106\/32",
+      "protocol":"sharp",
+      "selected":true,
+      "destSelected":true,
+      "distance":150,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":9,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.1.1",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true,
+          "weight":1
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/zebra_netlink/r1/zebra.conf b/tests/topotests/zebra_netlink/r1/zebra.conf
new file mode 100644 (file)
index 0000000..786be19
--- /dev/null
@@ -0,0 +1,2 @@
+int r1-eth0
+  ip address 192.168.1.1/24
\ No newline at end of file
diff --git a/tests/topotests/zebra_netlink/test_zebra_netlink.py b/tests/topotests/zebra_netlink/test_zebra_netlink.py
new file mode 100755 (executable)
index 0000000..7b692c7
--- /dev/null
@@ -0,0 +1,131 @@
+#!/usr/bin/env python
+
+#
+# test_zebra_netlink.py
+#
+# Copyright (c) 2020 by
+#
+# Permission to use, copy, modify, and/or distribute this software
+# for any purpose with or without fee is hereby granted, provided
+# that the above copyright notice and this permission notice appear
+# in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NETDEF DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NETDEF BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
+# DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
+# WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+# ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
+# OF THIS SOFTWARE.
+#
+
+"""
+test_zebra_netlink.py: Test some basic interactions with kernel using Netlink
+
+"""
+
+import os
+import re
+import sys
+import pytest
+import json
+import platform
+from functools import partial
+
+# Save the Current Working Directory to find configuration files.
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# 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 shutdown_bringup_interface
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+#####################################################
+##
+##   Network Topology Definition
+##
+#####################################################
+
+
+class ZebraTopo(Topo):
+    "Test topology builder"
+
+    def build(self, *_args, **_opts):
+        "Build function"
+        tgen = get_topogen(self)
+
+        tgen.add_router("r1")
+
+        # Create a empty network for router 1
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+
+
+#####################################################
+##
+##   Tests starting
+##
+#####################################################
+
+
+def setup_module(mod):
+    "Sets up the pytest environment"
+    tgen = Topogen(ZebraTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+    for rname, router in router_list.iteritems():
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+
+        router.load_config(
+            TopoRouter.RD_SHARP, os.path.join(CWD, "{}/sharpd.conf".format(rname))
+        )
+
+    # Initialize all routers.
+    tgen.start_router()
+
+
+def teardown_module(_mod):
+    "Teardown the pytest environment"
+    tgen = get_topogen()
+
+    # This function tears down the whole topology.
+    tgen.stop_topology()
+
+
+def test_zebra_netlink_batching():
+    "Test the situation where dataplane fills netlink send buffer entirely."
+    logger.info(
+        "Test the situation where dataplane fills netlink send buffer entirely."
+    )
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        ptyest.skip("skipped because of preview test failure")
+    r1 = tgen.gears["r1"]
+
+    # Reduce the size of the buffer to hit the limit.
+    r1.vtysh_cmd("conf t\nzebra kernel netlink batch-tx-buf 256 256")
+
+    r1.vtysh_cmd("sharp install routes 2.1.3.7 nexthop 192.168.1.1 100")
+    json_file = "{}/r1/v4_route.json".format(CWD)
+    expected = json.loads(open(json_file).read())
+    test_func = partial(topotest.router_json_cmp, r1, "show ip route json", expected,)
+    _, result = topotest.run_and_expect(test_func, None, count=2, wait=0.5)
+    assertmsg = '"r1" JSON output mismatches'
+    assert result is None, assertmsg
+
+    r1.vtysh_cmd("sharp remove routes 2.1.3.7 100")
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index e6a4a3d9e214d5626e712a5eb3d6da88af305062..b04076b945f08d9cd96e4134e3525aa01236a242 100644 (file)
 #define RTPROT_MROUTED 17
 #endif
 
-#define NL_BATCH_TX_BUFSIZE (16 * NL_PKT_BUF_SIZE)
-
-/*
- * For every request sent to the kernel that has failed we get an error message,
- * which contains a standard netlink message header and the payload consisting
- * of an error code and the original netlink mesage. So the receiving buffer
- * must be at least as big as the transmitting buffer increased by some space
- * for headers.
- */
-#define NL_BATCH_RX_BUFSIZE (NL_BATCH_TX_BUFSIZE + NL_PKT_BUF_SIZE)
+#define NL_DEFAULT_BATCH_BUFSIZE (16 * NL_PKT_BUF_SIZE)
 
 /*
  * We limit the batch's size to a number smaller than the length of the
  * big enough (bigger than the biggest Netlink message) then this situation
  * won't occur.
  */
-#define NL_BATCH_SEND_THRESHOLD (NL_BATCH_TX_BUFSIZE - NL_PKT_BUF_SIZE)
+#define NL_DEFAULT_BATCH_SEND_THRESHOLD (15 * NL_PKT_BUF_SIZE)
+
+/*
+ * For every request sent to the kernel that has failed we get an error message,
+ * which contains a standard netlink message header and the payload consisting
+ * of an error code and the original netlink mesage. So the receiving buffer
+ * must be at least as big as the transmitting buffer increased by some space
+ * for headers.
+ */
+#define NL_BATCH_RX_BUFSIZE (NL_DEFAULT_BATCH_BUFSIZE + NL_PKT_BUF_SIZE)
 
 static const struct message nlmsg_str[] = {{RTM_NEWROUTE, "RTM_NEWROUTE"},
                                           {RTM_DELROUTE, "RTM_DELROUTE"},
@@ -172,9 +172,16 @@ extern uint32_t nl_rcvbufsize;
 
 extern struct zebra_privs_t zserv_privs;
 
-char nl_batch_tx_buf[NL_BATCH_TX_BUFSIZE];
+DEFINE_MTYPE_STATIC(ZEBRA, NL_BUF, "Zebra Netlink buffers")
+
+size_t nl_batch_tx_bufsize;
+char *nl_batch_tx_buf;
+
 char nl_batch_rx_buf[NL_BATCH_RX_BUFSIZE];
 
+_Atomic uint32_t nl_batch_bufsize = NL_DEFAULT_BATCH_BUFSIZE;
+_Atomic uint32_t nl_batch_send_threshold = NL_DEFAULT_BATCH_SEND_THRESHOLD;
+
 struct nl_batch {
        void *buf;
        size_t bufsiz;
@@ -195,6 +202,33 @@ struct nl_batch {
        struct dplane_ctx_q *ctx_out_q;
 };
 
+int netlink_config_write_helper(struct vty *vty)
+{
+       uint32_t size =
+               atomic_load_explicit(&nl_batch_bufsize, memory_order_relaxed);
+       uint32_t threshold = atomic_load_explicit(&nl_batch_send_threshold,
+                                                 memory_order_relaxed);
+
+       if (size != NL_DEFAULT_BATCH_BUFSIZE
+           || threshold != NL_DEFAULT_BATCH_SEND_THRESHOLD)
+               vty_out(vty, "zebra kernel netlink batch-tx-buf %u %u\n", size,
+                       threshold);
+
+       return 0;
+}
+
+void netlink_set_batch_buffer_size(uint32_t size, uint32_t threshold, bool set)
+{
+       if (!set) {
+               size = NL_DEFAULT_BATCH_BUFSIZE;
+               threshold = NL_DEFAULT_BATCH_SEND_THRESHOLD;
+       }
+
+       atomic_store_explicit(&nl_batch_bufsize, size, memory_order_relaxed);
+       atomic_store_explicit(&nl_batch_send_threshold, threshold,
+                             memory_order_relaxed);
+}
+
 int netlink_talk_filter(struct nlmsghdr *h, ns_id_t ns_id, int startup)
 {
        /*
@@ -1232,9 +1266,24 @@ static void nl_batch_reset(struct nl_batch *bth)
 
 static void nl_batch_init(struct nl_batch *bth, struct dplane_ctx_q *ctx_out_q)
 {
+       /*
+        * If the size of the buffer has changed, free and then allocate a new
+        * one.
+        */
+       size_t bufsize =
+               atomic_load_explicit(&nl_batch_bufsize, memory_order_relaxed);
+       if (bufsize != nl_batch_tx_bufsize) {
+               if (nl_batch_tx_buf)
+                       XFREE(MTYPE_NL_BUF, nl_batch_tx_buf);
+
+               nl_batch_tx_buf = XCALLOC(MTYPE_NL_BUF, bufsize);
+               nl_batch_tx_bufsize = bufsize;
+       }
+
        bth->buf = nl_batch_tx_buf;
-       bth->bufsiz = sizeof(nl_batch_tx_buf);
-       bth->limit = NL_BATCH_SEND_THRESHOLD;
+       bth->bufsiz = bufsize;
+       bth->limit = atomic_load_explicit(&nl_batch_send_threshold,
+                                         memory_order_relaxed);
 
        bth->ctx_out_q = ctx_out_q;
 
index 7f66f2b28c2f3fca621ad34eb8622c362a9fd321..c02e16480b423874bb7c81f06962cd3e103f4c31 100644 (file)
@@ -129,6 +129,17 @@ extern enum netlink_msg_status netlink_batch_add_msg(
        ssize_t (*msg_encoder)(struct zebra_dplane_ctx *, void *, size_t),
        bool ignore_res);
 
+/*
+ * Vty/cli apis
+ */
+extern int netlink_config_write_helper(struct vty *vty);
+
+/*
+ * Configure size of the batch buffer and sending threshold. If 'unset', reset
+ * to default value.
+ */
+extern void netlink_set_batch_buffer_size(uint32_t size, uint32_t threshold,
+                                         bool set);
 
 #endif /* HAVE_NETLINK */
 
index fc1eb6223df311ddd172e606da0e5ea6d8d1ec37..a7b992bbb5534ae0504c614566227d3882c06cd3 100644 (file)
@@ -57,6 +57,7 @@
 #include "zebra/interface.h"
 #include "northbound_cli.h"
 #include "zebra/zebra_nb.h"
+#include "zebra/kernel_netlink.h"
 
 extern int allow_delete;
 
@@ -3397,6 +3398,11 @@ static int config_write_protocol(struct vty *vty)
        if (!zebra_nhg_kernel_nexthops_enabled())
                vty_out(vty, "no zebra nexthop kernel enable\n");
 
+#ifdef HAVE_NETLINK
+       /* Include netlink info */
+       netlink_config_write_helper(vty);
+#endif /* HAVE_NETLINK */
+
        return 1;
 }
 
@@ -3719,6 +3725,44 @@ DEFUN_HIDDEN (show_frr,
        return CMD_SUCCESS;
 }
 
+#ifdef HAVE_NETLINK
+DEFUN_HIDDEN(zebra_kernel_netlink_batch_tx_buf,
+            zebra_kernel_netlink_batch_tx_buf_cmd,
+            "zebra kernel netlink batch-tx-buf (1-1048576) (1-1048576)",
+            ZEBRA_STR
+            "Zebra kernel interface\n"
+            "Set Netlink parameters\n"
+            "Set batch buffer size and send threshold\n"
+            "Size of the buffer\n"
+            "Send threshold\n")
+{
+       uint32_t bufsize = 0, threshold = 0;
+
+       bufsize = strtoul(argv[4]->arg, NULL, 10);
+       threshold = strtoul(argv[5]->arg, NULL, 10);
+
+       netlink_set_batch_buffer_size(bufsize, threshold, true);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN_HIDDEN(no_zebra_kernel_netlink_batch_tx_buf,
+            no_zebra_kernel_netlink_batch_tx_buf_cmd,
+            "no zebra kernel netlink batch-tx-buf [(0-1048576)] [(0-1048576)]",
+            NO_STR ZEBRA_STR
+            "Zebra kernel interface\n"
+            "Set Netlink parameters\n"
+            "Set batch buffer size and send threshold\n"
+            "Size of the buffer\n"
+            "Send threshold\n")
+{
+       netlink_set_batch_buffer_size(0, 0, false);
+
+       return CMD_SUCCESS;
+}
+
+#endif /* HAVE_NETLINK */
+
 /* IP node for static routes. */
 static int zebra_ip_config(struct vty *vty);
 static struct cmd_node ip_node = {
@@ -3856,5 +3900,10 @@ void zebra_vty_init(void)
        install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
        install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
 
+#ifdef HAVE_NETLINK
+       install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd);
+       install_element(CONFIG_NODE, &no_zebra_kernel_netlink_batch_tx_buf_cmd);
+#endif /* HAVE_NETLINK */
+
        install_element(VIEW_NODE, &zebra_show_routing_tables_summary_cmd);
 }