--- /dev/null
+log timestamp precision 6
+log file frr.log
+
+no debug memstats-at-exit
+
+debug northbound notifications
+debug northbound libyang
+debug northbound events
+debug northbound callbacks
+
+debug mgmt backend datastore frontend transaction
+debug mgmt client frontend
+debug mgmt client backend
+
+interface r1-eth0
+ ip address 1.1.1.1/24
+ ipv6 address 2001:1111::1/64
+exit
+
+interface r1-eth1
+ ip address 2.2.2.1/24
+ ipv6 address 2002:2222::1/64
+exit
+
+interface r1-eth2 vrf red
+ ip address 3.3.3.1/24
+ ipv6 address 2003:333::1/64
+exit
+
+interface r1-eth3 vrf red
+ ip address 4.4.4.1/24
+ ipv6 address 2004:4444::1/64
+exit
+
+ip route 11.0.0.0/8 Null0
+ip route 11.11.11.11/32 1.1.1.2
+ip route 12.12.12.12/32 2.2.2.2
+
+ip route 13.0.0.0/8 Null0 vrf red
+ip route 13.13.13.13/32 3.3.3.2 vrf red
+ip route 14.14.14.14/32 4.4.4.2 vrf red
\ No newline at end of file
--- /dev/null
+#!/usr/bin/env python
+# -*- coding: utf-8 eval: (blacken-mode 1) -*-
+# SPDX-License-Identifier: ISC
+#
+# Copyright (c) 2025 Nvidia Inc.
+# Donald Sharp
+#
+"""
+Test zebra operational values
+"""
+
+import pytest
+import json
+from lib.topogen import Topogen
+from lib.topolog import logger
+
+
+pytestmark = [pytest.mark.mgmtd]
+
+
+@pytest.fixture(scope="module")
+def tgen(request):
+ "Setup/Teardown the environment and provide tgen argument to tests"
+
+ topodef = {"s1": ("r1",), "s2": ("r1",), "s3": ("r1",), "s4": ("r1",)}
+
+ tgen = Topogen(topodef, request.module.__name__)
+ tgen.start_topology()
+
+ router_list = tgen.routers()
+ for rname, router in router_list.items():
+ # Setup VRF red
+ router.net.add_l3vrf("red", 10)
+ router.net.add_loop("lo-red")
+ router.net.attach_iface_to_l3vrf("lo-red", "red")
+ router.net.attach_iface_to_l3vrf(rname + "-eth2", "red")
+ router.net.attach_iface_to_l3vrf(rname + "-eth3", "red")
+ router.load_frr_config("frr.conf")
+
+ tgen.start_router()
+ yield tgen
+ tgen.stop_topology()
+
+
+def test_zebra_operationalr(tgen):
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ r1 = tgen.gears["r1"]
+
+ output = json.loads(r1.vtysh_cmd("show mgmt get-data /frr-zebra:zebra"))
+
+ logger.info("Output")
+ logger.info(output)
+
+ logger.info("Ensuring that the max-multipath value is returned")
+ assert "max-multipath" in output["frr-zebra:zebra"].keys()
+
+
+if __name__ == "__main__":
+ # To suppress tracebacks, either use the following pytest call or add "--tb=no" to cli
+ # retval = pytest.main(["-s", "--tb=no"])
+ retval = pytest.main(["-s"])
+ sys.exit(retval)
container zebra {
description
"Data model for the Zebra daemon.";
+ leaf max-multipath {
+ config false;
+ type uint16 {
+ range "1..65535";
+ }
+ description
+ "The maximum number of nexthops for a route. At this point it
+ is unlikely that a multipath number will ever get larger then
+ 1024 but to allow for future expansions, the yang returns a
+ 16 bit number";
+ }
leaf ip-forwarding {
type boolean;
description
.name = "frr-zebra",
.features = features,
.nodes = {
+ {
+ .xpath = "/frr-zebra:zebra/max-multipath",
+ .cbs = {
+ .get_elem = zebra_max_multipath_get_elem,
+ }
+ },
{
.xpath = "/frr-zebra:zebra/ip-forwarding",
.cbs = {
extern const struct frr_yang_module_info frr_zebra_info;
/* prototypes */
+struct yang_data *zebra_max_multipath_get_elem(struct nb_cb_get_elem_args *args);
int get_route_information_rpc(struct nb_cb_rpc_args *args);
int get_v6_mroute_info_rpc(struct nb_cb_rpc_args *args);
int get_vrf_info_rpc(struct nb_cb_rpc_args *args);
return NULL;
}
+
+/*
+ * XPath:
+ * /frr-zebra:zebra/max-multipath
+ */
+struct yang_data *zebra_max_multipath_get_elem(struct nb_cb_get_elem_args *args)
+{
+ return yang_data_new_uint16(args->xpath, zrouter.multipath_num);
+}