]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #5722 from donaldsharp/kernel_routes
authorRuss White <russ@riw.us>
Thu, 6 Feb 2020 13:04:42 +0000 (08:04 -0500)
committerGitHub <noreply@github.com>
Thu, 6 Feb 2020 13:04:42 +0000 (08:04 -0500)
Kernel routes

tests/topotests/zebra_rib/r1/v4_route_1.json [new file with mode: 0644]
tests/topotests/zebra_rib/r1/v4_route_1_static_override.json [new file with mode: 0644]
tests/topotests/zebra_rib/r1/v4_route_2.json [new file with mode: 0644]
tests/topotests/zebra_rib/r1/zebra.conf [new file with mode: 0644]
tests/topotests/zebra_rib/test_zebra_rib.py [new file with mode: 0755]
zebra/zebra_rib.c

diff --git a/tests/topotests/zebra_rib/r1/v4_route_1.json b/tests/topotests/zebra_rib/r1/v4_route_1.json
new file mode 100644 (file)
index 0000000..3a77bda
--- /dev/null
@@ -0,0 +1,29 @@
+{
+  "4.5.1.0\/24":[
+    {
+      "prefix":"4.5.1.0\/24",
+      "protocol":"kernel",
+      "selected":true,
+      "destSelected":true,
+      "distance":255,
+      "metric":8192,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":8,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.210.2",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/zebra_rib/r1/v4_route_1_static_override.json b/tests/topotests/zebra_rib/r1/v4_route_1_static_override.json
new file mode 100644 (file)
index 0000000..aa9522a
--- /dev/null
@@ -0,0 +1,52 @@
+{
+  "4.5.1.0\/24":[
+    {
+      "prefix":"4.5.1.0\/24",
+      "protocol":"static",
+      "selected":true,
+      "destSelected":true,
+      "distance":1,
+      "metric":0,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":72,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.216.3",
+          "afi":"ipv4",
+          "interfaceIndex":8,
+          "interfaceName":"r1-eth6",
+          "active":true
+        }
+      ]
+    },
+    {
+      "prefix":"4.5.1.0\/24",
+      "protocol":"kernel",
+      "distance":255,
+      "metric":8192,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":0,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.210.2",
+          "afi":"ipv4",
+          "interfaceIndex":2,
+          "interfaceName":"r1-eth0",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/zebra_rib/r1/v4_route_2.json b/tests/topotests/zebra_rib/r1/v4_route_2.json
new file mode 100644 (file)
index 0000000..02c3878
--- /dev/null
@@ -0,0 +1,29 @@
+{
+  "4.5.2.0\/24":[
+    {
+      "prefix":"4.5.2.0\/24",
+      "protocol":"kernel",
+      "selected":true,
+      "destSelected":true,
+      "distance":1,
+      "metric":1,
+      "installed":true,
+      "table":254,
+      "internalStatus":16,
+      "internalFlags":8,
+      "internalNextHopNum":1,
+      "internalNextHopActiveNum":1,
+      "nexthops":[
+        {
+          "flags":3,
+          "fib":true,
+          "ip":"192.168.211.2",
+          "afi":"ipv4",
+          "interfaceIndex":3,
+          "interfaceName":"r1-eth1",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/zebra_rib/r1/zebra.conf b/tests/topotests/zebra_rib/r1/zebra.conf
new file mode 100644 (file)
index 0000000..b914f2d
--- /dev/null
@@ -0,0 +1,26 @@
+hostname r1
+!
+interface r1-eth0
+  ip address 192.168.210.1/24
+!
+interface r1-eth1
+  ip address 192.168.211.1/24
+!
+interface r1-eth2
+  ip address 192.168.212.1/24
+!
+interface r1-eth3
+  ip address 192.168.213.1/24
+!
+interface r1-eth4
+  ip address 192.168.214.1/24
+!
+interface r1-eth5
+  ip address 192.168.215.1/24
+!
+interface r1-eth6
+  ip address 192.168.216.1/24
+!
+interface r1-eth7
+  ip address 192.168.217.1/24
+!
diff --git a/tests/topotests/zebra_rib/test_zebra_rib.py b/tests/topotests/zebra_rib/test_zebra_rib.py
new file mode 100755 (executable)
index 0000000..d73f613
--- /dev/null
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+#
+# test_zebra_rib.py
+#
+# Copyright (c) 2019 by
+# Cumulus Networks, Inc
+# Donald Sharp
+#
+# 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_rib.py: Test some basic zebra <-> kernel interactions
+"""
+
+import os
+import re
+import sys
+from functools import partial
+import pytest
+import json
+
+# 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
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+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'])
+        switch.add_link(tgen.gears['r1'])
+        switch.add_link(tgen.gears['r1'])
+        switch.add_link(tgen.gears['r1'])
+        switch.add_link(tgen.gears['r1'])
+        switch.add_link(tgen.gears['r1'])
+        switch.add_link(tgen.gears['r1'])
+        switch.add_link(tgen.gears['r1'])
+
+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))
+        )
+
+    # Initialize all routers.
+    tgen.start_router()
+
+def teardown_module(mod):
+    "Teardown the pytest environment"
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+def test_zebra_kernel_admin_distance():
+    "Test some basic kernel routes added that should be accepted"
+    logger.info("Test some basic kernel routes that should be accepted")
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip('skipped because of router(s) failure')
+
+    r1 = tgen.gears['r1']
+
+    # Route with 255/8192 metric
+    r1.run('ip route add 4.5.1.0/24 via 192.168.210.2 dev r1-eth0 metric 4278198272')
+    # Route with 1/1 metric
+    r1.run('ip route add 4.5.2.0/24 via 192.168.211.2 dev r1-eth1 metric 16777217')
+    # Route with 10/1 metric
+    r1.run('ip route add 4.5.3.0/24 via 192.168.212.2 dev r1-eth2 metric 167772161')
+    # Same route with a 160/1 metric
+    r1.run('ip route add 4.5.3.0/24 via 192.168.213.2 dev r1-eth3 metric 2684354561')
+
+    #Currently I believe we have a bug here with the same route and different
+    #metric.  That needs to be properly resolved.  Making a note for
+    #coming back around later and fixing this.
+    #tgen.mininet_cli()
+    for i in range(1, 2):
+        json_file = '{}/r1/v4_route_{}.json'.format(CWD, i)
+        expected = json.loads(open(json_file).read())
+
+        test_func = partial(topotest.router_json_cmp,
+                            r1,
+                            'show ip route 4.5.{}.0 json'.format(i),
+                            expected)
+        _, result = topotest.run_and_expect(test_func, None, count=2, wait=.5)
+        assertmsg = '"r1" JSON output mismatches'
+        assert result is None, assertmsg
+    #tgen.mininet_cli()
+
+def test_zebra_kernel_override():
+    "Test that a FRR route with a lower admin distance takes over"
+    logger.info("Test kernel override with a better admin distance")
+    tgen = get_topogen()
+    if (tgen.routers_have_failure()):
+        ptyest.skip("skipped because of preview test failure")
+
+    r1 = tgen.gears['r1']
+    r1.vtysh_cmd("conf\nip route 4.5.1.0/24 192.168.216.3")
+    json_file = '{}/r1/v4_route_1_static_override.json'.format(CWD)
+    expected = json.loads(open(json_file).read())
+
+    test_func = partial(topotest.router_json_cmp,
+                        r1, 'show ip route 4.5.1.0 json', expected)
+    _, result = topotest.run_and_expect(test_func, None, count=2, wait=.5)
+    assert result is None, '"r1" JSON output mismatches'
+
+    logger.info("Test that the removal of the static route allows the kernel to take back over")
+    r1.vtysh_cmd("conf\nno ip route 4.5.1.0/24 192.168.216.3")
+    json_file = '{}/r1/v4_route_1.json'.format(CWD)
+    expected = json.loads(open(json_file).read())
+
+    test_func = partial(topotest.router_json_cmp,
+                        r1, 'show ip route 4.5.1.0 json', expected)
+    _, result = topotest.run_and_expect(test_func, None, count=2, wait=.5)
+    assert result is None, '"r1" JSON output mismatches'
+
+
+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))
index 6276a5d8b30961ba022d48430a2babfaf74302b0..f3112cc9c039bd564819e75cd8190fe60d529d95 100644 (file)
@@ -1075,7 +1075,8 @@ static void rib_process(struct route_node *rn)
                }
 
                /* Infinite distance. */
-               if (re->distance == DISTANCE_INFINITY) {
+               if (re->distance == DISTANCE_INFINITY &&
+                   re->type != ZEBRA_ROUTE_KERNEL) {
                        UNSET_FLAG(re->status, ROUTE_ENTRY_CHANGED);
                        continue;
                }