]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #7137 from kssoman/ospf
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 5 Nov 2020 16:57:50 +0000 (11:57 -0500)
committerGitHub <noreply@github.com>
Thu, 5 Nov 2020 16:57:50 +0000 (11:57 -0500)
ospf6d : Intra area route for connected prefix not installed

999 files changed:
.git-blame-ignore-revs
.github/ISSUE_TEMPLATE/bug_report.md
alpine/APKBUILD.in
babeld/babel_filter.c
babeld/babel_interface.c
babeld/babel_zebra.c
babeld/babeld.c
bfdd/control.c
bfdd/ptm_adapter.c
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_attr_evpn.c
bgpd/bgp_attr_evpn.h
bgpd/bgp_bfd.c
bgpd/bgp_bmp.h
bgpd/bgp_btoa.c
bgpd/bgp_conditional_adv.c [new file with mode: 0644]
bgpd/bgp_conditional_adv.h [new file with mode: 0644]
bgpd/bgp_damp.c
bgpd/bgp_debug.c
bgpd/bgp_dump.c
bgpd/bgp_ecommunity.c
bgpd/bgp_ecommunity.h
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_evpn_mh.c
bgpd/bgp_evpn_mh.h
bgpd/bgp_evpn_private.h
bgpd/bgp_evpn_vty.c
bgpd/bgp_evpn_vty.h
bgpd/bgp_filter.c
bgpd/bgp_flowspec_util.c
bgpd/bgp_fsm.c
bgpd/bgp_fsm.h
bgpd/bgp_io.c
bgpd/bgp_label.c
bgpd/bgp_main.c
bgpd/bgp_mpath.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_mplsvpn.h
bgpd/bgp_nb.c [new file with mode: 0644]
bgpd/bgp_nb.h [new file with mode: 0644]
bgpd/bgp_nb_config.c [new file with mode: 0644]
bgpd/bgp_nexthop.c
bgpd/bgp_nht.c
bgpd/bgp_packet.c
bgpd/bgp_pbr.c
bgpd/bgp_rd.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_routemap.c
bgpd/bgp_rpki.c
bgpd/bgp_table.c
bgpd/bgp_table.h
bgpd/bgp_trace.c [new file with mode: 0644]
bgpd/bgp_trace.h [new file with mode: 0644]
bgpd/bgp_updgrp.c
bgpd/bgp_updgrp_adv.c
bgpd/bgp_updgrp_packet.c
bgpd/bgp_vpn.c
bgpd/bgp_vty.c
bgpd/bgp_vty.h
bgpd/bgp_zebra.c
bgpd/bgpd.c
bgpd/bgpd.h
bgpd/rfapi/bgp_rfapi_cfg.c
bgpd/rfapi/rfapi.c
bgpd/rfapi/rfapi_import.c
bgpd/rfapi/rfapi_monitor.c
bgpd/rfapi/rfapi_rib.c
bgpd/rfapi/rfapi_vty.c
bgpd/rfapi/vnc_export_bgp.c
bgpd/rfapi/vnc_import_bgp.c
bgpd/rfapi/vnc_zebra.c
bgpd/subdir.am
configure.ac
doc/developer/conf.py
doc/developer/index.rst
doc/developer/logging.rst
doc/developer/tracing.rst [new file with mode: 0644]
doc/developer/workflow.rst
doc/extra/frrlexer.py
doc/manpages/conf.py
doc/manpages/frr-zebra.rst
doc/user/bgp.rst
doc/user/conf.py
doc/user/installation.rst
doc/user/isisd.rst
doc/user/ospfd.rst
doc/user/pim.rst
doc/user/snmp.rst
doc/user/zebra.rst
eigrpd/eigrp_dump.c
eigrpd/eigrp_dump.h
eigrpd/eigrp_filter.c
eigrpd/eigrp_fsm.c
eigrpd/eigrp_hello.c
eigrpd/eigrp_interface.c
eigrpd/eigrp_neighbor.c
eigrpd/eigrp_network.c
eigrpd/eigrp_northbound.c
eigrpd/eigrp_packet.c
eigrpd/eigrp_reply.c
eigrpd/eigrp_topology.c
eigrpd/eigrp_update.c
eigrpd/eigrp_vty.c
eigrpd/eigrp_zebra.c
eigrpd/eigrpd.c
isisd/fabricd.c
isisd/isis_adjacency.c
isisd/isis_circuit.c
isisd/isis_circuit.h
isisd/isis_cli.c
isisd/isis_csm.c
isisd/isis_dr.c
isisd/isis_events.c
isisd/isis_ldp_sync.c
isisd/isis_lfa.c [new file with mode: 0644]
isisd/isis_lfa.h [new file with mode: 0644]
isisd/isis_lsp.c
isisd/isis_memory.c
isisd/isis_memory.h
isisd/isis_nb.c
isisd/isis_nb.h
isisd/isis_nb_config.c
isisd/isis_pdu.c
isisd/isis_redist.c
isisd/isis_route.c
isisd/isis_route.h
isisd/isis_spf.c
isisd/isis_spf.h
isisd/isis_spf_private.h
isisd/isis_sr.c
isisd/isis_sr.h
isisd/isis_te.c
isisd/isis_tlvs.c
isisd/isis_tlvs.h
isisd/isis_tx_queue.c
isisd/isis_zebra.c
isisd/isis_zebra.h
isisd/isisd.c
isisd/isisd.h
isisd/subdir.am
ldpd/accept.c
ldpd/address.c
ldpd/adjacency.c
ldpd/control.c
ldpd/hello.c
ldpd/init.c
ldpd/interface.c
ldpd/keepalive.c
ldpd/labelmapping.c
ldpd/lde.c
ldpd/lde_lib.c
ldpd/ldp_vty_conf.c
ldpd/ldp_vty_exec.c
ldpd/ldp_zebra.c
ldpd/ldpd.c
ldpd/ldpe.c
ldpd/logmsg.c
ldpd/neighbor.c
ldpd/notification.c
ldpd/packet.c
lib/agentx.c
lib/agg_table.h
lib/command.c
lib/command.h
lib/filter.c
lib/filter_cli.c
lib/filter_nb.c
lib/frr_pthread.c
lib/frr_zmq.c
lib/hash.c
lib/if.c
lib/json.c
lib/json.h
lib/ldp_sync.c
lib/libfrr_trace.c [new file with mode: 0644]
lib/libfrr_trace.h [new file with mode: 0644]
lib/linklist.c
lib/memory.c
lib/nexthop.c
lib/nexthop.h
lib/nexthop_group.c
lib/northbound.c
lib/northbound.h
lib/northbound_cli.c
lib/northbound_cli.h
lib/northbound_confd.c
lib/northbound_grpc.cpp
lib/northbound_sysrepo.c
lib/plist.c
lib/prefix.c
lib/prefix.h
lib/routemap.c
lib/sigevent.c
lib/sigevent.h
lib/sockunion.c
lib/spf_backoff.c
lib/stream.h
lib/subdir.am
lib/table.c
lib/table.h
lib/thread.c
lib/thread.h
lib/trace.h [new file with mode: 0644]
lib/vxlan.h
lib/workqueue.c
lib/yang.c
lib/yang.h
lib/yang_translator.c
lib/zassert.h
lib/zclient.c
lib/zclient.h
lib/zlog.c
nhrpd/README.nhrpd
nhrpd/netlink_arp.c
nhrpd/nhrp_interface.c
nhrpd/nhrp_nhs.c
nhrpd/nhrp_route.c
nhrpd/nhrp_shortcut.c
nhrpd/nhrp_vty.c
nhrpd/vici.c
ospf6d/ospf6_abr.c
ospf6d/ospf6_abr.h
ospf6d/ospf6_area.c
ospf6d/ospf6_area.h
ospf6d/ospf6_asbr.c
ospf6d/ospf6_asbr.h
ospf6d/ospf6_bfd.c
ospf6d/ospf6_flood.c
ospf6d/ospf6_interface.c
ospf6d/ospf6_intra.c
ospf6d/ospf6_lsa.c
ospf6d/ospf6_lsa.h
ospf6d/ospf6_lsdb.c
ospf6d/ospf6_lsdb.h
ospf6d/ospf6_main.c
ospf6d/ospf6_message.c
ospf6d/ospf6_neighbor.c
ospf6d/ospf6_network.c
ospf6d/ospf6_network.h
ospf6d/ospf6_route.c
ospf6d/ospf6_route.h
ospf6d/ospf6_snmp.c
ospf6d/ospf6_spf.c
ospf6d/ospf6_spf.h
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospf6d/ospf6d.c
ospf6d/ospf6d.h
ospfclient/ospf_apiclient.c
ospfclient/ospfclient.c
ospfd/ospf_abr.c
ospfd/ospf_apiserver.c
ospfd/ospf_asbr.c
ospfd/ospf_asbr.h
ospfd/ospf_ase.c
ospfd/ospf_bfd.c
ospfd/ospf_dump.c
ospfd/ospf_dump.h
ospfd/ospf_dump_api.c
ospfd/ospf_ext.c
ospfd/ospf_flood.c
ospfd/ospf_gr_helper.c [new file with mode: 0644]
ospfd/ospf_gr_helper.h [new file with mode: 0644]
ospfd/ospf_ia.c
ospfd/ospf_interface.c
ospfd/ospf_ism.c
ospfd/ospf_ism.h
ospfd/ospf_ldp_sync.c
ospfd/ospf_lsa.c
ospfd/ospf_lsa.h
ospfd/ospf_memory.c
ospfd/ospf_memory.h
ospfd/ospf_neighbor.c
ospfd/ospf_neighbor.h
ospfd/ospf_network.c
ospfd/ospf_nsm.c
ospfd/ospf_nsm.h
ospfd/ospf_opaque.c
ospfd/ospf_opaque.h
ospfd/ospf_packet.c
ospfd/ospf_packet.h
ospfd/ospf_ri.c
ospfd/ospf_route.c
ospfd/ospf_snmp.c
ospfd/ospf_spf.c
ospfd/ospf_sr.c
ospfd/ospf_sr.h
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospfd.c
ospfd/ospfd.h
ospfd/subdir.am
pbrd/pbr_main.c
pbrd/pbr_nht.c
pbrd/pbr_vrf.c
pbrd/pbr_vrf.h
pbrd/pbr_vty.c
pbrd/pbr_zebra.c
pbrd/pbr_zebra.h
pimd/mtracebis.c
pimd/pim_bfd.c
pimd/pim_bsm.c
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_ifchannel.c
pimd/pim_igmp.c
pimd/pim_igmp_mtrace.c
pimd/pim_igmpv3.c
pimd/pim_join.c
pimd/pim_mlag.c
pimd/pim_msdp.c
pimd/pim_msdp.h
pimd/pim_msdp_packet.c
pimd/pim_msdp_packet.h
pimd/pim_neighbor.c
pimd/pim_nht.c
pimd/pim_register.c
pimd/pim_rp.c
pimd/pim_upstream.c
pimd/pim_zebra.c
python/callgraph-dot.py
python/clidef.py
python/clippy/__init__.py
python/firstheader.py
python/makefile.py
python/makevars.py
redhat/frr.spec.in
ripd/rip_cli.c
ripd/rip_interface.c
ripd/rip_peer.c
ripd/rip_zebra.c
ripd/ripd.c
ripd/ripd.h
ripngd/ripng_cli.c
ripngd/ripng_debug.c
ripngd/ripng_interface.c
ripngd/ripng_nb_config.c
ripngd/ripng_peer.c
ripngd/ripngd.c
ripngd/ripngd.h
sharpd/sharp_nht.c
sharpd/sharp_vty.c
staticd/static_routes.c
staticd/static_vty.c
staticd/static_zebra.c
tests/bgpd/test_aspath.py
tests/bgpd/test_bgp_table.c
tests/bgpd/test_bgp_table.py
tests/bgpd/test_capability.py
tests/bgpd/test_ecommunity.py
tests/bgpd/test_mp_attr.py
tests/bgpd/test_mpath.py
tests/bgpd/test_peer_attr.c
tests/bgpd/test_peer_attr.py
tests/helpers/python/frrsix.py
tests/helpers/python/frrtest.py
tests/isisd/test_common.c
tests/isisd/test_fuzz_isis_tlv.py
tests/isisd/test_isis_lspdb.py
tests/isisd/test_isis_spf.c
tests/isisd/test_isis_spf.in
tests/isisd/test_isis_spf.py
tests/isisd/test_isis_spf.refout
tests/isisd/test_isis_vertex_queue.py
tests/lib/cli/test_cli.c
tests/lib/cli/test_cli.py
tests/lib/cli/test_commands.py
tests/lib/northbound/test_oper_data.py
tests/lib/test_atomlist.py
tests/lib/test_graph.py
tests/lib/test_idalloc.py
tests/lib/test_nexthop_iter.py
tests/lib/test_ntop.py
tests/lib/test_prefix2str.py
tests/lib/test_printfrr.py
tests/lib/test_ringbuf.py
tests/lib/test_srcdest_table.c
tests/lib/test_srcdest_table.py
tests/lib/test_stream.py
tests/lib/test_table.c
tests/lib/test_table.py
tests/lib/test_timer_correctness.c
tests/lib/test_timer_correctness.py
tests/lib/test_timer_performance.c
tests/lib/test_ttable.py
tests/lib/test_typelist.py
tests/lib/test_versioncmp.py
tests/lib/test_zlog.py
tests/lib/test_zmq.py
tests/ospf6d/test_lsdb.c
tests/ospf6d/test_lsdb.py
tests/runtests.py
tests/subdir.am
tests/topotests/all-protocol-startup/test_all_protocol_startup.py
tests/topotests/bfd-isis-topo1/rt1/isisd.conf
tests/topotests/bfd-isis-topo1/rt2/isisd.conf
tests/topotests/bfd-isis-topo1/rt3/isisd.conf
tests/topotests/bfd-isis-topo1/rt4/isisd.conf
tests/topotests/bfd-isis-topo1/rt5/isisd.conf
tests/topotests/bfd-profiles-topo1/r3/isisd.conf
tests/topotests/bfd-profiles-topo1/r4/isisd.conf
tests/topotests/bfd-profiles-topo1/test_bfd_profiles_topo1.py
tests/topotests/bfd-topo3/test_bfd_topo3.py
tests/topotests/bgp-auth/test_bgp_auth.py
tests/topotests/bgp-basic-functionality-topo1/test_bgp_basic_functionality.py
tests/topotests/bgp-ecmp-topo2/test_ebgp_ecmp_topo2.py
tests/topotests/bgp-ecmp-topo2/test_ibgp_ecmp_topo2.py
tests/topotests/bgp-evpn-mh/test_evpn_mh.py
tests/topotests/bgp-evpn-mh/torm11/zebra.conf
tests/topotests/bgp-evpn-mh/torm12/zebra.conf
tests/topotests/bgp-evpn-mh/torm21/zebra.conf
tests/topotests/bgp-evpn-mh/torm22/evpn.conf
tests/topotests/bgp-evpn-mh/torm22/zebra.conf
tests/topotests/bgp-evpn-vxlan_topo1/test_bgp_evpn_vxlan.py [changed mode: 0644->0755]
tests/topotests/bgp-vrf-route-leak-basic/test_bgp-vrf-route-leak-basic.py
tests/topotests/bgp_aggregate_address_topo1/__init__.py [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/exabgp.env [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/peer1/exabgp.cfg [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py [new file with mode: 0644]
tests/topotests/bgp_as_allow_in/test_bgp_as_allow_in.py
tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json [new file with mode: 0644]
tests/topotests/bgp_communities_topo1/test_bgp_communities.py
tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/__init__.py [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/r3/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py [new file with mode: 0644]
tests/topotests/bgp_default-route/__init__.py [new file with mode: 0644]
tests/topotests/bgp_default-route/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route/test_bgp_default-originate.py [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map/__init__.py [deleted file]
tests/topotests/bgp_default-route_route-map/r1/bgpd.conf [deleted file]
tests/topotests/bgp_default-route_route-map/r1/zebra.conf [deleted file]
tests/topotests/bgp_default-route_route-map/r2/bgpd.conf [deleted file]
tests/topotests/bgp_default-route_route-map/r2/zebra.conf [deleted file]
tests/topotests/bgp_default-route_route-map/test_bgp_default-originate_route-map.py [deleted file]
tests/topotests/bgp_default-route_route-map_match/__init__.py [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match/test_bgp_default-originate_route-map_match.py [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match_set/__init__.py [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match_set/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match_set/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match_set/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match_set/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_match_set/test_bgp_default-originate_route-map_match_set.py [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_set/__init__.py [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_set/r1/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_set/r1/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_set/r2/bgpd.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_set/r2/zebra.conf [new file with mode: 0644]
tests/topotests/bgp_default-route_route-map_set/test_bgp_default-originate_route-map_set.py [new file with mode: 0644]
tests/topotests/bgp_ebgp_requires_policy/test_bgp_ebgp_requires_policy.py
tests/topotests/bgp_evpn_rt5/test_bgp_evpn.py
tests/topotests/bgp_features/test_bgp_features.py
tests/topotests/bgp_flowspec/test_bgp_flowspec_topo.py
tests/topotests/bgp_gr_functionality_topo1/test_bgp_gr_functionality_topo1.py
tests/topotests/bgp_gr_functionality_topo2/test_bgp_gr_functionality_topo2.py
tests/topotests/bgp_gshut/test_bgp_gshut.py
tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/bgpd.conf
tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/bgpd.conf
tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf
tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf
tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py
tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/scale_down.py
tests/topotests/bgp_large_community/test_bgp_large_community_topo_1.py
tests/topotests/bgp_large_community/test_bgp_large_community_topo_2.py
tests/topotests/bgp_link_bw_ip/test_bgp_linkbw_ip.py
tests/topotests/bgp_multi_vrf_topo1/test_bgp_multi_vrf_topo1.py
tests/topotests/bgp_multi_vrf_topo2/test_bgp_multi_vrf_topo2.py
tests/topotests/bgp_recursive_route_ebgp_multi_hop/test_bgp_recursive_route_ebgp_multi_hop.py
tests/topotests/bgp_update_delay/test_bgp_update_delay.py
tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo1.py
tests/topotests/bgp_vrf_dynamic_route_leak/test_bgp_vrf_dynamic_route_leak_topo2.py
tests/topotests/evpn_type5_test_topo1/test_evpn_type5_chaos_topo1.py
tests/topotests/evpn_type5_test_topo1/test_evpn_type5_topo1.py
tests/topotests/isis-sr-topo1/rt1/isisd.conf
tests/topotests/isis-sr-topo1/rt1/step1/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step1/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step1/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt1/step10/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step10/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step10/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step2/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step2/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step2/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step3/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step3/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step3/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step4/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step4/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step4/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step5/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step5/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step5/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step6/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step6/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step6/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step7/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step7/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step7/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step8/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step8/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step8/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt1/step9/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt1/step9/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt1/step9/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/isisd.conf
tests/topotests/isis-sr-topo1/rt2/step1/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step1/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step1/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt2/step10/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step10/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step10/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step2/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step2/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step2/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step3/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step3/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step3/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step4/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step4/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step4/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step5/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step5/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step5/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step6/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step6/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step6/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step7/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step7/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step7/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step8/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step8/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step8/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt2/step9/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt2/step9/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt2/step9/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/isisd.conf
tests/topotests/isis-sr-topo1/rt3/step1/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step1/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step1/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt3/step10/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step10/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step10/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step2/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step2/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step2/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step3/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step3/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step3/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step4/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step4/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step4/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step5/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step5/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step5/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step6/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step6/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step6/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step7/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step7/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step7/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step8/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step8/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step8/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt3/step9/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt3/step9/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt3/step9/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/isisd.conf
tests/topotests/isis-sr-topo1/rt4/step1/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step1/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step1/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt4/step10/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step10/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step10/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step2/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step2/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step2/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step2/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt4/step3/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step3/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step3/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step3/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt4/step4/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step4/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step4/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step5/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step5/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step5/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step6/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step6/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step6/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step7/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step7/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step7/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step8/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step8/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step8/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/step9/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt4/step9/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt4/step9/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt4/zebra.conf
tests/topotests/isis-sr-topo1/rt5/isisd.conf
tests/topotests/isis-sr-topo1/rt5/step1/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step1/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt5/step10/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step10/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step2/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step2/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step2/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt5/step3/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step3/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step3/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt5/step4/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step4/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step4/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt5/step5/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step5/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step6/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step6/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step7/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step7/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step8/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step8/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/step9/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step9/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt5/zebra.conf
tests/topotests/isis-sr-topo1/rt6/isisd.conf
tests/topotests/isis-sr-topo1/rt6/step1/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step1/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step1/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref
tests/topotests/isis-sr-topo1/rt6/step10/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step10/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step10/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step2/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step2/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step2/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step4/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step4/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step4/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step5/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step5/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step5/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step6/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step6/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step6/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step7/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step7/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step7/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step8/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step8/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step8/show_mpls_table.ref
tests/topotests/isis-sr-topo1/rt6/step9/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt6/step9/show_ipv6_route.ref
tests/topotests/isis-sr-topo1/rt6/step9/show_mpls_table.ref
tests/topotests/isis-sr-topo1/test_isis_sr_topo1.py
tests/topotests/isis-tilfa-topo1/__init__.py [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/isisd.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step1/show_mpls_table.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step2/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step2/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step2/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step3/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step3/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step3/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step4/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step6/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step6/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step6/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt1/zebra.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/isisd.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step6/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step6/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step6/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt2/zebra.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/isisd.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step2/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step2/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step2/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step3/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step3/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step3/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt3/zebra.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/isisd.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step2/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step2/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step2/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step3/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step3/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step3/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step9/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step9/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt4/zebra.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/isisd.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step2/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step2/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step2/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step3/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step3/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step3/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step6/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step6/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step7/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step7/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step7/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step8/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step8/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step8/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step9/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step9/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/step9/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt5/zebra.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/isisd.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step2/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step2/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step2/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step3/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step3/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step3/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step9/show_ip_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step9/show_ipv6_route.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/rt6/zebra.conf [new file with mode: 0644]
tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py [new file with mode: 0755]
tests/topotests/isis-topo1-vrf/r1/isisd.conf
tests/topotests/isis-topo1-vrf/r1/r1_route.json
tests/topotests/isis-topo1-vrf/r2/isisd.conf
tests/topotests/isis-topo1-vrf/r2/r2_route.json
tests/topotests/isis-topo1-vrf/r3/isisd.conf
tests/topotests/isis-topo1-vrf/r3/r3_route.json
tests/topotests/isis-topo1-vrf/r4/isisd.conf
tests/topotests/isis-topo1-vrf/r4/r4_route.json
tests/topotests/isis-topo1-vrf/r5/isisd.conf
tests/topotests/isis-topo1-vrf/test_isis_topo1_vrf.py
tests/topotests/isis-topo1/r1/isisd.conf
tests/topotests/isis-topo1/r1/r1_route.json
tests/topotests/isis-topo1/r2/isisd.conf
tests/topotests/isis-topo1/r2/r2_route.json
tests/topotests/isis-topo1/r3/isisd.conf
tests/topotests/isis-topo1/r3/r3_route.json
tests/topotests/isis-topo1/r4/isisd.conf
tests/topotests/isis-topo1/r4/r4_route.json
tests/topotests/isis-topo1/r5/isisd.conf
tests/topotests/ldp-sync-isis-topo1/r1/isisd.conf
tests/topotests/ldp-sync-isis-topo1/r2/isisd.conf
tests/topotests/ldp-sync-isis-topo1/r3/isisd.conf
tests/topotests/ldp-sync-isis-topo1/test_ldp_sync_isis_topo1.py
tests/topotests/ldp-sync-ospf-topo1/test_ldp_sync_ospf_topo1.py
tests/topotests/ldp-vpls-topo1/test_ldp_vpls_topo1.py
tests/topotests/lib/bgprib.py
tests/topotests/lib/common_config.py
tests/topotests/lib/ltemplate.py
tests/topotests/lib/lutil.py
tests/topotests/lib/ospf.py
tests/topotests/lib/test/test_json.py
tests/topotests/lib/topogen.py
tests/topotests/lib/topojson.py
tests/topotests/lib/topotest.py
tests/topotests/ospf-sr-topo1/test_ospf_sr_topo1.py
tests/topotests/ospf-topo2/test_ospf_topo2.py
tests/topotests/ospf_basic_functionality/test_ospf_authentication.py
tests/topotests/ospf_basic_functionality/test_ospf_ecmp.py
tests/topotests/ospf_basic_functionality/test_ospf_ecmp_lan.py
tests/topotests/ospf_basic_functionality/test_ospf_lan.py
tests/topotests/ospf_basic_functionality/test_ospf_nssa.py
tests/topotests/ospf_basic_functionality/test_ospf_routemaps.py
tests/topotests/ospf_basic_functionality/test_ospf_rte_calc.py
tests/topotests/ospf_basic_functionality/test_ospf_single_area.py
tests/topotests/pbr-topo1/test_pbr_topo1.py
tests/topotests/pim-basic/mcast-rx.py
tests/topotests/pim-basic/mcast-tx.py
tests/topotests/pytest.ini
tests/topotests/route-scale/test_route_scale.py
tools/coccinelle/README.md [new file with mode: 0644]
tools/coccinelle/thread_cancel_api.cocci [new file with mode: 0644]
tools/etc/frr/daemons
tools/fixup-deprecated.py
tools/frr-reload.py
tools/frrcommon.sh.in
tools/gcc-plugins/format-test.py
tools/gcc-plugins/frr-format.c
tools/gen_northbound_callbacks.c
tools/gen_yang_deviations.c
tools/generate_support_bundle.py
tools/git-reindent-branch.py
tools/indent.py
tools/render_md.py
tools/stringmangle.py
tools/symalyzer.py
vrrpd/vrrp.c
vrrpd/vrrp_vty.c
vrrpd/vrrp_zebra.c
vtysh/.gitignore
vtysh/vtysh.c
watchfrr/watchfrr.c
yang/embedmodel.py
yang/frr-bgp-common.yang
yang/frr-bgp.yang
yang/frr-filter.yang
yang/frr-isisd.yang
yang/frr-nexthop.yang
yang/frr-route-types.yang
yang/subdir.am
zebra/connected.c
zebra/debug.c
zebra/if_netlink.c
zebra/interface.c
zebra/interface.h
zebra/ioctl.c
zebra/irdp_main.c
zebra/irdp_packet.c
zebra/kernel_netlink.c
zebra/kernel_socket.c
zebra/main.c
zebra/redistribute.c
zebra/rib.h
zebra/router-id.c
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/rtadv.c
zebra/rule_netlink.c
zebra/zapi_msg.c
zebra/zebra_dplane.c
zebra/zebra_dplane.h
zebra/zebra_evpn.c
zebra/zebra_evpn_mac.c
zebra/zebra_evpn_mac.h
zebra/zebra_evpn_mh.c
zebra/zebra_evpn_mh.h
zebra/zebra_evpn_neigh.c
zebra/zebra_evpn_neigh.h
zebra/zebra_fpm.c
zebra/zebra_fpm_dt.c
zebra/zebra_fpm_netlink.c
zebra/zebra_gr.c
zebra/zebra_l2.c
zebra/zebra_l2.h
zebra/zebra_mlag_private.c
zebra/zebra_mpls.c
zebra/zebra_mpls.h
zebra/zebra_mroute.c
zebra/zebra_nb_config.c
zebra/zebra_nb_rpcs.c
zebra/zebra_netns_notify.c
zebra/zebra_nhg.c
zebra/zebra_nhg.h
zebra/zebra_opaque.c
zebra/zebra_ptm.c
zebra/zebra_pw.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_rnh.h
zebra/zebra_routemap.c
zebra/zebra_router.h
zebra/zebra_vrf.c
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zebra_vxlan.h
zebra/zserv.c

index e8a364050afbed20c8a9d81c3d5746be713ffa2e..61bc0ade6596beffcf2eb2c0aeeee121687922a7 100644 (file)
@@ -1 +1,12 @@
+# Following revs are all whitespace changes; use with
+# git blame --ignore-revs-file .git-blame-ignore-revs <...>
+# or to make it permanent
+# git config blame.ignoreRevsFile .git-blame-ignore-revs
+701a01920eee5431d2052aad92aefbdf50ac2139
+bf2394f08bdc91a6cbd3784a1bfa3af3247bb06f
+0157c327715ca367d13b7f02b2981f3484ccdeeb
+787e762445d50ca5b52fafcf8dd6de08ab90916f
+ac2914d3261a78cf78eec7a6e20ebbe42bb57150
+ac4d0be5874fafd14212d6007fff7495edc9b152
 d62a17aedeb0eebdba98238874bb13d62c48dbf9
+c14777c6bfd0a446c85243d3a9835054a259c276
index 98c7c3d54da0c87a2473500c40cff8bd79cac26a..8983b39eb3f994bb68d3f1ab2c742a664705a6d9 100644 (file)
@@ -7,37 +7,91 @@ assignees: ''
 
 ---
 
+<!--
+
+*** ATTENTION ***
+
+YOU MUST READ THIS TO HAVE YOUR ISSUE ADDRESSED
+
+PLEASE READ AND FILL OUT THIS TEMPLATE
+
+NEGLECTING TO PROVIDE INFORMATION REQUESTED HERE WILL RESULT IN
+SIGNIFICANT DELAYS ADDRESSING YOUR ISSUE
+
+ALWAYS PROVIDE:
+- FRR VERSION
+- OPERATING SYSTEM VERSION
+- KERNEL VERSION
+
+FAILURE TO PROVIDE THIS MAY RESULT IN YOUR ISSUE BEING IGNORED
+
+FOLLOW THESE GUIDELINES:
+
 - When reporting a crash, provide a backtrace
-- When pasting configs, logs, shell output, backtraces, and other large chunks of text use Markdown code blocks
-- Include the FRR version; if you built from Git, please provide the commit hash
+- When pasting configs, logs, shell output, backtraces, and other large chunks
+  of text, surround this text with triple backtics
+
+  ```
+  like this
+  ```
+
+- Include the FRR version; if you built from Git, please provide the commit
+  hash
 - Write your issue in English
 
+-->
+
 ---------------
 
 **Describe the bug**
+<!--
 A clear and concise description of what the bug is.
 
-(put "x" in "[ ]" if you already tried following)
+Put "x" in "[ ]" if you already tried following:
+-->
+
 [ ] Did you check if this is a duplicate issue?
 [ ] Did you test it on the latest FRRouting/frr master branch?
 
 
 **To Reproduce**
-Steps to reproduce the behavior:
+<!--
+Describe the steps to reproduce the behavior.
+Be as descriptive as possible.
+
+For example:
+
 1. Go to '...'
 2. Click on '....'
 3. Scroll down to '....'
 4. See error
+-->
 
 **Expected behavior**
-A clear and concise description of what you expected to happen.
+<!--
+Write here a clear and concise description of what you expected to happen when
+using the reproduction steps you provided above
+-->
 
 **Screenshots**
+<!--
 If applicable, add screenshots to help explain your problem.
+-->
 
 **Versions**
- - OS Kernel: [e.g. Linux, OpenBSD, etc] [version]
- - FRR Version: [version]
+<!--
+Include your operating system type and version here
+
+FAILURE TO PROVIDE THIS MAY RESULT IN YOUR ISSUE BEING IGNORED
+-->
+<!-- e.g. Fedora 24, Debian 10] -->
+ - OS Version:
+<!-- [e.g. Linux 5.4, OpenBSD 6.6] -->
+ - Kernel:
+<!-- e.g. 6.0, 7.4 -->
+ - FRR Version:
 
 **Additional context**
+<!--
 Add any other context about the problem here.
+-->
index 43a77832a94977d0ab1ea05c4d1e1bdaec425481..d6c6c5f0afb3ec018ee019d73183428625cfa942 100644 (file)
@@ -6,7 +6,7 @@ pkgrel=0
 pkgdesc="FRRouting is a fork of quagga"
 url="https://frrouting.org/"
 license="GPL-2.0"
-depends="json-c c-ares ipsec-tools iproute2 python3 py-ipaddr bash"
+depends="json-c c-ares iproute2 python3 bash"
 makedepends="ncurses-dev net-snmp-dev gawk texinfo perl
     acct autoconf automake bash binutils bison bsd-compat-headers build-base
     c-ares c-ares-dev ca-certificates cryptsetup-libs curl device-mapper-libs
index 28ba8e16a23793d77527c68c99b5741df2ef75b4..731ad1ba8b04940e002199a42c72ee5676270d4d 100644 (file)
@@ -59,24 +59,16 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen,
         if (access_list_apply (babel_ifp->list[distribute], &p)
             == FILTER_DENY) {
             debugf(BABEL_DEBUG_FILTER,
-                   "%s/%d filtered by distribute %s",
-                   p.family == AF_INET ?
-                   inet_ntoa(p.u.prefix4) :
-                   inet6_ntoa (p.u.prefix6),
-                   p.prefixlen,
-                   output ? "out" : "in");
+                   "%pFX filtered by distribute %s",
+                   &p, output ? "out" : "in");
             return INFINITY;
        }
     }
     if (babel_ifp != NULL && babel_ifp->prefix[distribute]) {
         if (prefix_list_apply (babel_ifp->prefix[distribute], &p)
             == PREFIX_DENY) {
-            debugf(BABEL_DEBUG_FILTER, "%s/%d filtered by distribute %s",
-                   p.family == AF_INET ?
-                   inet_ntoa(p.u.prefix4) :
-                   inet6_ntoa (p.u.prefix6),
-                   p.prefixlen,
-                   output ? "out" : "in");
+            debugf(BABEL_DEBUG_FILTER, "%pFX filtered by distribute %s",
+                   &p, output ? "out" : "in");
             return INFINITY;
        }
     }
@@ -91,12 +83,8 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen,
 
             if (alist) {
                 if (access_list_apply (alist, &p) == FILTER_DENY) {
-                    debugf(BABEL_DEBUG_FILTER,"%s/%d filtered by distribute %s",
-                           p.family == AF_INET ?
-                           inet_ntoa(p.u.prefix4) :
-                           inet6_ntoa (p.u.prefix6),
-                           p.prefixlen,
-                           output ? "out" : "in");
+                    debugf(BABEL_DEBUG_FILTER,"%pFX filtered by distribute %s",
+                           &p, output ? "out" : "in");
                     return INFINITY;
                }
            }
@@ -105,12 +93,8 @@ babel_filter(int output, const unsigned char *prefix, unsigned short plen,
             plist = prefix_list_lookup (p.family, dist->prefix[distribute]);
             if (plist) {
                 if (prefix_list_apply (plist, &p) == PREFIX_DENY) {
-                    debugf(BABEL_DEBUG_FILTER,"%s/%d filtered by distribute %s",
-                           p.family == AF_INET ?
-                           inet_ntoa(p.u.prefix4) :
-                           inet6_ntoa (p.u.prefix6),
-                           p.prefixlen,
-                           output ? "out" : "in");
+                    debugf(BABEL_DEBUG_FILTER,"%pFX filtered by distribute %s",
+                           &p, output ? "out" : "in");
                     return INFINITY;
                }
            }
index 1702d9277cd34466caaa11a9c03aa453c56b1c2f..ae8b161b0176aeb73dd1d338d9c3ab77ca4de538 100644 (file)
@@ -1106,6 +1106,7 @@ DEFUN (show_babel_route_addr,
 {
     struct in_addr addr;
     char buf[INET_ADDRSTRLEN + 8];
+    char buf1[INET_ADDRSTRLEN + 8];
     struct route_stream *routes = NULL;
     struct xroute_stream *xroutes = NULL;
     struct prefix prefix;
@@ -1118,7 +1119,8 @@ DEFUN (show_babel_route_addr,
     }
 
     /* Quagga has no convenient prefix constructors. */
-    snprintf(buf, sizeof(buf), "%s/%d", inet_ntoa(addr), 32);
+    snprintf(buf, sizeof(buf), "%s/%d",
+            inet_ntop(AF_INET, &addr, buf1, sizeof(buf1)), 32);
 
     ret = str2prefix(buf, &prefix);
     if (ret == 0) {
index 86f8bc721e73886f9f7182760f6780459b2791fe..d10d418572549605f31b3fc7407ebeff8717a1dd 100644 (file)
@@ -251,7 +251,7 @@ void babelz_zebra_init(void)
     install_element(CONFIG_NODE, &debug_babel_cmd);
     install_element(CONFIG_NODE, &no_debug_babel_cmd);
 
-    install_element(VIEW_NODE, &show_debugging_babel_cmd);
+    install_element(ENABLE_NODE, &show_debugging_babel_cmd);
 }
 
 void
index 09955cfbef28e4ec3f690b3293db1e7998b293c8..895ede704044727f771c4d9291ada33e11a45828 100644 (file)
@@ -317,13 +317,9 @@ babel_clean_routing_process(void)
     flush_all_routes();
     babel_interface_close_all();
 
-    /* cancel threads */
-    if (babel_routing_process->t_read != NULL) {
-        thread_cancel(babel_routing_process->t_read);
-    }
-    if (babel_routing_process->t_update != NULL) {
-        thread_cancel(babel_routing_process->t_update);
-    }
+    /* cancel events */
+    thread_cancel(&babel_routing_process->t_read);
+    thread_cancel(&babel_routing_process->t_update);
 
     distribute_list_delete(&babel_routing_process->distribute_ctx);
     XFREE(MTYPE_BABEL, babel_routing_process);
@@ -503,9 +499,7 @@ static void
 babel_set_timer(struct timeval *timeout)
 {
     long msecs = timeout->tv_sec * 1000 + timeout->tv_usec / 1000;
-    if (babel_routing_process->t_update != NULL) {
-        thread_cancel(babel_routing_process->t_update);
-    }
+    thread_cancel(&(babel_routing_process->t_update));
     thread_add_timer_msec(master, babel_main_loop, NULL, msecs, &babel_routing_process->t_update);
 }
 
index 3b954c64f823b0b35c9316e47891702384cc36a9..4929bf1998478456d28a36f1f45e7986ad4c129a 100644 (file)
@@ -145,10 +145,7 @@ void control_shutdown(void)
 {
        struct bfd_control_socket *bcs;
 
-       if (bglobal.bg_csockev) {
-               thread_cancel(bglobal.bg_csockev);
-               bglobal.bg_csockev = NULL;
-       }
+       thread_cancel(&bglobal.bg_csockev);
 
        socket_close(&bglobal.bg_csock);
 
@@ -204,15 +201,8 @@ static void control_free(struct bfd_control_socket *bcs)
        struct bfd_control_queue *bcq;
        struct bfd_notify_peer *bnp;
 
-       if (bcs->bcs_ev) {
-               thread_cancel(bcs->bcs_ev);
-               bcs->bcs_ev = NULL;
-       }
-
-       if (bcs->bcs_outev) {
-               thread_cancel(bcs->bcs_outev);
-               bcs->bcs_outev = NULL;
-       }
+       thread_cancel(&(bcs->bcs_ev));
+       thread_cancel(&(bcs->bcs_outev));
 
        close(bcs->bcs_sd);
 
@@ -318,10 +308,7 @@ static int control_queue_dequeue(struct bfd_control_socket *bcs)
        return 1;
 
 empty_list:
-       if (bcs->bcs_outev) {
-               thread_cancel(bcs->bcs_outev);
-               bcs->bcs_outev = NULL;
-       }
+       thread_cancel(&(bcs->bcs_outev));
        bcs->bcs_bout = NULL;
        return 0;
 }
index 48e55bce37ba4ddaf8d5212d140691873783d200..3a80d9203b49f3e694e1cc330d9cb4601f185a38 100644 (file)
@@ -783,17 +783,16 @@ static void bfdd_sessions_enable_address(struct connected *ifc)
 static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS)
 {
        struct connected *ifc;
-       char buf[64];
 
        ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
        if (ifc == NULL)
                return 0;
 
        if (bglobal.debug_zebra)
-               zlog_debug("zclient: %s local address %s",
+               zlog_debug("zclient: %s local address %pFX",
                           cmd == ZEBRA_INTERFACE_ADDRESS_ADD ? "add"
                                                              : "delete",
-                          prefix2str(ifc->address, buf, sizeof(buf)));
+                          ifc->address);
 
        bfdd_sessions_enable_address(ifc);
 
index 0821a724a647477468560d2644ac543d147b036a..b94e24e870b2029146c9c80beb5a93658237224b 100644 (file)
@@ -725,6 +725,8 @@ bool attrhash_cmp(const void *p1, const void *p2)
                    && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t))
                    && attr1->es_flags == attr2->es_flags
                    && attr1->mm_sync_seqnum == attr2->mm_sync_seqnum
+                   && attr1->df_pref == attr2->df_pref
+                   && attr1->df_alg == attr2->df_alg
                    && attr1->nh_ifindex == attr2->nh_ifindex
                    && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex
                    && attr1->distance == attr2->distance
@@ -763,8 +765,7 @@ static void attr_show_all_iterator(struct hash_bucket *bucket, struct vty *vty)
        struct attr *attr = bucket->data;
        char sid_str[BUFSIZ];
 
-       vty_out(vty, "attr[%ld] nexthop %s\n", attr->refcnt,
-               inet_ntoa(attr->nexthop));
+       vty_out(vty, "attr[%ld] nexthop %pI4\n", attr->refcnt, &attr->nexthop);
 
        sid_str[0] = '\0';
        if (attr->srv6_l3vpn)
@@ -2248,6 +2249,9 @@ bgp_attr_ext_communities(struct bgp_attr_parser_args *args)
 
        attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
 
+       /* Extract DF election preference and  mobility sequence number */
+       attr->df_pref = bgp_attr_df_pref_from_ec(attr, &attr->df_alg);
+
        /* Extract MAC mobility sequence number, if any. */
        attr->mm_seqnum = bgp_attr_mac_mobility_seqnum(attr, &sticky);
        attr->sticky = sticky;
index e6e953364bebe5d0c0d199e55054622b601accd1..ef0e74344a968be7dc0adaa2ae4d55a58b862597 100644 (file)
@@ -294,6 +294,10 @@ struct attr {
 
        /* SR-TE Color */
        uint32_t srte_color;
+
+       /* EVPN DF preference and algorithm for DF election on local ESs */
+       uint16_t df_pref;
+       uint8_t df_alg;
 };
 
 /* rmap_change_flags definition */
index aa0c59f3a7a57942a6f6c47c15e1d185f27408bb..7cc9ecd79edfc4a03bccda858e9e1bb84693bd1a 100644 (file)
@@ -26,6 +26,7 @@
 #include "log.h"
 #include "memory.h"
 #include "stream.h"
+#include "vxlan.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_attr.h"
@@ -145,6 +146,43 @@ uint8_t bgp_attr_default_gw(struct attr *attr)
        return 0;
 }
 
+/*
+ * Fetch and return the DF preference and algorithm from
+ * DF election extended community, if present, else 0.
+ */
+uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg)
+{
+       struct ecommunity *ecom;
+       int i;
+       uint16_t df_pref = 0;
+
+       *alg = EVPN_MH_DF_ALG_SERVICE_CARVING;
+       ecom = attr->ecommunity;
+       if (!ecom || !ecom->size)
+               return 0;
+
+       for (i = 0; i < ecom->size; i++) {
+               uint8_t *pnt;
+               uint8_t type, sub_type;
+
+               pnt = (ecom->val + (i * ECOMMUNITY_SIZE));
+               type = *pnt++;
+               sub_type = *pnt++;
+               if (!(type == ECOMMUNITY_ENCODE_EVPN
+                     && sub_type == ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION))
+                       continue;
+
+               *alg = (*pnt++) & ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS;
+
+               pnt += 3;
+               pnt = ptr_get_be16(pnt, &df_pref);
+               (void)pnt; /* consume value */
+               break;
+       }
+
+       return df_pref;
+}
+
 /*
  * Fetch and return the sequence number from MAC Mobility extended
  * community, if present, else 0.
index 19c028a8262c11109874b988345c79e13968df22..6fdf73fd1e32583fed6aa4883dcace75131c8e5e 100644 (file)
@@ -48,6 +48,7 @@ extern uint8_t bgp_attr_default_gw(struct attr *attr);
 
 extern void bgp_attr_evpn_na_flag(struct attr *attr, uint8_t *router_flag,
                bool *proxy);
+extern uint16_t bgp_attr_df_pref_from_ec(struct attr *attr, uint8_t *alg);
 
 extern bool is_zero_gw_ip(const union gw_addr *gw_ip, afi_t afi);
 
index 1e1c97c2d9d935b04d1ecd3dc7373ba708f9a2be..11e9344d1cafafec0d912a27d1a337790fe2d83e 100644 (file)
@@ -385,24 +385,21 @@ static int bgp_bfd_dest_update(ZAPI_CALLBACK_ARGS)
 
        if (BGP_DEBUG(zebra, ZEBRA)) {
                struct vrf *vrf;
-               char buf[2][PREFIX2STR_BUFFER];
 
                vrf = vrf_lookup_by_id(vrf_id);
-               prefix2str(&dp, buf[0], sizeof(buf[0]));
-               if (ifp) {
+
+               if (ifp)
                        zlog_debug(
-                               "Zebra: vrf %s(%u) interface %s bfd destination %s %s %s",
-                               VRF_LOGNAME(vrf), vrf_id, ifp->name,
-                               buf[0], bfd_get_status_str(status),
+                               "Zebra: vrf %s(%u) interface %s bfd destination %pFX %s %s",
+                               VRF_LOGNAME(vrf), vrf_id, ifp->name, &dp,
+                               bfd_get_status_str(status),
                                remote_cbit ? "(cbit on)" : "");
-               } else {
-                       prefix2str(&sp, buf[1], sizeof(buf[1]));
+               else
                        zlog_debug(
-                               "Zebra: vrf %s(%u) source %s bfd destination %s %s %s",
-                               VRF_LOGNAME(vrf), vrf_id, buf[1], buf[0],
+                               "Zebra: vrf %s(%u) source %pFX bfd destination %pFX %s %s",
+                               VRF_LOGNAME(vrf), vrf_id, &sp, &dp,
                                bfd_get_status_str(status),
                                remote_cbit ? "(cbit on)" : "");
-               }
        }
 
        /* Bring the peer down if BFD is enabled in BGP */
@@ -601,6 +598,7 @@ static int bgp_bfd_peer_param_type_set(struct peer *peer,
        return 0;
 }
 
+#if HAVE_BFDD > 0
 /**
  * Set peer BFD profile configuration.
  */
@@ -655,6 +653,7 @@ static int bgp_bfd_peer_set_profile(struct peer *peer, const char *profile)
 
        return 0;
 }
+#endif
 
 /*
  * bgp_bfd_peer_config_write - Write the peer BFD configuration.
index 9032da55bf26d0c4efc9308769659a1bf70c4ca2..d6b22d0cbca142b9d49a11bcdf18870fd1b06619 100644 (file)
@@ -156,7 +156,7 @@ struct bmp {
         * table entry, the sync* fields note down what we sent last
         */
        struct prefix syncpos;
-       struct bgp_node *syncrdpos;
+       struct bgp_dest *syncrdpos;
        uint64_t syncpeerid;
        afi_t syncafi;
        safi_t syncsafi;
index cbe18e23cb0da6976c8da0455c116f06f346e6f2..13c42d95f4cb3cc04bf2123e99f86d75082dec58 100644 (file)
@@ -108,7 +108,7 @@ static void attr_parse(struct stream *s, uint16_t len)
                case BGP_ATTR_NEXT_HOP: {
                        struct in_addr nexthop;
                        nexthop.s_addr = stream_get_ipv4(s);
-                       printf("NEXTHOP: %s\n", inet_ntoa(nexthop));
+                       printf("NEXTHOP: %pI4\n", &nexthop);
                } break;
                default:
                        stream_getw_from(s, length);
@@ -244,7 +244,7 @@ int main(int argc, char **argv)
                        while (s->getp < len - 16) {
                                p.prefix.s_addr = stream_get_ipv4(s);
                                p.prefixlen = stream_getc(s);
-                               printf("PREFIX: %s/%d\n", inet_ntoa(p.prefix),
+                               printf("PREFIX: %pI4/%d\n", &p.prefix,
                                       p.prefixlen);
 
                                status = stream_getc(s);
@@ -252,8 +252,7 @@ int main(int argc, char **argv)
                                peer.s_addr = stream_get_ipv4(s);
                                source_as = stream_getw(s);
 
-                               printf("FROM: %s AS%d\n", inet_ntoa(peer),
-                                      source_as);
+                               printf("FROM: %pI4 AS%d\n", &peer, source_as);
                                printf("ORIGINATED: %s", ctime(&originated));
 
                                attrlen = stream_getw(s);
@@ -278,8 +277,8 @@ int main(int argc, char **argv)
                        sip.s_addr = stream_get_ipv4(s);
                        dip.s_addr = stream_get_ipv4(s);
 
-                       printf("saddr: %s\n", inet_ntoa(sip));
-                       printf("daddr: %s\n", inet_ntoa(dip));
+                       printf("saddr: %pI4\n", &sip);
+                       printf("daddr: %pI4\n", &dip);
 
                        printf("\n");
                }
diff --git a/bgpd/bgp_conditional_adv.c b/bgpd/bgp_conditional_adv.c
new file mode 100644 (file)
index 0000000..0731adc
--- /dev/null
@@ -0,0 +1,343 @@
+/*
+ * BGP Conditional advertisement
+ * Copyright (C) 2020  Samsung R&D Institute India - Bangalore.
+ *                     Madhurilatha Kuruganti
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "bgpd/bgp_conditional_adv.h"
+
+const char *get_afi_safi_str(afi_t afi, safi_t safi, bool for_json);
+
+static route_map_result_t
+bgp_check_rmap_prefixes_in_bgp_table(struct bgp_table *table,
+                                    struct route_map *rmap)
+{
+       struct attr dummy_attr = {0};
+       struct bgp_dest *dest;
+       struct bgp_path_info *pi;
+       struct bgp_path_info path = {0};
+       struct bgp_path_info_extra path_extra = {0};
+       const struct prefix *dest_p;
+       route_map_result_t ret = RMAP_DENYMATCH;
+
+       for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
+               dest_p = bgp_dest_get_prefix(dest);
+               assert(dest_p);
+
+               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+                       dummy_attr = *pi->attr;
+
+                       /* Fill temp path_info */
+                       prep_for_rmap_apply(&path, &path_extra, dest, pi,
+                                           pi->peer, &dummy_attr);
+
+                       RESET_FLAG(dummy_attr.rmap_change_flags);
+
+                       ret = route_map_apply(rmap, dest_p, RMAP_BGP, &path);
+                       if (ret != RMAP_PERMITMATCH)
+                               bgp_attr_flush(&dummy_attr);
+                       else {
+                               if (BGP_DEBUG(update, UPDATE_OUT))
+                                       zlog_debug(
+                                               "%s: Condition map routes present in BGP table",
+                                               __func__);
+
+                               return ret;
+                       }
+               }
+       }
+
+       if (BGP_DEBUG(update, UPDATE_OUT))
+               zlog_debug("%s: Condition map routes not present in BGP table",
+                          __func__);
+
+       return ret;
+}
+
+static void bgp_conditional_adv_routes(struct peer *peer, afi_t afi,
+                                      safi_t safi, struct bgp_table *table,
+                                      struct route_map *rmap,
+                                      enum update_type update_type)
+{
+       int addpath_capable;
+       struct bgp_dest *dest;
+       struct bgp_path_info *pi;
+       struct bgp_path_info path;
+       struct peer_af *paf;
+       const struct prefix *dest_p;
+       struct update_subgroup *subgrp;
+       struct attr dummy_attr = {0}, attr = {0};
+       struct bgp_path_info_extra path_extra = {0};
+
+       paf = peer_af_find(peer, afi, safi);
+       if (!paf)
+               return;
+
+       subgrp = PAF_SUBGRP(paf);
+       /* Ignore if subgroup doesn't exist (implies AF is not negotiated) */
+       if (!subgrp)
+               return;
+
+       if (BGP_DEBUG(update, UPDATE_OUT))
+               zlog_debug("%s: %s routes to/from %s for %s", __func__,
+                          update_type == ADVERTISE ? "Advertise" : "Withdraw",
+                          peer->host, get_afi_safi_str(afi, safi, false));
+
+       addpath_capable = bgp_addpath_encode_tx(peer, afi, safi);
+
+       for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest)) {
+               dest_p = bgp_dest_get_prefix(dest);
+               assert(dest_p);
+
+               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+                       dummy_attr = *pi->attr;
+
+                       /* Fill temp path_info */
+                       prep_for_rmap_apply(&path, &path_extra, dest, pi,
+                                           pi->peer, &dummy_attr);
+
+                       RESET_FLAG(dummy_attr.rmap_change_flags);
+
+                       if (route_map_apply(rmap, dest_p, RMAP_BGP, &path)
+                           != RMAP_PERMITMATCH) {
+                               bgp_attr_flush(&dummy_attr);
+                               continue;
+                       }
+
+                       if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
+                           || (addpath_capable
+                               && bgp_addpath_tx_path(
+                                          peer->addpath_type[afi][safi],
+                                          pi))) {
+
+                               /* Skip route-map checks in
+                                * subgroup_announce_check while executing from
+                                * the conditional advertise scanner process.
+                                * otherwise when route-map is also configured
+                                * on same peer, routes in advertise-map may not
+                                * be advertised as expected.
+                                */
+                               if ((update_type == ADVERTISE)
+                                   && subgroup_announce_check(dest, pi, subgrp,
+                                                              dest_p, &attr,
+                                                              true))
+                                       bgp_adj_out_set_subgroup(dest, subgrp,
+                                                                &attr, pi);
+                               else {
+                                       /* If default originate is enabled for
+                                        * the peer, do not send explicit
+                                        * withdraw. This will prevent deletion
+                                        * of default route advertised through
+                                        * default originate.
+                                        */
+                                       if (CHECK_FLAG(
+                                                   peer->af_flags[afi][safi],
+                                                   PEER_FLAG_DEFAULT_ORIGINATE)
+                                           && is_default_prefix(dest_p))
+                                               break;
+
+                                       bgp_adj_out_unset_subgroup(
+                                               dest, subgrp, 1,
+                                               bgp_addpath_id_for_peer(
+                                                       peer, afi, safi,
+                                                       &pi->tx_addpath));
+                               }
+                       }
+               }
+       }
+}
+
+/* Handler of conditional advertisement timer event.
+ * Each route in the condition-map is evaluated.
+ */
+static int bgp_conditional_adv_timer(struct thread *t)
+{
+       afi_t afi;
+       safi_t safi;
+       int pfx_rcd_safi;
+       struct bgp *bgp = NULL;
+       struct peer *peer = NULL;
+       struct peer_af *paf = NULL;
+       struct bgp_table *table = NULL;
+       struct bgp_filter *filter = NULL;
+       struct listnode *node, *nnode = NULL;
+       struct update_subgroup *subgrp = NULL;
+       route_map_result_t ret;
+
+       bgp = THREAD_ARG(t);
+       assert(bgp);
+
+       thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp,
+                        CONDITIONAL_ROUTES_POLL_TIME, &bgp->t_condition_check);
+
+       /* loop through each peer and advertise or withdraw routes if
+        * advertise-map is configured and prefix(es) in condition-map
+        * does exist(exist-map)/not exist(non-exist-map) in BGP table
+        * based on condition(exist-map or non-exist map)
+        */
+       for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
+               if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                       continue;
+
+               if (peer->status != Established)
+                       continue;
+
+               FOREACH_AFI_SAFI (afi, safi) {
+                       if (strmatch(get_afi_safi_str(afi, safi, true),
+                                    "Unknown"))
+                               continue;
+
+                       if (!peer->afc_nego[afi][safi])
+                               continue;
+
+                       /* labeled-unicast routes are installed in the unicast
+                        * table so in order to display the correct PfxRcd value
+                        * we must look at SAFI_UNICAST
+                        */
+                       pfx_rcd_safi = (safi == SAFI_LABELED_UNICAST)
+                                              ? SAFI_UNICAST
+                                              : safi;
+
+                       table = bgp->rib[afi][pfx_rcd_safi];
+                       if (!table)
+                               continue;
+
+                       filter = &peer->filter[afi][safi];
+
+                       if (!filter->advmap.aname || !filter->advmap.cname
+                           || !filter->advmap.amap || !filter->advmap.cmap)
+                               continue;
+
+                       if (!peer->advmap_config_change[afi][safi]
+                           && !peer->advmap_table_change)
+                               continue;
+
+                       if (BGP_DEBUG(update, UPDATE_OUT)) {
+                               if (peer->advmap_table_change)
+                                       zlog_debug(
+                                               "%s: %s - routes changed in BGP table.",
+                                               __func__, peer->host);
+                               if (peer->advmap_config_change[afi][safi])
+                                       zlog_debug(
+                                               "%s: %s for %s - advertise/condition map configuration is changed.",
+                                               __func__, peer->host,
+                                               get_afi_safi_str(afi, safi,
+                                                                false));
+                       }
+
+                       /* cmap (route-map attached to exist-map or
+                        * non-exist-map) map validation
+                        */
+                       ret = bgp_check_rmap_prefixes_in_bgp_table(
+                               table, filter->advmap.cmap);
+
+                       /* Derive conditional advertisement status from
+                        * condition and return value of condition-map
+                        * validation.
+                        */
+                       if (filter->advmap.condition == CONDITION_EXIST)
+                               filter->advmap.update_type =
+                                       (ret == RMAP_PERMITMATCH) ? ADVERTISE
+                                                                 : WITHDRAW;
+                       else
+                               filter->advmap.update_type =
+                                       (ret == RMAP_PERMITMATCH) ? WITHDRAW
+                                                                 : ADVERTISE;
+
+                       /* Send regular update as per the existing policy.
+                        * There is a change in route-map, match-rule, ACLs,
+                        * or route-map filter configuration on the same peer.
+                        */
+                       if (peer->advmap_config_change[afi][safi]) {
+
+                               if (BGP_DEBUG(update, UPDATE_OUT))
+                                       zlog_debug(
+                                               "%s: Configuration is changed on peer %s for %s, send the normal update first.",
+                                               __func__, peer->host,
+                                               get_afi_safi_str(afi, safi,
+                                                                false));
+
+                               paf = peer_af_find(peer, afi, safi);
+                               if (paf) {
+                                       update_subgroup_split_peer(paf, NULL);
+                                       subgrp = paf->subgroup;
+                                       if (subgrp && subgrp->update_group)
+                                               subgroup_announce_table(
+                                                       paf->subgroup, NULL);
+                               }
+                               peer->advmap_config_change[afi][safi] = false;
+                       }
+
+                       /* Send update as per the conditional advertisement */
+                       bgp_conditional_adv_routes(peer, afi, safi, table,
+                                                  filter->advmap.amap,
+                                                  filter->advmap.update_type);
+               }
+               peer->advmap_table_change = false;
+       }
+       return 0;
+}
+
+void bgp_conditional_adv_enable(struct peer *peer, afi_t afi, safi_t safi)
+{
+       struct bgp *bgp = peer->bgp;
+
+       assert(bgp);
+
+       /* This flag is used to monitor conditional routes status in BGP table,
+        * and advertise/withdraw routes only when there is a change in BGP
+        * table w.r.t conditional routes
+        */
+       peer->advmap_config_change[afi][safi] = true;
+
+       /* advertise-map is already configured on atleast one of its
+        * neighbors (AFI/SAFI). So just increment the counter.
+        */
+       if (++bgp->condition_filter_count > 1) {
+               if (BGP_DEBUG(update, UPDATE_OUT))
+                       zlog_debug("%s: condition_filter_count %d", __func__,
+                                  bgp->condition_filter_count);
+
+               return;
+       }
+
+       /* Register for conditional routes polling timer */
+       thread_add_timer(bm->master, bgp_conditional_adv_timer, bgp,
+                        CONDITIONAL_ROUTES_POLL_TIME, &bgp->t_condition_check);
+}
+
+void bgp_conditional_adv_disable(struct peer *peer, afi_t afi, safi_t safi)
+{
+       struct bgp *bgp = peer->bgp;
+
+       assert(bgp);
+
+       /* advertise-map is not configured on any of its neighbors or
+        * it is configured on more than one neighbor(AFI/SAFI).
+        * So there's nothing to do except decrementing the counter.
+        */
+       if (--bgp->condition_filter_count != 0) {
+               if (BGP_DEBUG(update, UPDATE_OUT))
+                       zlog_debug("%s: condition_filter_count %d", __func__,
+                                  bgp->condition_filter_count);
+
+               return;
+       }
+
+       /* Last filter removed. So cancel conditional routes polling thread. */
+       THREAD_OFF(bgp->t_condition_check);
+}
diff --git a/bgpd/bgp_conditional_adv.h b/bgpd/bgp_conditional_adv.h
new file mode 100644 (file)
index 0000000..7b5053d
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * BGP Conditional advertisement
+ * Copyright (C) 2020  Samsung R&D Institute India - Bangalore.
+ *                     Madhurilatha Kuruganti
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_BGP_CONDITION_ADV_H
+#define _FRR_BGP_CONDITION_ADV_H
+#include <zebra.h>
+#include "prefix.h"
+#include "bgpd/bgp_addpath.h"
+#include "bgpd/bgp_attr.h"
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_debug.h"
+#include "bgpd/bgp_route.h"
+#include "bgpd/bgp_updgrp.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Polling time for monitoring condition-map routes in route table */
+#define CONDITIONAL_ROUTES_POLL_TIME 60
+
+extern void bgp_conditional_adv_enable(struct peer *peer, afi_t afi,
+                                      safi_t safi);
+extern void bgp_conditional_adv_disable(struct peer *peer, afi_t afi,
+                                       safi_t safi);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FRR_BGP_CONDITION_ADV_H */
index 999216818224c19ec70c9539370128c734e90271..94a27ead0e454ce6e296e66e1f3b51bf48bb0487 100644 (file)
@@ -467,10 +467,8 @@ int bgp_damp_disable(struct bgp *bgp, afi_t afi, safi_t safi)
        if (!CHECK_FLAG(bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING))
                return 0;
 
-       /* Cancel reuse thread. */
-       if (bdc->t_reuse)
-               thread_cancel(bdc->t_reuse);
-       bdc->t_reuse = NULL;
+       /* Cancel reuse event. */
+       thread_cancel(&(bdc->t_reuse));
 
        /* Clean BGP dampening information.  */
        bgp_damp_info_clean(afi, safi);
index e9d7c9e8aaa3ee686ca1829b4297861a3f308c1c..a513bc493dd4be2aa0105afe758fc30daf031e6b 100644 (file)
@@ -21,6 +21,7 @@
 #include <zebra.h>
 
 #include <lib/version.h>
+#include "lib/printfrr.h"
 #include "prefix.h"
 #include "linklist.h"
 #include "stream.h"
@@ -236,7 +237,6 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc,
 {
        struct bgp_debug_filter *filter;
        struct listnode *node, *nnode;
-       char buf[PREFIX2STR_BUFFER];
 
        vty_out(vty, "%s", desc);
 
@@ -248,10 +248,8 @@ static void bgp_debug_list_print(struct vty *vty, const char *desc,
 
                        if (filter->p && filter->p->family == AF_EVPN)
                                bgp_debug_print_evpn_prefix(vty, "", filter->p);
-                       else if (filter->p) {
-                               prefix2str(filter->p, buf, sizeof(buf));
-                               vty_out(vty, " %s", buf);
-                       }
+                       else if (filter->p)
+                               vty_out(vty, " %pFX", filter->p);
                }
        }
 
@@ -267,7 +265,6 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
 {
        struct bgp_debug_filter *filter;
        struct listnode *node, *nnode;
-       char buf[PREFIX2STR_BUFFER];
        int write = 0;
 
        if (list && !list_isempty(list)) {
@@ -282,8 +279,7 @@ static int bgp_debug_list_conf_print(struct vty *vty, const char *desc,
                                                            filter->p);
                                write++;
                        } else if (filter->p) {
-                               prefix2str(filter->p, buf, sizeof(buf));
-                               vty_out(vty, "%s %s\n", desc, buf);
+                               vty_out(vty, "%s %pFX\n", desc, filter->p);
                                write++;
                        }
                }
@@ -380,7 +376,7 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size)
        buf[0] = '\0';
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)))
-               snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop));
+               snprintfrr(buf, size, "nexthop %pI4", &attr->nexthop);
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)))
                snprintf(buf + strlen(buf), size - strlen(buf), ", origin %s",
@@ -400,7 +396,7 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size)
                                   BUFSIZ));
 
        if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4)
-               snprintf(buf, size, "nexthop %s", inet_ntoa(attr->nexthop));
+               snprintfrr(buf, size, "nexthop %pI4", &attr->nexthop);
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)))
                snprintf(buf + strlen(buf), size - strlen(buf),
@@ -424,13 +420,13 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size)
                         ", atomic-aggregate");
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)))
-               snprintf(buf + strlen(buf), size - strlen(buf),
-                        ", aggregated by %u %s", attr->aggregator_as,
-                        inet_ntoa(attr->aggregator_addr));
+               snprintfrr(buf + strlen(buf), size - strlen(buf),
+                          ", aggregated by %u %pI4", attr->aggregator_as,
+                          &attr->aggregator_addr);
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)))
-               snprintf(buf + strlen(buf), size - strlen(buf),
-                        ", originator %s", inet_ntoa(attr->originator_id));
+               snprintfrr(buf + strlen(buf), size - strlen(buf),
+                          ", originator %pI4", &attr->originator_id);
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
                int i;
@@ -438,8 +434,8 @@ bool bgp_dump_attr(struct attr *attr, char *buf, size_t size)
                snprintf(buf + strlen(buf), size - strlen(buf),
                         ", clusterlist");
                for (i = 0; i < attr->cluster->length / 4; i++)
-                       snprintf(buf + strlen(buf), size - strlen(buf), " %s",
-                                inet_ntoa(attr->cluster->list[i]));
+                       snprintfrr(buf + strlen(buf), size - strlen(buf),
+                                  " %pI4", &attr->cluster->list[i]);
        }
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)))
@@ -592,9 +588,9 @@ static void bgp_debug_print_evpn_prefix(struct vty *vty, const char *desc,
                                        buf, PREFIX2STR_BUFFER));
                }
        } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IMET_ROUTE) {
-               snprintf(evpn_desc, sizeof(evpn_desc),
-                        "l2vpn evpn type multicast ip %s",
-                        inet_ntoa(p->u.prefix_evpn.imet_addr.ip.ipaddr_v4));
+               snprintfrr(evpn_desc, sizeof(evpn_desc),
+                          "l2vpn evpn type multicast ip %pI4",
+                          &p->u.prefix_evpn.imet_addr.ip.ipaddr_v4);
        } else if (p->u.prefix_evpn.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
                uint8_t family = is_evpn_prefix_ipaddr_v4(
                                        (struct prefix_evpn *)p) ? AF_INET
@@ -616,21 +612,14 @@ static int bgp_debug_parse_evpn_prefix(struct vty *vty, struct cmd_token **argv,
        struct prefix *argv_p;
        struct ethaddr mac;
        struct ipaddr ip;
-       int evpn_type;
-       int type_idx = 0;
+       int evpn_type = 0;
        int mac_idx = 0;
        int ip_idx = 0;
 
        argv_p = *argv_pp;
 
-       if (argv_find(argv, argc, "macip", &type_idx))
-               evpn_type = BGP_EVPN_MAC_IP_ROUTE;
-       else if (argv_find(argv, argc, "multicast", &type_idx))
-               evpn_type = BGP_EVPN_IMET_ROUTE;
-       else if (argv_find(argv, argc, "prefix", &type_idx))
-               evpn_type = BGP_EVPN_IP_PREFIX_ROUTE;
-       else
-               evpn_type = 0;
+       if (bgp_evpn_cli_parse_type(&evpn_type, argv, argc) < 0)
+               return CMD_WARNING;
 
        if (evpn_type == BGP_EVPN_MAC_IP_ROUTE) {
                memset(&ip, 0, sizeof(struct ipaddr));
@@ -1395,31 +1384,33 @@ DEFUN (no_debug_bgp_update_direct_peer,
 
 DEFPY (debug_bgp_update_prefix_afi_safi,
        debug_bgp_update_prefix_afi_safi_cmd,
-       "debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
+       "debug bgp updates prefix l2vpn$afi evpn$safi type <<macip|2> mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|<multicast|3> ip <A.B.C.D|X:X::X:X>|<prefix|5> ip <A.B.C.D/M|X:X::X:X/M>>",
        DEBUG_STR
        BGP_STR
        "BGP updates\n"
        "Specify a prefix to debug\n"
        L2VPN_HELP_STR
        EVPN_HELP_STR
-       "Specify EVPN Route type\n"
-       "MAC-IP (Type-2) route\n"
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
        MAC_STR MAC_STR MAC_STR
        IP_STR
        "IPv4 address\n"
        "IPv6 address\n"
-       "Multicast (Type-3) route\n"
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
        IP_STR
        "IPv4 address\n"
        "IPv6 address\n"
-       "Prefix (Type-5) route\n"
+       EVPN_TYPE_5_HELP_STR
+       EVPN_TYPE_5_HELP_STR
        IP_STR
        "IPv4 prefix\n"
        "IPv6 prefix\n")
 {
        struct prefix *argv_p;
        int ret = CMD_SUCCESS;
-       char buf[PREFIX2STR_BUFFER];
 
        argv_p = prefix_new();
 
@@ -1432,12 +1423,10 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
        if (!bgp_debug_update_prefixes)
                bgp_debug_update_prefixes = list_new();
 
-       prefix2str(argv_p, buf, sizeof(buf));
-
        if (bgp_debug_list_has_entry(bgp_debug_update_prefixes, NULL, argv_p)) {
                vty_out(vty,
-                       "BGP updates debugging is already enabled for %s\n",
-                       buf);
+                       "BGP updates debugging is already enabled for %pFX\n",
+                       argv_p);
                prefix_free(&argv_p);
                return CMD_SUCCESS;
        }
@@ -1448,7 +1437,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
                DEBUG_ON(update, UPDATE_PREFIX);
        } else {
                TERM_DEBUG_ON(update, UPDATE_PREFIX);
-               vty_out(vty, "BGP updates debugging is on for %s\n", buf);
+               vty_out(vty, "BGP updates debugging is on for %pFX\n", argv_p);
        }
 
        prefix_free(&argv_p);
@@ -1458,7 +1447,7 @@ DEFPY (debug_bgp_update_prefix_afi_safi,
 
 DEFPY (no_debug_bgp_update_prefix_afi_safi,
        no_debug_bgp_update_prefix_afi_safi_cmd,
-       "no debug bgp updates prefix l2vpn$afi evpn$safi type <macip mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|multicast ip <A.B.C.D|X:X::X:X>|prefix ip <A.B.C.D/M|X:X::X:X/M>>",
+       "no debug bgp updates prefix l2vpn$afi evpn$safi type <<macip|2> mac <X:X:X:X:X:X|X:X:X:X:X:X/M> [ip <A.B.C.D|X:X::X:X>]|<multicast|3> ip <A.B.C.D|X:X::X:X>|<prefix|5> ip <A.B.C.D/M|X:X::X:X/M>>",
        NO_STR
        DEBUG_STR
        BGP_STR
@@ -1466,17 +1455,20 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi,
        "Specify a prefix to debug\n"
        L2VPN_HELP_STR
        EVPN_HELP_STR
-       "Specify EVPN Route type\n"
-       "MAC-IP (Type-2) route\n"
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
        MAC_STR MAC_STR MAC_STR
        IP_STR
        "IPv4 address\n"
        "IPv6 address\n"
-       "Multicast (Type-3) route\n"
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
        IP_STR
        "IPv4 address\n"
        "IPv6 address\n"
-       "Prefix (Type-5) route\n"
+       EVPN_TYPE_5_HELP_STR
+       EVPN_TYPE_5_HELP_STR
        IP_STR
        "IPv4 prefix\n"
        "IPv6 prefix\n")
@@ -1484,7 +1476,6 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi,
        struct prefix *argv_p;
        bool found_prefix = false;
        int ret = CMD_SUCCESS;
-       char buf[PREFIX2STR_BUFFER];
 
        argv_p = prefix_new();
 
@@ -1510,13 +1501,11 @@ DEFPY (no_debug_bgp_update_prefix_afi_safi,
                }
        }
 
-       prefix2str(argv_p, buf, sizeof(buf));
-
        if (found_prefix)
-               vty_out(vty, "BGP updates debugging is off for %s\n", buf);
+               vty_out(vty, "BGP updates debugging is off for %pFX\n", argv_p);
        else
-               vty_out(vty, "BGP updates debugging was not enabled for %s\n",
-                       buf);
+               vty_out(vty, "BGP updates debugging was not enabled for %pFX\n",
+                       argv_p);
 
        prefix_free(&argv_p);
 
@@ -2643,7 +2632,6 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
                                    char *str, int size)
 {
        char rd_buf[RD_ADDRSTRLEN];
-       char pfx_buf[PREFIX_STRLEN];
        char tag_buf[30];
        /* ' with addpath ID '          17
         * max strlen of uint32       + 10
@@ -2681,10 +2669,9 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
        }
 
        if (prd)
-               snprintf(str, size, "RD %s %s%s%s %s %s",
-                        prefix_rd2str(prd, rd_buf, sizeof(rd_buf)),
-                        prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf,
-                        pathid_buf, afi2str(afi), safi2str(safi));
+               snprintfrr(str, size, "RD %s %pFX%s%s %s %s",
+                          prefix_rd2str(prd, rd_buf, sizeof(rd_buf)), pu.p,
+                          tag_buf, pathid_buf, afi2str(afi), safi2str(safi));
        else if (safi == SAFI_FLOWSPEC) {
                char return_string[BGP_FLOWSPEC_NLRI_STRING_MAX];
                const struct prefix_fs *fs = pu.fs;
@@ -2697,9 +2684,8 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
                snprintf(str, size, "FS %s Match{%s}", afi2str(afi),
                         return_string);
        } else
-               snprintf(str, size, "%s%s%s %s %s",
-                        prefix2str(pu, pfx_buf, sizeof(pfx_buf)), tag_buf,
-                        pathid_buf, afi2str(afi), safi2str(safi));
+               snprintfrr(str, size, "%pFX%s%s %s %s", pu.p, tag_buf,
+                          pathid_buf, afi2str(afi), safi2str(safi));
 
        return str;
 }
index abd349a18880a4c3fe016a46312f845411da55c1..975bba93147b7d2b21918240523423fad964aa7e 100644 (file)
@@ -677,11 +677,8 @@ static int bgp_dump_unset(struct bgp_dump *bgp_dump)
                bgp_dump->fp = NULL;
        }
 
-       /* Removing interval thread. */
-       if (bgp_dump->t_interval) {
-               thread_cancel(bgp_dump->t_interval);
-               bgp_dump->t_interval = NULL;
-       }
+       /* Removing interval event. */
+       thread_cancel(&bgp_dump->t_interval);
 
        bgp_dump->interval = 0;
 
index 3a0400a4b32240400ed04ebce47c745db93f4118..de3757aebb3f6c6ab4d0ca97fcfd5f0cf10d8718 100644 (file)
@@ -29,6 +29,8 @@
 #include "jhash.h"
 #include "stream.h"
 
+#include "lib/printfrr.h"
+
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_ecommunity.h"
 #include "bgpd/bgp_lcommunity.h"
@@ -819,8 +821,8 @@ static int ecommunity_rt_soo_str_internal(char *buf, size_t bufsz,
                eip.val = (*pnt++ << 8);
                eip.val |= (*pnt++);
 
-               len = snprintf(buf, bufsz, "%s%s:%u", prefix, inet_ntoa(eip.ip),
-                              eip.val);
+               len = snprintfrr(buf, bufsz, "%s%pI4:%u", prefix, &eip.ip,
+                                eip.val);
        }
 
        /* consume value */
@@ -1036,6 +1038,27 @@ char *ecommunity_ecom2str(struct ecommunity *ecom, int format, int filter)
                                        (flags &
                                         ECOMMUNITY_EVPN_SUBTYPE_ESI_SA_FLAG) ?
                                        "SA":"AA");
+                       } else if (*pnt
+                                  == ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION) {
+                               uint8_t alg;
+                               uint16_t pref;
+                               uint16_t bmap;
+
+                               alg = *(pnt + 1);
+                               memcpy(&bmap, pnt + 2, 2);
+                               bmap = ntohs(bmap);
+                               memcpy(&pref, pnt + 5, 2);
+                               pref = ntohs(pref);
+
+                               if (bmap)
+                                       snprintf(
+                                               encbuf, sizeof(encbuf),
+                                               "DF: (alg: %u, bmap: 0x%x pref: %u)",
+                                               alg, bmap, pref);
+                               else
+                                       snprintf(encbuf, sizeof(encbuf),
+                                                "DF: (alg: %u, pref: %u)", alg,
+                                                pref);
                        } else
                                unk_ecom = 1;
                } else if (type == ECOMMUNITY_ENCODE_REDIRECT_IP_NH) {
index fe90efe1f7d1d749b48661ae23b8bfd36a28fe97..e9c52287f1e52e5c4b5880b6a8cf4c18c280caf9 100644 (file)
 #define ECOMMUNITY_EVPN_SUBTYPE_ESI_LABEL    0x01
 #define ECOMMUNITY_EVPN_SUBTYPE_ES_IMPORT_RT 0x02
 #define ECOMMUNITY_EVPN_SUBTYPE_ROUTERMAC    0x03
+#define ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION 0x06
 #define ECOMMUNITY_EVPN_SUBTYPE_DEF_GW       0x0d
 #define ECOMMUNITY_EVPN_SUBTYPE_ND           0x08
 
 #define ECOMMUNITY_EVPN_SUBTYPE_MACMOBILITY_FLAG_STICKY 0x01
 
+/* DF alg bits - only lower 5 bits are applicable */
+#define ECOMMUNITY_EVPN_SUBTYPE_DF_ALG_BITS 0x1f
+
 #define ECOMMUNITY_EVPN_SUBTYPE_ND_ROUTER_FLAG   0x01
 #define ECOMMUNITY_EVPN_SUBTYPE_ND_OVERRIDE_FLAG 0x02
 #define ECOMMUNITY_EVPN_SUBTYPE_PROXY_FLAG       0x04
index 0703853354fcdaabad4b1253576b2392f83b2c70..67d0a95cb6bcaaaa45c30d97514f567051b427dc 100644 (file)
@@ -31,6 +31,8 @@
 #include "jhash.h"
 #include "zclient.h"
 
+#include "lib/printfrr.h"
+
 #include "bgpd/bgp_attr_evpn.h"
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -64,9 +66,10 @@ DEFINE_QOBJ_TYPE(bgp_evpn_es)
  */
 static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn);
 static void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
-               struct bgpevpn *vpn,
-               struct bgp_node *rn, struct bgp_path_info *local_pi,
-               const char *caller);
+                                             struct bgpevpn *vpn,
+                                             struct bgp_dest *dest,
+                                             struct bgp_path_info *local_pi,
+                                             const char *caller);
 static struct in_addr zero_vtep_ip;
 
 /*
@@ -545,10 +548,10 @@ static void evpn_convert_nexthop_to_ipv6(struct attr *attr)
        attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
 }
 
-struct bgp_node *bgp_global_evpn_node_get(
-               struct bgp_table *table, afi_t afi,
-               safi_t safi, const struct prefix_evpn *evp,
-               struct prefix_rd *prd)
+struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table, afi_t afi,
+                                         safi_t safi,
+                                         const struct prefix_evpn *evp,
+                                         struct prefix_rd *prd)
 {
        struct prefix_evpn global_p;
 
@@ -562,10 +565,10 @@ struct bgp_node *bgp_global_evpn_node_get(
        return bgp_afi_node_get(table, afi, safi, (struct prefix *)evp, prd);
 }
 
-struct bgp_node *bgp_global_evpn_node_lookup(
-               struct bgp_table *table, afi_t afi,
-               safi_t safi, const struct prefix_evpn *evp,
-               struct prefix_rd *prd)
+struct bgp_dest *bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi,
+                                            safi_t safi,
+                                            const struct prefix_evpn *evp,
+                                            struct prefix_rd *prd)
 {
        struct prefix_evpn global_p;
 
@@ -701,9 +704,9 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
        stream_putw_at(s, 0, stream_get_endp(s));
 
        if (bgp_debug_zebra(NULL))
-               zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %s",
+               zlog_debug("Tx %s Remote VTEP, VNI %u remote VTEP %pI4",
                           add ? "ADD" : "DEL", vpn->vni,
-                          inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4));
+                          &p->prefix.imet_addr.ip.ipaddr_v4);
 
        return zclient_send_message(zclient);
 }
@@ -1031,18 +1034,17 @@ static void evpn_delete_old_local_route(struct bgp *bgp, struct bgpevpn *vpn,
        safi_t safi = SAFI_EVPN;
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) {
-               char prefix_buf[PREFIX_STRLEN];
                char esi_buf[ESI_STR_LEN];
                char esi_buf2[ESI_STR_LEN];
-               struct prefix_evpn *evp = (struct prefix_evpn *)&dest->p;
+               struct prefix_evpn *evp =
+                       (struct prefix_evpn *)bgp_dest_get_prefix(dest);
 
-               zlog_debug("local path deleted %s es %s; new-path-es %s",
-                               prefix2str(evp,
-                                       prefix_buf, sizeof(prefix_buf)),
-                               esi_to_str(&old_local->attr->esi,
-                                       esi_buf, sizeof(esi_buf)),
-                               new_select ? esi_to_str(&new_select->attr->esi,
-                                       esi_buf2, sizeof(esi_buf2)) : "");
+               zlog_debug("local path deleted %pFX es %s; new-path-es %s", evp,
+                          esi_to_str(&old_local->attr->esi, esi_buf,
+                                     sizeof(esi_buf)),
+                          new_select ? esi_to_str(&new_select->attr->esi,
+                                                  esi_buf2, sizeof(esi_buf2))
+                                     : "");
        }
 
        /* Locate route node in the global EVPN routing table. Note that
@@ -1309,23 +1311,18 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
                        attr.nexthop = bgp_vrf->evpn_info->pip_ip;
                        attr.mp_nexthop_global_in = bgp_vrf->evpn_info->pip_ip;
                } else if (bgp_vrf->evpn_info->pip_ip.s_addr == INADDR_ANY)
-                       if (bgp_debug_zebra(NULL)) {
-                               char buf1[PREFIX_STRLEN];
-
-                               zlog_debug("VRF %s evp %s advertise-pip primary ip is not configured",
-                                          vrf_id_to_name(bgp_vrf->vrf_id),
-                                          prefix2str(evp, buf1, sizeof(buf1)));
-                       }
+                       if (bgp_debug_zebra(NULL))
+                               zlog_debug(
+                                       "VRF %s evp %pFX advertise-pip primary ip is not configured",
+                                       vrf_id_to_name(bgp_vrf->vrf_id), evp);
        }
 
        if (bgp_debug_zebra(NULL)) {
                char buf[ETHER_ADDR_STRLEN];
-               char buf1[PREFIX_STRLEN];
                char buf2[INET6_ADDRSTRLEN];
 
-               zlog_debug("VRF %s type-5 route evp %s RMAC %s nexthop %s",
-                          vrf_id_to_name(bgp_vrf->vrf_id),
-                          prefix2str(evp, buf1, sizeof(buf1)),
+               zlog_debug("VRF %s type-5 route evp %pFX RMAC %s nexthop %s",
+                          vrf_id_to_name(bgp_vrf->vrf_id), evp,
                           prefix_mac2str(&attr.rmac, buf, sizeof(buf)),
                           inet_ntop(AF_INET, &attr.nexthop, buf2,
                                     INET_ADDRSTRLEN));
@@ -1359,9 +1356,9 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
 }
 
 static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi,
-               struct bgp_node *rn, uint32_t loc_seq, uint32_t *max_sync_seq,
-               bool *active_on_peer, bool *peer_router,
-               bool *proxy_from_peer)
+                                  struct bgp_dest *dest, uint32_t loc_seq,
+                                  uint32_t *max_sync_seq, bool *active_on_peer,
+                                  bool *peer_router, bool *proxy_from_peer)
 {
        struct bgp_path_info *tmp_pi;
        struct bgp_path_info *second_best_path = NULL;
@@ -1372,8 +1369,8 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi,
        /* find the best non-local path. a local path can only be present
         * as best path
         */
-       for (tmp_pi = bgp_dest_get_bgp_path_info(rn); tmp_pi;
-                       tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_dest_get_bgp_path_info(dest); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->sub_type != BGP_ROUTE_IMPORTED ||
                        !CHECK_FLAG(tmp_pi->flags, BGP_PATH_VALID))
                        continue;
@@ -1420,11 +1417,13 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi,
  * VPN route table. It will take precedence over all sync paths.
  */
 static void update_evpn_route_entry_sync_info(struct bgp *bgp,
-               struct bgp_node *rn, struct attr *attr, uint32_t loc_seq,
-               bool setup_sync)
+                                             struct bgp_dest *dest,
+                                             struct attr *attr,
+                                             uint32_t loc_seq, bool setup_sync)
 {
        esi_t *esi;
-       struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
+       struct prefix_evpn *evp =
+               (struct prefix_evpn *)bgp_dest_get_prefix(dest);
 
        if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
                return;
@@ -1437,9 +1436,9 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp,
                        bool peer_router = false;
                        bool proxy_from_peer = false;
 
-                       bgp_evpn_get_sync_info(bgp, esi, rn, loc_seq,
-                                       &max_sync_seq, &active_on_peer,
-                                       &peer_router, &proxy_from_peer);
+                       bgp_evpn_get_sync_info(bgp, esi, dest, loc_seq,
+                                              &max_sync_seq, &active_on_peer,
+                                              &peer_router, &proxy_from_peer);
                        attr->mm_sync_seqnum = max_sync_seq;
                        if (active_on_peer)
                                attr->es_flags |= ATTR_ES_PEER_ACTIVE;
@@ -1455,21 +1454,23 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp,
                                attr->es_flags &= ~ATTR_ES_PEER_ROUTER;
 
                        if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) {
-                               char prefix_buf[PREFIX_STRLEN];
                                char esi_buf[ESI_STR_LEN];
 
-                               zlog_debug("setup sync info for %s es %s max_seq %d %s%s%s",
-                                       prefix2str(evp, prefix_buf,
-                                               sizeof(prefix_buf)),
+                               zlog_debug(
+                                       "setup sync info for %pFX es %s max_seq %d %s%s%s",
+                                       evp,
                                        esi_to_str(esi, esi_buf,
-                                               sizeof(esi_buf)),
+                                                  sizeof(esi_buf)),
                                        max_sync_seq,
-                                       (attr->es_flags & ATTR_ES_PEER_ACTIVE) ?
-                                       "peer-active " : "",
-                                       (attr->es_flags & ATTR_ES_PEER_PROXY) ?
-                                       "peer-proxy " : "",
-                                       (attr->es_flags & ATTR_ES_PEER_ROUTER) ?
-                                       "peer-router " : "");
+                                       (attr->es_flags & ATTR_ES_PEER_ACTIVE)
+                                               ? "peer-active "
+                                               : "",
+                                       (attr->es_flags & ATTR_ES_PEER_PROXY)
+                                               ? "peer-proxy "
+                                               : "",
+                                       (attr->es_flags & ATTR_ES_PEER_ROUTER)
+                                               ? "peer-router "
+                                               : "");
                        }
                }
        } else {
@@ -1660,7 +1661,7 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
 {
        /* local path was not picked as the winner; kick it out */
        if (bgp_debug_zebra(NULL))
-               zlog_debug("evicting local evpn prefix %pRN as remote won",
+               zlog_debug("evicting local evpn prefix %pBD as remote won",
                           dest);
 
        evpn_delete_old_local_route(bgp, vpn, dest, local_pi, NULL);
@@ -1715,18 +1716,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
 
        if (bgp_debug_zebra(NULL)) {
                char buf[ETHER_ADDR_STRLEN];
-               char buf1[PREFIX_STRLEN];
                char buf3[ESI_STR_LEN];
 
-               zlog_debug("VRF %s vni %u type-2 route evp %s RMAC %s nexthop %s esi %s",
-                               vpn->bgp_vrf ?
-                               vrf_id_to_name(vpn->bgp_vrf->vrf_id) : " ",
-                               vpn->vni,
-                               prefix2str(p, buf1, sizeof(buf1)),
-                               prefix_mac2str(&attr.rmac, buf,
-                                       sizeof(buf)),
-                               inet_ntoa(attr.mp_nexthop_global_in),
-                               esi_to_str(esi, buf3, sizeof(buf3)));
+               zlog_debug(
+                       "VRF %s vni %u type-2 route evp %pFX RMAC %s nexthop %pI4 esi %s",
+                       vpn->bgp_vrf ? vrf_id_to_name(vpn->bgp_vrf->vrf_id)
+                                    : " ",
+                       vpn->vni, p,
+                       prefix_mac2str(&attr.rmac, buf, sizeof(buf)),
+                       &attr.mp_nexthop_global_in,
+                       esi_to_str(esi, buf3, sizeof(buf3)));
        }
        /* router mac is only needed for type-2 routes here. */
        if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
@@ -1937,8 +1936,10 @@ static int delete_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
 }
 
 static void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
-               struct bgpevpn *vpn, struct bgp_node *rn,
-               struct bgp_path_info *local_pi, const char *caller)
+                                             struct bgpevpn *vpn,
+                                             struct bgp_dest *dest,
+                                             struct bgp_path_info *local_pi,
+                                             const char *caller)
 {
        afi_t afi = AFI_L2VPN;
        safi_t safi = SAFI_EVPN;
@@ -1947,9 +1948,10 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
        struct attr *attr_new;
        uint32_t seq;
        int add_l3_ecomm = 0;
-       struct bgp_node *global_rn;
+       struct bgp_dest *global_dest;
        struct bgp_path_info *global_pi;
-       struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
+       struct prefix_evpn *evp =
+               (struct prefix_evpn *)bgp_dest_get_prefix(dest);
        int route_change;
        bool old_is_sync = false;
 
@@ -1993,24 +1995,23 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
 
        if (bgp_debug_zebra(NULL)) {
                char buf[ETHER_ADDR_STRLEN];
-               char buf1[PREFIX_STRLEN];
                char buf3[ESI_STR_LEN];
 
-               zlog_debug("VRF %s vni %u evp %s RMAC %s nexthop %s esi %s esf 0x%x from %s",
-                               vpn->bgp_vrf ?
-                               vrf_id_to_name(vpn->bgp_vrf->vrf_id) : " ",
-                               vpn->vni,
-                               prefix2str(evp, buf1, sizeof(buf1)),
-                               prefix_mac2str(&attr.rmac, buf, sizeof(buf)),
-                               inet_ntoa(attr.mp_nexthop_global_in),
-                               esi_to_str(&attr.esi, buf3, sizeof(buf3)),
-                               attr.es_flags, caller);
+               zlog_debug(
+                       "VRF %s vni %u evp %pFX RMAC %s nexthop %pI4 esi %s esf 0x%x from %s",
+                       vpn->bgp_vrf ? vrf_id_to_name(vpn->bgp_vrf->vrf_id)
+                                    : " ",
+                       vpn->vni, evp,
+                       prefix_mac2str(&attr.rmac, buf, sizeof(buf)),
+                       &attr.mp_nexthop_global_in,
+                       esi_to_str(&attr.esi, buf3, sizeof(buf3)),
+                       attr.es_flags, caller);
        }
 
        /* Update the route entry. */
-       route_change = update_evpn_route_entry(bgp, vpn, afi, safi,
-                       rn, &attr, 0, &pi, 0, seq,
-                       true /* setup_sync */, &old_is_sync);
+       route_change = update_evpn_route_entry(
+               bgp, vpn, afi, safi, dest, &attr, 0, &pi, 0, seq,
+               true /* setup_sync */, &old_is_sync);
 
        assert(pi);
        attr_new = pi->attr;
@@ -2026,14 +2027,14 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
         * advertised to peers; otherwise, ensure it is evicted and
         * (re)install the remote route into zebra.
         */
-       evpn_route_select_install(bgp, vpn, rn);
+       evpn_route_select_install(bgp, vpn, dest);
 
        if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
                route_change = 0;
        } else {
                if (!CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
                        route_change = 0;
-                       evpn_cleanup_local_non_best_route(bgp, vpn, rn, pi);
+                       evpn_cleanup_local_non_best_route(bgp, vpn, dest, pi);
                } else {
                        bool new_is_sync;
 
@@ -2056,17 +2057,17 @@ static void bgp_evpn_update_type2_route_entry(struct bgp *bgp,
 
        if (route_change) {
                /* Update route in global routing table. */
-               global_rn = bgp_global_evpn_node_get(bgp->rib[afi][safi],
-                               afi, safi, evp, &vpn->prd);
-               assert(global_rn);
-               update_evpn_route_entry(bgp, vpn, afi, safi, global_rn,
-                               attr_new, 0, &global_pi, 0,
-                               mac_mobility_seqnum(attr_new),
-                               false /* setup_sync */, NULL /* old_is_sync */);
+               global_dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi,
+                                                      safi, evp, &vpn->prd);
+               assert(global_dest);
+               update_evpn_route_entry(
+                       bgp, vpn, afi, safi, global_dest, attr_new, 0,
+                       &global_pi, 0, mac_mobility_seqnum(attr_new),
+                       false /* setup_sync */, NULL /* old_is_sync */);
 
                /* Schedule for processing and unlock node. */
-               bgp_process(bgp, global_rn, afi, safi);
-               bgp_dest_unlock_node(global_rn);
+               bgp_process(bgp, global_dest, afi, safi);
+               bgp_dest_unlock_node(global_dest);
        }
 
        /* Unintern temporary. */
@@ -2383,19 +2384,16 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
        struct prefix *pp = &p;
        afi_t afi = 0;
        safi_t safi = 0;
-       char buf[PREFIX_STRLEN];
        bool new_pi = false;
 
        memset(pp, 0, sizeof(struct prefix));
        ip_prefix_from_evpn_prefix(evp, pp);
 
-       if (bgp_debug_zebra(NULL)) {
+       if (bgp_debug_zebra(NULL))
                zlog_debug(
-                       "vrf %s: import evpn prefix %s parent %p flags 0x%x",
-                       vrf_id_to_name(bgp_vrf->vrf_id),
-                       prefix2str(evp, buf, sizeof(buf)),
-                       parent_pi, parent_pi->flags);
-       }
+                       "vrf %s: import evpn prefix %pFX parent %p flags 0x%x",
+                       vrf_id_to_name(bgp_vrf->vrf_id), evp, parent_pi,
+                       parent_pi->flags);
 
        /* Create (or fetch) route within the VRF. */
        /* NOTE: There is no RD here. */
@@ -2474,11 +2472,10 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
        bgp_dest_unlock_node(dest);
 
        if (bgp_debug_zebra(NULL))
-               zlog_debug(
-                       "... %s pi dest %p (l %d) pi %p (l %d, f 0x%x)",
-                       new_pi ? "new" : "update",
-                       dest, bgp_dest_to_rnode(dest)->lock,
-                       pi, pi->lock, pi->flags);
+               zlog_debug("... %s pi dest %p (l %d) pi %p (l %d, f 0x%x)",
+                          new_pi ? "new" : "update", dest,
+                          bgp_dest_get_lock_count(dest), pi, pi->lock,
+                          pi->flags);
 
        return ret;
 }
@@ -2575,18 +2572,15 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
        struct prefix *pp = &p;
        afi_t afi = 0;
        safi_t safi = 0;
-       char buf[PREFIX_STRLEN];
 
        memset(pp, 0, sizeof(struct prefix));
        ip_prefix_from_evpn_prefix(evp, pp);
 
-       if (bgp_debug_zebra(NULL)) {
+       if (bgp_debug_zebra(NULL))
                zlog_debug(
-                       "vrf %s: unimport evpn prefix %s parent %p flags 0x%x",
-                       vrf_id_to_name(bgp_vrf->vrf_id),
-                       prefix2str(evp, buf, sizeof(buf)),
-                       parent_pi, parent_pi->flags);
-       }
+                       "vrf %s: unimport evpn prefix %pFX parent %p flags 0x%x",
+                       vrf_id_to_name(bgp_vrf->vrf_id), evp, parent_pi,
+                       parent_pi->flags);
 
        /* Locate route within the VRF. */
        /* NOTE: There is no RD here. */
@@ -2613,10 +2607,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                return 0;
 
        if (bgp_debug_zebra(NULL))
-               zlog_debug(
-                       "... delete dest %p (l %d) pi %p (l %d, f 0x%x)",
-                       dest, bgp_dest_to_rnode(dest)->lock,
-                       pi, pi->lock, pi->flags);
+               zlog_debug("... delete dest %p (l %d) pi %p (l %d, f 0x%x)",
+                          dest, bgp_dest_get_lock_count(dest), pi, pi->lock,
+                          pi->flags);
 
        /* Process for route leaking. */
        vpn_leak_from_vrf_withdraw(bgp_get_default(), bgp_vrf, pi);
@@ -2844,15 +2837,13 @@ static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf,
         */
        if (memcmp(&bgp_vrf->rmac, &pi->attr->rmac, ETH_ALEN) == 0) {
                if (bgp_debug_update(pi->peer, NULL, NULL, 1)) {
-                       char buf1[PREFIX_STRLEN];
                        char attr_str[BUFSIZ] = {0};
 
                        bgp_dump_attr(pi->attr, attr_str, sizeof(attr_str));
 
-                       zlog_debug("%s: bgp %u prefix %s with attr %s - DENIED due to self mac",
-                               __func__, bgp_vrf->vrf_id,
-                               prefix2str(evp, buf1, sizeof(buf1)),
-                               attr_str);
+                       zlog_debug(
+                               "%s: bgp %u prefix %pFX with attr %s - DENIED due to self mac",
+                               __func__, bgp_vrf->vrf_id, evp, attr_str);
                }
 
                return 1;
@@ -2873,7 +2864,6 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
        struct bgp_table *table;
        struct bgp_path_info *pi;
        int ret;
-       char buf[PREFIX_STRLEN];
        struct bgp *bgp_evpn = NULL;
 
        afi = AFI_L2VPN;
@@ -2934,11 +2924,10 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
                                        if (ret) {
                                                flog_err(
                                                        EC_BGP_EVPN_FAIL,
-                                                       "Failed to %s EVPN %s route in VRF %s",
+                                                       "Failed to %s EVPN %pFX route in VRF %s",
                                                        install ? "install"
                                                                : "uninstall",
-                                                       prefix2str(evp, buf,
-                                                                  sizeof(buf)),
+                                                       evp,
                                                        vrf_id_to_name(
                                                                bgp_vrf->vrf_id));
                                                return ret;
@@ -3107,7 +3096,6 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi,
                                           struct bgp_path_info *pi,
                                           struct list *vrfs, int install)
 {
-       char buf[PREFIX2STR_BUFFER];
        struct bgp *bgp_vrf;
        struct listnode *node, *nnode;
 
@@ -3133,10 +3121,9 @@ static int install_uninstall_route_in_vrfs(struct bgp *bgp_def, afi_t afi,
 
                if (ret) {
                        flog_err(EC_BGP_EVPN_FAIL,
-                                "%u: Failed to %s prefix %s in VRF %s",
+                                "%u: Failed to %s prefix %pFX in VRF %s",
                                 bgp_def->vrf_id,
-                                install ? "install" : "uninstall",
-                                prefix2str(evp, buf, sizeof(buf)),
+                                install ? "install" : "uninstall", evp,
                                 vrf_id_to_name(bgp_vrf->vrf_id));
                        return ret;
                }
@@ -4094,17 +4081,14 @@ void bgp_evpn_withdraw_type5_route(struct bgp *bgp_vrf, const struct prefix *p,
 {
        int ret = 0;
        struct prefix_evpn evp;
-       char buf[PREFIX_STRLEN];
 
        build_type5_prefix_from_ip_prefix(&evp, p);
        ret = delete_evpn_type5_route(bgp_vrf, &evp);
-       if (ret) {
+       if (ret)
                flog_err(
                        EC_BGP_EVPN_ROUTE_DELETE,
-                       "%u failed to delete type-5 route for prefix %s in vrf %s",
-                       bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)),
-                       vrf_id_to_name(bgp_vrf->vrf_id));
-       }
+                       "%u failed to delete type-5 route for prefix %pFX in vrf %s",
+                       bgp_vrf->vrf_id, p, vrf_id_to_name(bgp_vrf->vrf_id));
 }
 
 /* withdraw all type-5 routes for an address family */
@@ -4166,14 +4150,13 @@ void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf, const struct prefix *p,
 {
        int ret = 0;
        struct prefix_evpn evp;
-       char buf[PREFIX_STRLEN];
 
        build_type5_prefix_from_ip_prefix(&evp, p);
        ret = update_evpn_type5_route(bgp_vrf, &evp, src_attr);
        if (ret)
                flog_err(EC_BGP_EVPN_ROUTE_CREATE,
-                        "%u: Failed to create type-5 route for prefix %s",
-                        bgp_vrf->vrf_id, prefix2str(p, buf, sizeof(buf)));
+                        "%u: Failed to create type-5 route for prefix %pFX",
+                        bgp_vrf->vrf_id, p);
 }
 
 /* Inject all prefixes of a particular address-family (currently, IPv4 or
@@ -4593,81 +4576,6 @@ void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json)
        }
 }
 
-/*
- * Function to convert evpn route to string.
- * NOTE: We don't use prefix2str as the output here is a bit different.
- */
-char *bgp_evpn_route2str(const struct prefix_evpn *p, char *buf, int len)
-{
-       char buf1[ETHER_ADDR_STRLEN];
-       char buf2[PREFIX2STR_BUFFER];
-       char buf3[ESI_STR_LEN];
-
-       if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
-               snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
-                        p->prefix.imet_addr.eth_tag,
-                        is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN
-                                                    : IPV6_MAX_BITLEN,
-                        inet_ntoa(p->prefix.imet_addr.ip.ipaddr_v4));
-       } else if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
-               if (is_evpn_prefix_ipaddr_none(p))
-                       snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
-                                p->prefix.route_type,
-                                p->prefix.macip_addr.eth_tag,
-                                8 * ETH_ALEN,
-                                prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
-                                               sizeof(buf1)));
-               else {
-                       uint8_t family;
-
-                       family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET
-                                                            : AF_INET6;
-                       snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
-                                p->prefix.route_type,
-                                p->prefix.macip_addr.eth_tag,
-                                8 * ETH_ALEN,
-                                prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
-                                               sizeof(buf1)),
-                                family == AF_INET ? IPV4_MAX_BITLEN
-                                                  : IPV6_MAX_BITLEN,
-                                inet_ntop(family,
-                                          &p->prefix.macip_addr.ip.ip.addr,
-                                          buf2,
-                                          PREFIX2STR_BUFFER));
-               }
-       } else if (p->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) {
-               snprintf(buf, len, "[%d]:[%d]:[%d]:[%s]",
-                        p->prefix.route_type,
-                        p->prefix.prefix_addr.eth_tag,
-                        p->prefix.prefix_addr.ip_prefix_length,
-                        is_evpn_prefix_ipaddr_v4(p)
-                                ? inet_ntoa(p->prefix.prefix_addr.ip.ipaddr_v4)
-                                : inet6_ntoa(p->prefix.prefix_addr.ip.ipaddr_v6));
-       } else if (p->prefix.route_type == BGP_EVPN_ES_ROUTE) {
-               snprintf(buf, len, "[%d]:[%s]:[%d]:[%s]",
-                        p->prefix.route_type,
-                        esi_to_str(&p->prefix.es_addr.esi, buf3, sizeof(buf3)),
-                        is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN
-                                                    : IPV6_MAX_BITLEN,
-                        inet_ntoa(p->prefix.es_addr.ip.ipaddr_v4));
-       } else if (p->prefix.route_type == BGP_EVPN_AD_ROUTE) {
-               snprintf(buf, len, "[%d]:[%u]:[%s]:[%d]:[%s]",
-                        p->prefix.route_type,
-                        p->prefix.ead_addr.eth_tag,
-                        esi_to_str(&p->prefix.ead_addr.esi,
-                                       buf3, sizeof(buf3)),
-                        is_evpn_prefix_ipaddr_v4(p) ? IPV4_MAX_BITLEN
-                                                    : IPV6_MAX_BITLEN,
-                        inet_ntoa(p->prefix.ead_addr.ip.ipaddr_v4));
-       } else {
-               /* For EVPN route types not supported yet. */
-               snprintf(buf, len, "(unsupported route type %d)",
-                        p->prefix.route_type);
-       }
-
-       return (buf);
-}
-
 /*
  * Encode EVPN prefix in Update (MP_REACH)
  */
@@ -5035,8 +4943,7 @@ void bgp_evpn_derive_auto_rd(struct bgp *bgp, struct bgpevpn *vpn)
 
        vpn->prd.family = AF_UNSPEC;
        vpn->prd.prefixlen = 64;
-       snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id),
-                vpn->rd_id);
+       snprintfrr(buf, sizeof(buf), "%pI4:%hu", &bgp->router_id, vpn->rd_id);
        (void)str2prefix_rd(buf, &vpn->prd);
        UNSET_FLAG(vpn->flags, VNI_FLAG_RD_CFGD);
 }
@@ -5209,7 +5116,7 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
                                                              sizeof(attr_str));
 
                                                zlog_debug(
-                                                       "%u: prefix %pRN with attr %s - DENIED due to martian or self nexthop",
+                                                       "%u: prefix %pBD with attr %s - DENIED due to martian or self nexthop",
                                                        bgp->vrf_id, dest,
                                                        attr_str);
                                        }
index 8535f1fa31e195adc3c2ffcb023f1cd8ed632e91..ba43191ebf356fdb55040f8a31e606c3aa27c178 100644 (file)
@@ -154,8 +154,6 @@ extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf);
 extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
 extern char *bgp_evpn_label2str(mpls_label_t *label, uint32_t num_labels,
                                char *buf, int len);
-extern char *bgp_evpn_route2str(const struct prefix_evpn *p, char *buf,
-                               int len);
 extern void bgp_evpn_route2json(const struct prefix_evpn *p, json_object *json);
 extern void bgp_evpn_encode_prefix(struct stream *s, const struct prefix *p,
                                   const struct prefix_rd *prd,
index 934c22d1687bc02f44de2e7ea0dabe4f0d1f558f..021e811147677e099a92172377ebae9182a85d92 100644 (file)
@@ -29,6 +29,8 @@
 #include "jhash.h"
 #include "zclient.h"
 
+#include "lib/printfrr.h"
+
 #include "bgpd/bgp_attr_evpn.h"
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -52,7 +54,10 @@ static void bgp_evpn_local_es_down(struct bgp *bgp,
 static void bgp_evpn_local_type1_evi_route_del(struct bgp *bgp,
                struct bgp_evpn_es *es);
 static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
-               struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr);
+                                                    struct bgp_evpn_es *es,
+                                                    struct in_addr vtep_ip,
+                                                    bool esr, uint8_t df_alg,
+                                                    uint16_t df_pref);
 static void bgp_evpn_es_vtep_del(struct bgp *bgp,
                struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr);
 static void bgp_evpn_es_cons_checks_pend_add(struct bgp_evpn_es *es);
@@ -82,8 +87,8 @@ esi_t zero_esi_buf, *zero_esi = &zero_esi_buf;
  * installed in the ES's routing table.
  */
 static int bgp_evpn_es_route_select_install(struct bgp *bgp,
-               struct bgp_evpn_es *es,
-               struct bgp_node *rn)
+                                           struct bgp_evpn_es *es,
+                                           struct bgp_dest *dest)
 {
        int ret = 0;
        afi_t afi = AFI_L2VPN;
@@ -93,8 +98,8 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
        struct bgp_path_info_pair old_and_new;
 
        /* Compute the best path. */
-       bgp_best_selection(bgp, rn, &bgp->maxpaths[afi][safi],
-                       &old_and_new, afi, safi);
+       bgp_best_selection(bgp, dest, &bgp->maxpaths[afi][safi], &old_and_new,
+                          afi, safi);
        old_select = old_and_new.old;
        new_select = old_and_new.new;
 
@@ -103,42 +108,45 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
         * updated
         */
        if (old_select && old_select == new_select
-               && old_select->type == ZEBRA_ROUTE_BGP
-               && old_select->sub_type == BGP_ROUTE_IMPORTED
-               && !CHECK_FLAG(rn->flags, BGP_NODE_USER_CLEAR)
-               && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
-               && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
+           && old_select->type == ZEBRA_ROUTE_BGP
+           && old_select->sub_type == BGP_ROUTE_IMPORTED
+           && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
+           && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
+           && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
                if (bgp_zebra_has_route_changed(old_select)) {
-                       bgp_evpn_es_vtep_add(bgp, es,
-                                       old_select->attr->nexthop,
-                                       true /*esr*/);
+                       bgp_evpn_es_vtep_add(bgp, es, old_select->attr->nexthop,
+                                            true /*esr*/,
+                                            old_select->attr->df_alg,
+                                            old_select->attr->df_pref);
                }
                UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
-               bgp_zebra_clear_route_change_flags(rn);
+               bgp_zebra_clear_route_change_flags(dest);
                return ret;
        }
 
        /* If the user did a "clear" this flag will be set */
-       UNSET_FLAG(rn->flags, BGP_NODE_USER_CLEAR);
+       UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR);
 
        /* bestpath has changed; update relevant fields and install or uninstall
         * into the zebra RIB.
         */
        if (old_select || new_select)
-               bgp_bump_version(rn);
+               bgp_bump_version(dest);
 
        if (old_select)
-               bgp_path_info_unset_flag(rn, old_select, BGP_PATH_SELECTED);
+               bgp_path_info_unset_flag(dest, old_select, BGP_PATH_SELECTED);
        if (new_select) {
-               bgp_path_info_set_flag(rn, new_select, BGP_PATH_SELECTED);
-               bgp_path_info_unset_flag(rn, new_select, BGP_PATH_ATTR_CHANGED);
+               bgp_path_info_set_flag(dest, new_select, BGP_PATH_SELECTED);
+               bgp_path_info_unset_flag(dest, new_select,
+                                        BGP_PATH_ATTR_CHANGED);
                UNSET_FLAG(new_select->flags, BGP_PATH_MULTIPATH_CHG);
        }
 
        if (new_select && new_select->type == ZEBRA_ROUTE_BGP
                        && new_select->sub_type == BGP_ROUTE_IMPORTED) {
-               bgp_evpn_es_vtep_add(bgp, es,
-                               new_select->attr->nexthop, true /*esr */);
+               bgp_evpn_es_vtep_add(bgp, es, new_select->attr->nexthop,
+                                    true /*esr */, new_select->attr->df_alg,
+                                    new_select->attr->df_pref);
        } else {
                if (old_select && old_select->type == ZEBRA_ROUTE_BGP
                                && old_select->sub_type == BGP_ROUTE_IMPORTED)
@@ -148,11 +156,11 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
        }
 
        /* Clear any route change flags. */
-       bgp_zebra_clear_route_change_flags(rn);
+       bgp_zebra_clear_route_change_flags(dest);
 
        /* Reap old select bgp_path_info, if it has been removed */
        if (old_select && CHECK_FLAG(old_select->flags, BGP_PATH_REMOVED))
-               bgp_path_info_reap(rn, old_select);
+               bgp_path_info_reap(dest, old_select);
 
        return ret;
 }
@@ -163,17 +171,17 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
                struct bgp_path_info *parent_pi)
 {
        int ret = 0;
-       struct bgp_node *rn = NULL;
+       struct bgp_dest *dest = NULL;
        struct bgp_path_info *pi = NULL;
        struct attr *attr_new = NULL;
 
        /* Create (or fetch) route within the VNI.
         * NOTE: There is no RD here.
         */
-       rn = bgp_node_get(es->route_table, (struct prefix *)p);
+       dest = bgp_node_get(es->route_table, (struct prefix *)p);
 
        /* Check if route entry is already present. */
-       for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next)
+       for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
                if (pi->extra
                                && (struct bgp_path_info *)pi->extra->parent ==
                                parent_pi)
@@ -185,16 +193,16 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
 
                /* Create new route with its attribute. */
                pi = info_make(parent_pi->type, BGP_ROUTE_IMPORTED, 0,
-                               parent_pi->peer, attr_new, rn);
+                              parent_pi->peer, attr_new, dest);
                SET_FLAG(pi->flags, BGP_PATH_VALID);
                bgp_path_info_extra_get(pi);
                pi->extra->parent = bgp_path_info_lock(parent_pi);
-               bgp_dest_lock_node((struct bgp_node *)parent_pi->net);
-               bgp_path_info_add(rn, pi);
+               bgp_dest_lock_node((struct bgp_dest *)parent_pi->net);
+               bgp_path_info_add(dest, pi);
        } else {
                if (attrhash_cmp(pi->attr, parent_pi->attr)
                                && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
-                       bgp_dest_unlock_node(rn);
+                       bgp_dest_unlock_node(dest);
                        return 0;
                }
                /* The attribute has changed. */
@@ -203,7 +211,7 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
 
                /* Restore route, if needed. */
                if (CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
-                       bgp_path_info_restore(rn, pi);
+                       bgp_path_info_restore(dest, pi);
 
                /* Mark if nexthop has changed. */
                if (!IPV4_ADDR_SAME(&pi->attr->nexthop, &attr_new->nexthop))
@@ -216,9 +224,9 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
        }
 
        /* Perform route selection and update zebra, if required. */
-       ret = bgp_evpn_es_route_select_install(bgp, es, rn);
+       ret = bgp_evpn_es_route_select_install(bgp, es, dest);
 
-       bgp_dest_unlock_node(rn);
+       bgp_dest_unlock_node(dest);
 
        return ret;
 }
@@ -228,7 +236,7 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es,
                struct prefix_evpn *p, struct bgp_path_info *parent_pi)
 {
        int ret;
-       struct bgp_node *rn;
+       struct bgp_dest *dest;
        struct bgp_path_info *pi;
 
        if (!es->route_table)
@@ -237,12 +245,12 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es,
        /* Locate route within the ESI.
         * NOTE: There is no RD here.
         */
-       rn = bgp_node_lookup(es->route_table, (struct prefix *)p);
-       if (!rn)
+       dest = bgp_node_lookup(es->route_table, (struct prefix *)p);
+       if (!dest)
                return 0;
 
        /* Find matching route entry. */
-       for (pi = bgp_dest_get_bgp_path_info(rn); pi; pi = pi->next)
+       for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
                if (pi->extra
                                && (struct bgp_path_info *)pi->extra->parent ==
                                parent_pi)
@@ -252,13 +260,13 @@ static int bgp_evpn_es_route_uninstall(struct bgp *bgp, struct bgp_evpn_es *es,
                return 0;
 
        /* Mark entry for deletion */
-       bgp_path_info_delete(rn, pi);
+       bgp_path_info_delete(dest, pi);
 
        /* Perform route selection and update zebra, if required. */
-       ret = bgp_evpn_es_route_select_install(bgp, es, rn);
+       ret = bgp_evpn_es_route_select_install(bgp, es, dest);
 
        /* Unlock route node. */
-       bgp_dest_unlock_node(rn);
+       bgp_dest_unlock_node(dest);
 
        return ret;
 }
@@ -293,7 +301,7 @@ int bgp_evpn_es_route_install_uninstall(struct bgp *bgp, struct bgp_evpn_es *es,
  */
 static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es)
 {
-       struct bgp_node *rn;
+       struct bgp_dest *dest;
        struct bgp_path_info *pi, *nextpi;
 
        /* de-activate the ES */
@@ -301,13 +309,12 @@ static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es)
        bgp_evpn_local_type1_evi_route_del(bgp, es);
 
        /* Walk this ES's routing table and delete all routes. */
-       for (rn = bgp_table_top(es->route_table); rn;
-                       rn = bgp_route_next(rn)) {
-               for (pi = bgp_dest_get_bgp_path_info(rn);
-                               (pi != NULL) && (nextpi = pi->next, 1);
-                               pi = nextpi) {
-                       bgp_path_info_delete(rn, pi);
-                       bgp_path_info_reap(rn, pi);
+       for (dest = bgp_table_top(es->route_table); dest;
+            dest = bgp_route_next(dest)) {
+               for (pi = bgp_dest_get_bgp_path_info(dest);
+                    (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
+                       bgp_path_info_delete(dest, pi);
+                       bgp_path_info_reap(dest, pi);
                }
        }
 }
@@ -327,10 +334,11 @@ static void bgp_evpn_es_route_del_all(struct bgp *bgp, struct bgp_evpn_es *es)
  * Note: vpn is applicable only to EAD-EVI routes (NULL for EAD-ES and
  * ESR).
  */
-static int bgp_evpn_mh_route_update(struct bgp *bgp,
-               struct bgp_evpn_es *es, struct bgpevpn *vpn, afi_t afi,
-               safi_t safi, struct bgp_node *rn, struct attr *attr,
-               int add, struct bgp_path_info **ri, int *route_changed)
+static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
+                                   struct bgpevpn *vpn, afi_t afi, safi_t safi,
+                                   struct bgp_dest *dest, struct attr *attr,
+                                   int add, struct bgp_path_info **ri,
+                                   int *route_changed)
 {
        struct bgp_path_info *tmp_pi = NULL;
        struct bgp_path_info *local_pi = NULL;  /* local route entry if any */
@@ -339,11 +347,11 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp,
        struct prefix_evpn *evp;
 
        *ri = NULL;
-       evp = (struct prefix_evpn *)&rn->p;
+       evp = (struct prefix_evpn *)bgp_dest_get_prefix(dest);
        *route_changed = 1;
 
        /* locate the local and remote entries if any */
-       for (tmp_pi = bgp_dest_get_bgp_path_info(rn); tmp_pi;
+       for (tmp_pi = bgp_dest_get_bgp_path_info(dest); tmp_pi;
             tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                                && tmp_pi->type == ZEBRA_ROUTE_BGP
@@ -361,10 +369,9 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp,
         */
        if (remote_pi) {
                flog_err(
-                               EC_BGP_ES_INVALID,
-                               "%u ERROR: local es route for ESI: %s Vtep %s also learnt from remote",
-                               bgp->vrf_id, es->esi_str,
-                               inet_ntoa(es->originator_ip));
+                       EC_BGP_ES_INVALID,
+                       "%u ERROR: local es route for ESI: %s Vtep %pI4 also learnt from remote",
+                       bgp->vrf_id, es->esi_str, &es->originator_ip);
                return -1;
        }
 
@@ -379,7 +386,7 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp,
 
                /* Create new route with its attribute. */
                tmp_pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
-                               bgp->peer_self, attr_new, rn);
+                                  bgp->peer_self, attr_new, dest);
                SET_FLAG(tmp_pi->flags, BGP_PATH_VALID);
 
                if (evp->prefix.route_type == BGP_EVPN_AD_ROUTE) {
@@ -392,7 +399,7 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp,
                }
 
                /* add the newly created path to the route-node */
-               bgp_path_info_add(rn, tmp_pi);
+               bgp_path_info_add(dest, tmp_pi);
        } else {
                tmp_pi = local_pi;
                if (attrhash_cmp(tmp_pi->attr, attr)
@@ -403,12 +410,12 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp,
                         * Add (or update) attribute to hash.
                         */
                        attr_new = bgp_attr_intern(attr);
-                       bgp_path_info_set_flag(rn, tmp_pi,
-                                       BGP_PATH_ATTR_CHANGED);
+                       bgp_path_info_set_flag(dest, tmp_pi,
+                                              BGP_PATH_ATTR_CHANGED);
 
                        /* Restore route, if needed. */
                        if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED))
-                               bgp_path_info_restore(rn, tmp_pi);
+                               bgp_path_info_restore(dest, tmp_pi);
 
                        /* Unintern existing, set to new. */
                        bgp_attr_unintern(&tmp_pi->attr);
@@ -419,13 +426,13 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp,
 
        if (*route_changed) {
                if (BGP_DEBUG(evpn_mh, EVPN_MH_RT))
-                       zlog_debug("local ES %s vni %u route-type %s nexthop %s updated",
-                                       es->esi_str,
-                                       vpn ? vpn->vni : 0,
-                                       evp->prefix.route_type ==
-                                       BGP_EVPN_ES_ROUTE ? "esr" :
-                                       (vpn ? "ead-evi" : "ead-es"),
-                                       inet_ntoa(attr->mp_nexthop_global_in));
+                       zlog_debug(
+                               "local ES %s vni %u route-type %s nexthop %pI4 updated",
+                               es->esi_str, vpn ? vpn->vni : 0,
+                               evp->prefix.route_type == BGP_EVPN_ES_ROUTE
+                                       ? "esr"
+                                       (vpn ? "ead-evi" : "ead-es"),
+                               &attr->mp_nexthop_global_in);
        }
 
        /* Return back the route entry. */
@@ -444,8 +451,8 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es,
        afi_t afi = AFI_L2VPN;
        safi_t safi = SAFI_EVPN;
        struct bgp_path_info *pi;
-       struct bgp_node *rn = NULL; /* rn in esi table */
-       struct bgp_node *global_rn = NULL; /* rn in global table */
+       struct bgp_dest *dest = NULL;        /* dest in esi table */
+       struct bgp_dest *global_dest = NULL; /* dest in global table */
        struct bgp_table *rt_table;
        struct prefix_rd *prd;
 
@@ -461,51 +468,55 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es,
         * If it doesn't exist, ther is nothing to do.
         * Note: there is no RD here.
         */
-       rn = bgp_node_lookup(rt_table, (struct prefix *)p);
-       if (!rn)
+       dest = bgp_node_lookup(rt_table, (struct prefix *)p);
+       if (!dest)
                return 0;
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_RT))
-               zlog_debug("local ES %s vni %u route-type %s nexthop %s delete",
-                               es->esi_str,
-                               vpn ? vpn->vni : 0,
-                               p->prefix.route_type == BGP_EVPN_ES_ROUTE ?
-                               "esr" : (vpn ? "ead-evi" : "ead-es"),
-                               inet_ntoa(es->originator_ip));
+               zlog_debug(
+                       "local ES %s vni %u route-type %s nexthop %pI4 delete",
+                       es->esi_str, vpn ? vpn->vni : 0,
+                       p->prefix.route_type == BGP_EVPN_ES_ROUTE
+                               ? "esr"
+                               : (vpn ? "ead-evi" : "ead-es"),
+                       &es->originator_ip);
 
        /* Next, locate route node in the global EVPN routing table.
         * Note that this table is a 2-level tree (RD-level + Prefix-level)
         */
-       global_rn = bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi,
-                       (const struct prefix_evpn *)p, prd);
-       if (global_rn) {
+       global_dest =
+               bgp_global_evpn_node_lookup(bgp->rib[afi][safi], afi, safi,
+                                           (const struct prefix_evpn *)p, prd);
+       if (global_dest) {
 
                /* Delete route entry in the global EVPN table. */
-               delete_evpn_route_entry(bgp, afi, safi, global_rn, &pi);
+               delete_evpn_route_entry(bgp, afi, safi, global_dest, &pi);
 
                /* Schedule for processing - withdraws to peers happen from
                 * this table.
                 */
                if (pi)
-                       bgp_process(bgp, global_rn, afi, safi);
-               bgp_dest_unlock_node(global_rn);
+                       bgp_process(bgp, global_dest, afi, safi);
+               bgp_dest_unlock_node(global_dest);
        }
 
        /*
         * Delete route entry in the ESI or VNI routing table.
         * This can just be removed.
         */
-       delete_evpn_route_entry(bgp, afi, safi, rn, &pi);
+       delete_evpn_route_entry(bgp, afi, safi, dest, &pi);
        if (pi)
-               bgp_path_info_reap(rn, pi);
-       bgp_dest_unlock_node(rn);
+               bgp_path_info_reap(dest, pi);
+       bgp_dest_unlock_node(dest);
        return 0;
 }
 
 /*****************************************************************************
  * Ethernet Segment (Type-4) Routes
- * ESRs are used for BUM handling. XXX - BUM support is planned for phase-2 i.e.
- * this code is just a place holder for now
+ * ESRs are used for DF election. Currently service-carving described in
+ * RFC 7432 is NOT supported. Instead preference based DF election is
+ * used by default.
+ * Reference: draft-ietf-bess-evpn-pref-df
  */
 /* Build extended community for EVPN ES (type-4) route */
 static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es,
@@ -513,8 +524,10 @@ static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es,
 {
        struct ecommunity ecom_encap;
        struct ecommunity ecom_es_rt;
+       struct ecommunity ecom_df;
        struct ecommunity_val eval;
        struct ecommunity_val eval_es_rt;
+       struct ecommunity_val eval_df;
        bgp_encap_types tnl_type;
        struct ethaddr mac;
 
@@ -538,6 +551,13 @@ static void bgp_evpn_type4_route_extcomm_build(struct bgp_evpn_es *es,
        attr->ecommunity =
                ecommunity_merge(attr->ecommunity, &ecom_es_rt);
 
+       /* DF election extended community */
+       memset(&ecom_df, 0, sizeof(ecom_df));
+       encode_df_elect_extcomm(&eval_df, es->df_pref);
+       ecom_df.size = 1;
+       ecom_df.val = (uint8_t *)eval_df.val;
+       attr->ecommunity = ecommunity_merge(attr->ecommunity, &ecom_df);
+
        attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
 }
 
@@ -551,7 +571,7 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp,
        safi_t safi = SAFI_EVPN;
        struct attr attr;
        struct attr *attr_new = NULL;
-       struct bgp_node *rn = NULL;
+       struct bgp_dest *dest = NULL;
        struct bgp_path_info *pi = NULL;
 
        memset(&attr, 0, sizeof(struct attr));
@@ -567,17 +587,16 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp,
 
        /* First, create (or fetch) route node within the ESI. */
        /* NOTE: There is no RD here. */
-       rn = bgp_node_get(es->route_table, (struct prefix *)p);
+       dest = bgp_node_get(es->route_table, (struct prefix *)p);
 
        /* Create or update route entry. */
-       ret = bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi,
-                       rn, &attr, 1, &pi, &route_changed);
-       if (ret != 0) {
-               flog_err(EC_BGP_ES_INVALID,
-                               "%u ERROR: Failed to updated ES route ESI: %s VTEP %s",
-                               bgp->vrf_id, es->esi_str,
-                               inet_ntoa(es->originator_ip));
-       }
+       ret = bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi, dest, &attr, 1,
+                                      &pi, &route_changed);
+       if (ret != 0)
+               flog_err(
+                       EC_BGP_ES_INVALID,
+                       "%u ERROR: Failed to updated ES route ESI: %s VTEP %pI4",
+                       bgp->vrf_id, es->esi_str, &es->originator_ip);
 
        assert(pi);
        attr_new = pi->attr;
@@ -586,8 +605,8 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp,
         * this is just to set the flags correctly
         * as local route in the ES always wins.
         */
-       bgp_evpn_es_route_select_install(bgp, es, rn);
-       bgp_dest_unlock_node(rn);
+       bgp_evpn_es_route_select_install(bgp, es, dest);
+       bgp_dest_unlock_node(dest);
 
        /* If this is a new route or some attribute has changed, export the
         * route to the global table. The route will be advertised to peers
@@ -597,14 +616,15 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp,
        if (route_changed) {
                struct bgp_path_info *global_pi;
 
-               rn = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
-                               p, &es->prd);
-               bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi,
-                               rn, attr_new, 1, &global_pi, &route_changed);
+               dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
+                                               p, &es->prd);
+               bgp_evpn_mh_route_update(bgp, es, NULL, afi, safi, dest,
+                                        attr_new, 1, &global_pi,
+                                        &route_changed);
 
                /* Schedule for processing and unlock node. */
-               bgp_process(bgp, rn, afi, safi);
-               bgp_dest_unlock_node(rn);
+               bgp_process(bgp, dest, afi, safi);
+               bgp_dest_unlock_node(dest);
        }
 
        /* Unintern temporary. */
@@ -694,8 +714,7 @@ static int bgp_evpn_type4_remote_routes_import(struct bgp *bgp,
        int ret;
        afi_t afi;
        safi_t safi;
-       char buf[PREFIX_STRLEN];
-       struct bgp_node *rd_rn, *rn;
+       struct bgp_dest *rd_dest, *dest;
        struct bgp_table *table;
        struct bgp_path_info *pi;
 
@@ -705,17 +724,19 @@ static int bgp_evpn_type4_remote_routes_import(struct bgp *bgp,
        /* Walk entire global routing table and evaluate routes which could be
         * imported into this Ethernet Segment.
         */
-       for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
-                       rd_rn = bgp_route_next(rd_rn)) {
-               table = bgp_dest_get_bgp_table_info(rd_rn);
+       for (rd_dest = bgp_table_top(bgp->rib[afi][safi]); rd_dest;
+            rd_dest = bgp_route_next(rd_dest)) {
+               table = bgp_dest_get_bgp_table_info(rd_dest);
                if (!table)
                        continue;
 
-               for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
+               for (dest = bgp_table_top(table); dest;
+                    dest = bgp_route_next(dest)) {
+                       struct prefix_evpn *evp =
+                               (struct prefix_evpn *)bgp_dest_get_prefix(dest);
 
-                       for (pi = bgp_dest_get_bgp_path_info(rn); pi;
-                                       pi = pi->next) {
+                       for (pi = bgp_dest_get_bgp_path_info(dest); pi;
+                            pi = pi->next) {
                                /*
                                 * Consider "valid" remote routes applicable for
                                 * this ES.
@@ -737,13 +758,11 @@ static int bgp_evpn_type4_remote_routes_import(struct bgp *bgp,
 
                                if (ret) {
                                        flog_err(
-                                                       EC_BGP_EVPN_FAIL,
-                                                       "Failed to %s EVPN %s route in ESI %s",
-                                                       install ? "install"
+                                               EC_BGP_EVPN_FAIL,
+                                               "Failed to %s EVPN %pFX route in ESI %s",
+                                               install ? "install"
                                                        : "uninstall",
-                                                       prefix2str(evp, buf,
-                                                               sizeof(buf)),
-                                                       es->esi_str);
+                                               evp, es->esi_str);
                                        return ret;
                                }
                        }
@@ -845,7 +864,7 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
        safi_t safi = SAFI_EVPN;
        struct attr attr;
        struct attr *attr_new = NULL;
-       struct bgp_node *rn = NULL;
+       struct bgp_dest *dest = NULL;
        struct bgp_path_info *pi = NULL;
        int route_changed = 0;
        struct prefix_rd *global_rd;
@@ -867,17 +886,17 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
                bgp_evpn_type1_evi_route_extcomm_build(es, vpn, &attr);
 
                /* First, create (or fetch) route node within the VNI. */
-               rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
+               dest = bgp_node_get(vpn->route_table, (struct prefix *)p);
 
                /* Create or update route entry. */
-               ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi,
-                               rn, &attr, 1, &pi, &route_changed);
-               if (ret != 0) {
-                       flog_err(EC_BGP_ES_INVALID,
-                                       "%u Failed to update EAD-EVI route ESI: %s VNI %u VTEP %s",
-                                       bgp->vrf_id, es->esi_str, vpn->vni,
-                                       inet_ntoa(es->originator_ip));
-               }
+               ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, dest,
+                                              &attr, 1, &pi, &route_changed);
+               if (ret != 0)
+                       flog_err(
+                               EC_BGP_ES_INVALID,
+                               "%u Failed to update EAD-EVI route ESI: %s VNI %u VTEP %pI4",
+                               bgp->vrf_id, es->esi_str, vpn->vni,
+                               &es->originator_ip);
                global_rd = &vpn->prd;
        } else {
                /* EAD-ES route update */
@@ -889,16 +908,16 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
                /* First, create (or fetch) route node within the ES. */
                /* NOTE: There is no RD here. */
                /* XXX: fragment ID must be included as a part of the prefix. */
-               rn = bgp_node_get(es->route_table, (struct prefix *)p);
+               dest = bgp_node_get(es->route_table, (struct prefix *)p);
 
                /* Create or update route entry. */
-               ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi,
-                               rn, &attr, 1, &pi, &route_changed);
+               ret = bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, dest,
+                                              &attr, 1, &pi, &route_changed);
                if (ret != 0) {
-                       flog_err(EC_BGP_ES_INVALID,
-                                       "%u ERROR: Failed to updated EAD-EVI route ESI: %s VTEP %s",
-                                       bgp->vrf_id, es->esi_str,
-                                       inet_ntoa(es->originator_ip));
+                       flog_err(
+                               EC_BGP_ES_INVALID,
+                               "%u ERROR: Failed to updated EAD-EVI route ESI: %s VTEP %pI4",
+                               bgp->vrf_id, es->esi_str, &es->originator_ip);
                }
                global_rd = &es->prd;
        }
@@ -911,8 +930,8 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
         * this is just to set the flags correctly as local route in
         * the ES always wins.
         */
-       evpn_route_select_install(bgp, vpn, rn);
-       bgp_dest_unlock_node(rn);
+       evpn_route_select_install(bgp, vpn, dest);
+       bgp_dest_unlock_node(dest);
 
        /* If this is a new route or some attribute has changed, export the
         * route to the global table. The route will be advertised to peers
@@ -922,14 +941,15 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
        if (route_changed) {
                struct bgp_path_info *global_pi;
 
-               rn = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
-                               p, global_rd);
-               bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi,
-                               rn, attr_new, 1, &global_pi, &route_changed);
+               dest = bgp_global_evpn_node_get(bgp->rib[afi][safi], afi, safi,
+                                               p, global_rd);
+               bgp_evpn_mh_route_update(bgp, es, vpn, afi, safi, dest,
+                                        attr_new, 1, &global_pi,
+                                        &route_changed);
 
                /* Schedule for processing and unlock node. */
-               bgp_process(bgp, rn, afi, safi);
-               bgp_dest_unlock_node(rn);
+               bgp_process(bgp, dest, afi, safi);
+               bgp_dest_unlock_node(dest);
        }
 
        /* Unintern temporary. */
@@ -1136,6 +1156,7 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp,
 {
        struct bgp_evpn_es *es = es_vtep->es;
        struct stream *s;
+       uint32_t flags = 0;
 
        /* Check socket. */
        if (!zclient || zclient->sock < 0)
@@ -1149,6 +1170,9 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp,
                return 0;
        }
 
+       if (es_vtep->flags & BGP_EVPNES_VTEP_ESR)
+               flags |= ZAPI_ES_VTEP_FLAG_ESR_RXED;
+
        s = zclient->obuf;
        stream_reset(s);
 
@@ -1157,19 +1181,24 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp,
                bgp->vrf_id);
        stream_put(s, &es->esi, sizeof(esi_t));
        stream_put_ipv4(s, es_vtep->vtep_ip.s_addr);
+       if (add) {
+               stream_putl(s, flags);
+               stream_putc(s, es_vtep->df_alg);
+               stream_putw(s, es_vtep->df_pref);
+       }
 
        stream_putw_at(s, 0, stream_get_endp(s));
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("Tx %s Remote ESI %s VTEP %s",
-                               add ? "ADD" : "DEL", es->esi_str,
-                               inet_ntoa(es_vtep->vtep_ip));
+               zlog_debug("Tx %s Remote ESI %s VTEP %pI4", add ? "ADD" : "DEL",
+                          es->esi_str, &es_vtep->vtep_ip);
 
        return zclient_send_message(zclient);
 }
 
 static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
-               struct bgp_evpn_es_vtep *es_vtep)
+                                           struct bgp_evpn_es_vtep *es_vtep,
+                                           bool param_change)
 {
        bool old_active;
        bool new_active;
@@ -1185,26 +1214,30 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
 
        new_active = !!CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
 
-       if (old_active == new_active)
-               return;
+       if ((old_active != new_active) || (new_active && param_change)) {
 
-       if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("es %s vtep %s %s",
-                               es_vtep->es->esi_str,
-                               inet_ntoa(es_vtep->vtep_ip),
-                               new_active ? "active" : "inactive");
+               if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
+                       zlog_debug("es %s vtep %pI4 %s df %u/%u",
+                                  es_vtep->es->esi_str, &es_vtep->vtep_ip,
+                                  new_active ? "active" : "inactive",
+                                  es_vtep->df_alg, es_vtep->df_pref);
 
-       /* send remote ES to zebra */
-       bgp_zebra_send_remote_es_vtep(bgp, es_vtep, new_active);
+               /* send remote ES to zebra */
+               bgp_zebra_send_remote_es_vtep(bgp, es_vtep, new_active);
 
-       /* queue up the es for background consistency checks */
-       bgp_evpn_es_cons_checks_pend_add(es_vtep->es);
+               /* queue up the es for background consistency checks */
+               bgp_evpn_es_cons_checks_pend_add(es_vtep->es);
+       }
 }
 
 static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
-               struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr)
+                                                    struct bgp_evpn_es *es,
+                                                    struct in_addr vtep_ip,
+                                                    bool esr, uint8_t df_alg,
+                                                    uint16_t df_pref)
 {
        struct bgp_evpn_es_vtep *es_vtep;
+       bool param_change = false;
 
        es_vtep = bgp_evpn_es_vtep_find(es, vtep_ip);
 
@@ -1212,17 +1245,23 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
                es_vtep = bgp_evpn_es_vtep_new(es, vtep_ip);
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("es %s vtep %s add %s",
-                               es_vtep->es->esi_str,
-                               inet_ntoa(es_vtep->vtep_ip),
-                               esr ? "esr" : "ead");
+               zlog_debug("es %s vtep %pI4 add %s df %u/%u",
+                          es_vtep->es->esi_str, &es_vtep->vtep_ip,
+                          esr ? "esr" : "ead", df_alg, df_pref);
 
-       if (esr)
+       if (esr) {
                SET_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ESR);
-       else
+               if ((es_vtep->df_pref != df_pref)
+                   || (es_vtep->df_alg != df_alg)) {
+                       param_change = true;
+                       es_vtep->df_pref = df_pref;
+                       es_vtep->df_alg = df_alg;
+               }
+       } else {
                ++es_vtep->evi_cnt;
+       }
 
-       bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep);
+       bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change);
 
        return es_vtep;
 }
@@ -1230,19 +1269,24 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
 static void bgp_evpn_es_vtep_do_del(struct bgp *bgp,
                struct bgp_evpn_es_vtep *es_vtep, bool esr)
 {
+       bool param_change = false;
+
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("es %s vtep %s del %s",
-                               es_vtep->es->esi_str,
-                               inet_ntoa(es_vtep->vtep_ip),
-                               esr ? "esr" : "ead");
+               zlog_debug("es %s vtep %pI4 del %s", es_vtep->es->esi_str,
+                          &es_vtep->vtep_ip, esr ? "esr" : "ead");
        if (esr) {
                UNSET_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ESR);
+               if (es_vtep->df_pref || es_vtep->df_alg) {
+                       param_change = true;
+                       es_vtep->df_pref = 0;
+                       es_vtep->df_alg = 0;
+               }
        } else {
                if (es_vtep->evi_cnt)
                        --es_vtep->evi_cnt;
        }
 
-       bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep);
+       bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change);
        bgp_evpn_es_vtep_free(es_vtep);
 }
 
@@ -1313,11 +1357,14 @@ static struct bgp_evpn_es *bgp_evpn_es_new(struct bgp *bgp, const esi_t *esi)
  * This just frees appropriate memory, caller should have taken other
  * needed actions.
  */
-static void bgp_evpn_es_free(struct bgp_evpn_es *es)
+static void bgp_evpn_es_free(struct bgp_evpn_es *es, const char *caller)
 {
        if (es->flags & (BGP_EVPNES_LOCAL | BGP_EVPNES_REMOTE))
                return;
 
+       if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
+               zlog_debug("%s: es %s free", caller, es->esi_str);
+
        /* cleanup resources maintained against the ES */
        list_delete(&es->es_evi_list);
        list_delete(&es->es_vtep_list);
@@ -1347,8 +1394,7 @@ static void bgp_evpn_es_local_info_set(struct bgp *bgp, struct bgp_evpn_es *es)
        bf_assign_index(bm->rd_idspace, es->rd_id);
        es->prd.family = AF_UNSPEC;
        es->prd.prefixlen = 64;
-       snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(bgp->router_id),
-                es->rd_id);
+       snprintfrr(buf, sizeof(buf), "%pI4:%hu", &bgp->router_id, es->rd_id);
        (void)str2prefix_rd(buf, &es->prd);
 }
 
@@ -1365,7 +1411,7 @@ static void bgp_evpn_es_local_info_clear(struct bgp_evpn_es *es)
 
        bf_release_index(bm->rd_idspace, es->rd_id);
 
-       bgp_evpn_es_free(es);
+       bgp_evpn_es_free(es, __func__);
 }
 
 /* eval remote info associated with the ES */
@@ -1376,7 +1422,7 @@ static void bgp_evpn_es_remote_info_re_eval(struct bgp_evpn_es *es)
        } else {
                if (CHECK_FLAG(es->flags, BGP_EVPNES_REMOTE)) {
                        UNSET_FLAG(es->flags, BGP_EVPNES_REMOTE);
-                       bgp_evpn_es_free(es);
+                       bgp_evpn_es_free(es, __func__);
                }
        }
 }
@@ -1422,32 +1468,43 @@ static void bgp_evpn_local_es_down(struct bgp *bgp,
 }
 
 /* Process ES link oper-up by generating ES-EAD and ESR */
-static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es)
+static void bgp_evpn_local_es_up(struct bgp *bgp, struct bgp_evpn_es *es,
+                                bool regen_esr)
 {
        struct prefix_evpn p;
+       bool regen_ead = false;
 
-       if (CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP))
-               return;
-
-       SET_FLAG(es->flags, BGP_EVPNES_OPER_UP);
+       if (!CHECK_FLAG(es->flags, BGP_EVPNES_OPER_UP)) {
+               if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
+                       zlog_debug("local es %s up", es->esi_str);
 
-       if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("local es %s up", es->esi_str);
+               SET_FLAG(es->flags, BGP_EVPNES_OPER_UP);
+               regen_esr = true;
+               regen_ead = true;
+       }
 
-       /* generate ESR */
-       build_evpn_type4_prefix(&p, &es->esi, es->originator_ip);
-       if (bgp_evpn_type4_route_update(bgp, es, &p))
-               flog_err(EC_BGP_EVPN_ROUTE_CREATE,
-                               "%u: Type4 route creation failure for ESI %s",
-                               bgp->vrf_id, es->esi_str);
+       if (regen_esr) {
+               if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
+                       zlog_debug("local es %s generate ESR", es->esi_str);
+               /* generate ESR */
+               build_evpn_type4_prefix(&p, &es->esi, es->originator_ip);
+               if (bgp_evpn_type4_route_update(bgp, es, &p))
+                       flog_err(EC_BGP_EVPN_ROUTE_CREATE,
+                                "%u: Type4 route creation failure for ESI %s",
+                                bgp->vrf_id, es->esi_str);
+       }
 
-       /* generate EAD-EVI */
-       bgp_evpn_local_type1_evi_route_add(bgp, es);
+       if (regen_ead) {
+               if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
+                       zlog_debug("local es %s generate EAD", es->esi_str);
+               /* generate EAD-EVI */
+               bgp_evpn_local_type1_evi_route_add(bgp, es);
 
-       /* generate EAD-ES */
-       build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG,
-                       &es->esi, es->originator_ip);
-       bgp_evpn_type1_route_update(bgp, es, NULL, &p);
+               /* generate EAD-ES */
+               build_evpn_type1_prefix(&p, BGP_EVPN_AD_ES_ETH_TAG, &es->esi,
+                                       es->originator_ip);
+               bgp_evpn_type1_route_update(bgp, es, NULL, &p);
+       }
 }
 
 static void bgp_evpn_local_es_do_del(struct bgp *bgp, struct bgp_evpn_es *es)
@@ -1505,11 +1562,13 @@ int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi)
  * ES.
  */
 int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
-               struct in_addr originator_ip, bool oper_up)
+                         struct in_addr originator_ip, bool oper_up,
+                         uint16_t df_pref)
 {
        char buf[ESI_STR_LEN];
        struct bgp_evpn_es *es;
        bool new_es = true;
+       bool regen_esr = false;
 
        /* create the new es */
        es = bgp_evpn_es_find(esi);
@@ -1527,11 +1586,14 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
        }
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("add local es %s orig-ip %s",
-                               es->esi_str,
-                               inet_ntoa(originator_ip));
+               zlog_debug("add local es %s orig-ip %pI4 df_pref %u", es->esi_str,
+                          &originator_ip, df_pref);
 
        es->originator_ip = originator_ip;
+       if (df_pref != es->df_pref) {
+               es->df_pref = df_pref;
+               regen_esr = true;
+       }
        bgp_evpn_es_local_info_set(bgp, es);
 
        /* import all remote Type-4 routes in the ES table */
@@ -1550,7 +1612,7 @@ int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
         * can be generated even if the link is inactive.
         */
        if (oper_up)
-               bgp_evpn_local_es_up(bgp, es);
+               bgp_evpn_local_es_up(bgp, es, regen_esr);
        else
                bgp_evpn_local_es_down(bgp, es);
 
@@ -1564,10 +1626,12 @@ static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es,
        struct listnode *node;
        struct bgp_evpn_es_vtep *es_vtep;
        bool first = true;
+       char ip_buf[INET6_ADDRSTRLEN];
 
        vtep_str[0] = '\0';
        for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) {
                vtep_flag_str[0] = '\0';
+
                if (es_vtep->flags & BGP_EVPNES_VTEP_ESR)
                        strlcat(vtep_flag_str, "E", sizeof(vtep_flag_str));
                if (es_vtep->flags & BGP_EVPNES_VTEP_ACTIVE)
@@ -1579,7 +1643,10 @@ static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es,
                        first = false;
                else
                        strlcat(vtep_str, ",", vtep_str_size);
-               strlcat(vtep_str, inet_ntoa(es_vtep->vtep_ip), vtep_str_size);
+               strlcat(vtep_str,
+                       inet_ntop(AF_INET, &es_vtep->vtep_ip, ip_buf,
+                                 sizeof(ip_buf)),
+                       vtep_str_size);
                strlcat(vtep_str, "(", vtep_str_size);
                strlcat(vtep_str, vtep_flag_str, vtep_str_size);
                strlcat(vtep_str, ")", vtep_str_size);
@@ -1588,21 +1655,18 @@ static char *bgp_evpn_es_vteps_str(char *vtep_str, struct bgp_evpn_es *es,
        return vtep_str;
 }
 
-static inline void json_array_string_add(json_object *json, const char *str)
-{
-       json_object_array_add(json, json_object_new_string(str));
-}
-
 static void bgp_evpn_es_json_vtep_fill(json_object *json_vteps,
                struct bgp_evpn_es_vtep *es_vtep)
 {
        json_object *json_vtep_entry;
        json_object *json_flags;
+       char ip_buf[INET6_ADDRSTRLEN];
 
        json_vtep_entry = json_object_new_object();
 
-       json_object_string_add(json_vtep_entry, "vtep_ip",
-                       inet_ntoa(es_vtep->vtep_ip));
+       json_object_string_add(
+               json_vtep_entry, "vtep_ip",
+               inet_ntop(AF_INET, &es_vtep->vtep_ip, ip_buf, sizeof(ip_buf)));
        if (es_vtep->flags & (BGP_EVPNES_VTEP_ESR |
                         BGP_EVPNES_VTEP_ACTIVE)) {
                json_flags = json_object_new_array();
@@ -1611,12 +1675,49 @@ static void bgp_evpn_es_json_vtep_fill(json_object *json_vteps,
                if (es_vtep->flags & BGP_EVPNES_VTEP_ACTIVE)
                        json_array_string_add(json_flags, "active");
                json_object_object_add(json_vtep_entry, "flags", json_flags);
+               if (es_vtep->flags & BGP_EVPNES_VTEP_ESR) {
+                       json_object_int_add(json_vtep_entry, "dfPreference",
+                                           es_vtep->df_pref);
+                       json_object_int_add(json_vtep_entry, "dfAlgorithm",
+                                           es_vtep->df_pref);
+               }
        }
 
        json_object_array_add(json_vteps,
                        json_vtep_entry);
 }
 
+static void bgp_evpn_es_vteps_show_detail(struct vty *vty,
+                                         struct bgp_evpn_es *es)
+{
+       char vtep_flag_str[BGP_EVPN_FLAG_STR_SZ];
+       struct listnode *node;
+       struct bgp_evpn_es_vtep *es_vtep;
+       char alg_buf[EVPN_DF_ALG_STR_LEN];
+
+       for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) {
+               vtep_flag_str[0] = '\0';
+               if (es_vtep->flags & BGP_EVPNES_VTEP_ESR)
+                       strlcat(vtep_flag_str, "E", sizeof(vtep_flag_str));
+               if (es_vtep->flags & BGP_EVPNES_VTEP_ACTIVE)
+                       strlcat(vtep_flag_str, "A", sizeof(vtep_flag_str));
+
+               if (!strlen(vtep_flag_str))
+                       strlcat(vtep_flag_str, "-", sizeof(vtep_flag_str));
+
+               vty_out(vty, "  %pI4 flags: %s", &es_vtep->vtep_ip,
+                       vtep_flag_str);
+
+               if (es_vtep->flags & BGP_EVPNES_VTEP_ESR)
+                       vty_out(vty, " df_alg: %s df_pref: %u\n",
+                               evpn_es_df_alg2str(es_vtep->df_alg, alg_buf,
+                                                  sizeof(alg_buf)),
+                               es_vtep->df_pref);
+               else
+                       vty_out(vty, "\n");
+       }
+}
+
 static void bgp_evpn_es_show_entry(struct vty *vty,
                struct bgp_evpn_es *es, json_object *json)
 {
@@ -1680,9 +1781,14 @@ static void bgp_evpn_es_show_entry(struct vty *vty,
 static void bgp_evpn_es_show_entry_detail(struct vty *vty,
                struct bgp_evpn_es *es, json_object *json)
 {
+       char ip_buf[INET6_ADDRSTRLEN];
+
        if (json) {
                json_object *json_flags;
                json_object *json_incons;
+               json_object *json_vteps;
+               struct listnode *node;
+               struct bgp_evpn_es_vtep *es_vtep;
 
                /* Add the "brief" info first */
                bgp_evpn_es_show_entry(vty, es, json);
@@ -1696,11 +1802,20 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
                        json_object_object_add(json, "flags", json_flags);
                }
                json_object_string_add(json, "originator_ip",
-                               inet_ntoa(es->originator_ip));
+                                      inet_ntop(AF_INET, &es->originator_ip,
+                                                ip_buf, sizeof(ip_buf)));
                json_object_int_add(json, "remoteVniCount",
                                es->remote_es_evi_cnt);
                json_object_int_add(json, "inconsistentVniVtepCount",
                                es->incons_evi_vtep_cnt);
+               if (listcount(es->es_vtep_list)) {
+                       json_vteps = json_object_new_array();
+                       for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node,
+                                                 es_vtep)) {
+                               bgp_evpn_es_json_vtep_fill(json_vteps, es_vtep);
+                       }
+                       json_object_object_add(json, "vteps", json_vteps);
+               }
                if (es->inconsistencies) {
                        json_incons = json_object_new_array();
                        if (es->inconsistencies & BGP_EVPNES_INCONS_VTEP_LIST)
@@ -1712,7 +1827,6 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
        } else {
                char incons_str[BGP_EVPNES_INCONS_STR_SZ];
                char type_str[4];
-               char vtep_str[ES_VTEP_LIST_STR_SZ + BGP_EVPN_VTEPS_FLAG_STR_SZ];
                char buf1[RD_ADDRSTRLEN];
 
                type_str[0] = '\0';
@@ -1721,10 +1835,6 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
                if (es->flags & BGP_EVPNES_REMOTE)
                        strlcat(type_str, "R", sizeof(type_str));
 
-               bgp_evpn_es_vteps_str(vtep_str, es, sizeof(vtep_str));
-               if (!strlen(vtep_str))
-                       strlcpy(buf1, "-", sizeof(buf1));
-
                if (es->flags & BGP_EVPNES_LOCAL)
                        prefix_rd2str(&es->prd, buf1, sizeof(buf1));
                else
@@ -1733,8 +1843,10 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
                vty_out(vty, "ESI: %s\n", es->esi_str);
                vty_out(vty, " Type: %s\n", type_str);
                vty_out(vty, " RD: %s\n", buf1);
-               vty_out(vty, " Originator-IP: %s\n",
-                               inet_ntoa(es->originator_ip));
+               vty_out(vty, " Originator-IP: %pI4\n", &es->originator_ip);
+               if (es->flags & BGP_EVPNES_LOCAL)
+                       vty_out(vty, " Local ES DF preference: %u\n",
+                               es->df_pref);
                vty_out(vty, " VNI Count: %d\n", listcount(es->es_evi_list));
                vty_out(vty, " Remote VNI Count: %d\n",
                                es->remote_es_evi_cnt);
@@ -1750,7 +1862,10 @@ static void bgp_evpn_es_show_entry_detail(struct vty *vty,
                }
                vty_out(vty, " Inconsistencies: %s\n",
                                incons_str);
-               vty_out(vty, " VTEPs: %s\n", vtep_str);
+               if (listcount(es->es_vtep_list)) {
+                       vty_out(vty, " VTEPs:\n");
+                       bgp_evpn_es_vteps_show_detail(vty, es);
+               }
                vty_out(vty, "\n");
        }
 }
@@ -1913,18 +2028,18 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
                return;
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("es %s evi %u vtep %s %s",
-                               evi_vtep->es_evi->es->esi_str,
-                               evi_vtep->es_evi->vpn->vni,
-                               inet_ntoa(evi_vtep->vtep_ip),
-                               new_active ? "active" : "inactive");
+               zlog_debug("es %s evi %u vtep %pI4 %s",
+                          evi_vtep->es_evi->es->esi_str,
+                          evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip,
+                          new_active ? "active" : "inactive");
 
        /* add VTEP to parent es */
        if (new_active) {
                struct bgp_evpn_es_vtep *es_vtep;
 
                es_vtep = bgp_evpn_es_vtep_add(bgp, evi_vtep->es_evi->es,
-                               evi_vtep->vtep_ip, false /*esr*/);
+                                              evi_vtep->vtep_ip, false /*esr*/,
+                                              0, 0);
                evi_vtep->es_vtep = es_vtep;
        } else {
                if (evi_vtep->es_vtep) {
@@ -1949,11 +2064,10 @@ static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp,
                evi_vtep = bgp_evpn_es_evi_vtep_new(es_evi, vtep_ip);
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("add es %s evi %u vtep %s %s",
-                               evi_vtep->es_evi->es->esi_str,
-                               evi_vtep->es_evi->vpn->vni,
-                               inet_ntoa(evi_vtep->vtep_ip),
-                               ead_es ? "ead_es" : "ead_evi");
+               zlog_debug("add es %s evi %u vtep %pI4 %s",
+                          evi_vtep->es_evi->es->esi_str,
+                          evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip,
+                          ead_es ? "ead_es" : "ead_evi");
 
        if (ead_es)
                SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_ES);
@@ -1974,11 +2088,10 @@ static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp,
                return;
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("del es %s evi %u vtep %s %s",
-                               evi_vtep->es_evi->es->esi_str,
-                               evi_vtep->es_evi->vpn->vni,
-                               inet_ntoa(evi_vtep->vtep_ip),
-                               ead_es ? "ead_es" : "ead_evi");
+               zlog_debug("del es %s evi %u vtep %pI4 %s",
+                          evi_vtep->es_evi->es->esi_str,
+                          evi_vtep->es_evi->vpn->vni, &evi_vtep->vtep_ip,
+                          ead_es ? "ead_es" : "ead_evi");
 
        if (ead_es)
                UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_ES);
@@ -2290,13 +2403,10 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
                return 0;
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("add remote %s es %s evi %u vtep %s",
-                               p->prefix.ead_addr.eth_tag ?
-                               "ead-es" : "ead-evi",
-                               esi_to_str(esi, buf,
-                                       sizeof(buf)),
-                               vpn->vni,
-                               inet_ntoa(p->prefix.ead_addr.ip.ipaddr_v4));
+               zlog_debug("add remote %s es %s evi %u vtep %pI4",
+                          p->prefix.ead_addr.eth_tag ? "ead-es" : "ead-evi",
+                          esi_to_str(esi, buf, sizeof(buf)), vpn->vni,
+                          &p->prefix.ead_addr.ip.ipaddr_v4);
 
        es = bgp_evpn_es_find(esi);
        if (!es) {
@@ -2313,7 +2423,7 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
        if (!es_evi) {
                es_evi = bgp_evpn_es_evi_new(es, vpn);
                if (!es_evi) {
-                       bgp_evpn_es_free(es);
+                       bgp_evpn_es_free(es, __func__);
                        return -1;
                }
        }
@@ -2342,13 +2452,11 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
                return 0;
 
        if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
-               zlog_debug("del remote %s es %s evi %u vtep %s",
-                               p->prefix.ead_addr.eth_tag ?
-                               "ead-es" : "ead-evi",
-                               esi_to_str(&p->prefix.ead_addr.esi, buf,
-                                       sizeof(buf)),
-                               vpn->vni,
-                               inet_ntoa(p->prefix.ead_addr.ip.ipaddr_v4));
+               zlog_debug(
+                       "del remote %s es %s evi %u vtep %pI4",
+                       p->prefix.ead_addr.eth_tag ? "ead-es" : "ead-evi",
+                       esi_to_str(&p->prefix.ead_addr.esi, buf, sizeof(buf)),
+                       vpn->vni, &p->prefix.ead_addr.ip.ipaddr_v4);
 
        es = bgp_evpn_es_find(&p->prefix.ead_addr.esi);
        if (!es)
@@ -2399,6 +2507,7 @@ static char *bgp_evpn_es_evi_vteps_str(char *vtep_str,
        struct listnode *node;
        struct bgp_evpn_es_evi_vtep *evi_vtep;
        bool first = true;
+       char ip_buf[INET6_ADDRSTRLEN];
 
        vtep_str[0] = '\0';
        for (ALL_LIST_ELEMENTS_RO(es_evi->es_evi_vtep_list, node, evi_vtep)) {
@@ -2414,7 +2523,10 @@ static char *bgp_evpn_es_evi_vteps_str(char *vtep_str,
                        first = false;
                else
                        strlcat(vtep_str, ",", vtep_str_size);
-               strlcat(vtep_str, inet_ntoa(evi_vtep->vtep_ip), vtep_str_size);
+               strlcat(vtep_str,
+                       inet_ntop(AF_INET, &evi_vtep->vtep_ip, ip_buf,
+                                 sizeof(ip_buf)),
+                       vtep_str_size);
                strlcat(vtep_str, "(", vtep_str_size);
                strlcat(vtep_str, vtep_flag_str, vtep_str_size);
                strlcat(vtep_str, ")", vtep_str_size);
@@ -2428,12 +2540,13 @@ static void bgp_evpn_es_evi_json_vtep_fill(json_object *json_vteps,
 {
        json_object *json_vtep_entry;
        json_object *json_flags;
+       char ip_buf[INET6_ADDRSTRLEN];
 
        json_vtep_entry = json_object_new_object();
 
-       json_object_string_add(json_vtep_entry,
-                       "vtep_ip",
-                       inet_ntoa(evi_vtep->vtep_ip));
+       json_object_string_add(
+               json_vtep_entry, "vtep_ip",
+               inet_ntop(AF_INET, &evi_vtep->vtep_ip, ip_buf, sizeof(ip_buf)));
        if (evi_vtep->flags & (BGP_EVPN_EVI_VTEP_EAD_PER_ES |
                         BGP_EVPN_EVI_VTEP_EAD_PER_EVI)) {
                json_flags = json_object_new_array();
@@ -2892,17 +3005,15 @@ void bgp_evpn_mh_finish(void)
 {
        struct bgp_evpn_es *es;
        struct bgp_evpn_es *es_next;
-       struct bgp *bgp;
 
-       bgp = bgp_get_evpn();
-       if (bgp) {
-               RB_FOREACH_SAFE(es, bgp_es_rb_head,
-                               &bgp_mh_info->es_rb_tree, es_next) {
-                       /* XXX - need to force free remote ESs here */
-                       bgp_evpn_local_es_do_del(bgp, es);
-               }
+       if (BGP_DEBUG(evpn_mh, EVPN_MH_RT))
+               zlog_debug("evpn mh finish");
+
+       RB_FOREACH_SAFE (es, bgp_es_rb_head, &bgp_mh_info->es_rb_tree,
+                        es_next) {
+               bgp_evpn_es_local_info_clear(es);
        }
-       thread_cancel(bgp_mh_info->t_cons_check);
+       thread_cancel(&bgp_mh_info->t_cons_check);
        list_delete(&bgp_mh_info->local_es_list);
        list_delete(&bgp_mh_info->pend_es_list);
 
index 93355d495a8ee8aa96bab951499d087b44ec1b22..d719524bddbc31e88fc8f85a954f24a7ae25ce3f 100644 (file)
@@ -110,6 +110,9 @@ struct bgp_evpn_es {
         */
        uint32_t incons_evi_vtep_cnt;
 
+       /* preference config for BUM-DF election. advertised via the ESR. */
+       uint16_t df_pref;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp_evpn_es)
@@ -131,6 +134,10 @@ struct bgp_evpn_es_vtep {
 
        uint32_t evi_cnt; /* es_evis referencing this vtep as an active path */
 
+       /* Algorithm and preference for DF election. Rxed via the ESR */
+       uint8_t df_alg;
+       uint16_t df_pref;
+
        /* memory used for adding the entry to es->es_vtep_list */
        struct listnode es_listnode;
 };
@@ -264,6 +271,11 @@ static inline bool bgp_evpn_attr_is_local_es(struct attr *attr)
        return attr ? !!(attr->es_flags & ATTR_ES_IS_LOCAL) : false;
 }
 
+static inline uint32_t bgp_evpn_attr_get_df_pref(struct attr *attr)
+{
+       return (attr) ? attr->df_pref : 0;
+}
+
 /****************************************************************************/
 extern int bgp_evpn_es_route_install_uninstall(struct bgp *bgp,
                struct bgp_evpn_es *es, afi_t afi, safi_t safi,
@@ -276,7 +288,8 @@ int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi,
                struct attr *attr, uint8_t *pfx, int psize,
                uint32_t addpath_id);
 extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
-               struct in_addr originator_ip, bool oper_up);
+                                struct in_addr originator_ip, bool oper_up,
+                                uint16_t df_pref);
 extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi);
 extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni);
 extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni);
index ca45b198a74793ff98d7150d534c1ea026ae291a..c47576c00c5a768943f1583a73a17241f936b1e1 100644 (file)
@@ -308,6 +308,17 @@ static inline void encode_es_rt_extcomm(struct ecommunity_val *eval,
        memcpy(&eval->val[2], mac, ETH_ALEN);
 }
 
+static inline void encode_df_elect_extcomm(struct ecommunity_val *eval,
+                                          uint16_t pref)
+{
+       memset(eval, 0, sizeof(*eval));
+       eval->val[0] = ECOMMUNITY_ENCODE_EVPN;
+       eval->val[1] = ECOMMUNITY_EVPN_SUBTYPE_DF_ELECTION;
+       eval->val[2] = EVPN_MH_DF_ALG_PREF;
+       eval->val[6] = (pref >> 8) & 0xff;
+       eval->val[7] = pref & 0xff;
+}
+
 static inline void encode_esi_label_extcomm(struct ecommunity_val *eval,
                                        bool single_active)
 {
@@ -603,11 +614,13 @@ extern void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi,
                                    struct bgp_path_info **pi);
 int vni_list_cmp(void *p1, void *p2);
 extern int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
-               struct bgp_node *rn);
-extern struct bgp_node *bgp_global_evpn_node_get(
-               struct bgp_table *table, afi_t afi, safi_t safi,
-               const struct prefix_evpn *evp, struct prefix_rd *prd);
-extern struct bgp_node *bgp_global_evpn_node_lookup(
-               struct bgp_table *table, afi_t afi, safi_t safi,
-               const struct prefix_evpn *evp, struct prefix_rd *prd);
+                                    struct bgp_dest *dest);
+extern struct bgp_dest *bgp_global_evpn_node_get(struct bgp_table *table,
+                                                afi_t afi, safi_t safi,
+                                                const struct prefix_evpn *evp,
+                                                struct prefix_rd *prd);
+extern struct bgp_dest *
+bgp_global_evpn_node_lookup(struct bgp_table *table, afi_t afi, safi_t safi,
+                           const struct prefix_evpn *evp,
+                           struct prefix_rd *prd);
 #endif /* _BGP_EVPN_PRIVATE_H */
index 15ecffdc72413beb62eb8eda5f80477e58a081f1..e9e2aafebbec174a26973ef40e55f6306b58e2f5 100644 (file)
@@ -22,6 +22,8 @@
 #include "command.h"
 #include "prefix.h"
 #include "lib/json.h"
+#include "lib/printfrr.h"
+#include "lib/vxlan.h"
 #include "stream.h"
 
 #include "bgpd/bgpd.h"
@@ -103,8 +105,7 @@ static void display_vrf_import_rt(struct vty *vty, struct vrf_irt_node *irt,
                eip.val = (*pnt++ << 8);
                eip.val |= (*pnt++);
 
-               snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip),
-                        eip.val);
+               snprintfrr(rt_buf, sizeof(rt_buf), "%pI4:%u", &eip.ip, eip.val);
 
                if (json)
                        json_object_string_add(json_rt, "rt", rt_buf);
@@ -213,8 +214,7 @@ static void display_import_rt(struct vty *vty, struct irt_node *irt,
                eip.val = (*pnt++ << 8);
                eip.val |= (*pnt++);
 
-               snprintf(rt_buf, sizeof(rt_buf), "%s:%u", inet_ntoa(eip.ip),
-                        eip.val);
+               snprintfrr(rt_buf, sizeof(rt_buf), "%pI4:%u", &eip.ip, eip.val);
 
                if (json)
                        json_object_string_add(json_rt, "rt", rt_buf);
@@ -314,8 +314,7 @@ static void bgp_evpn_show_route_rd_header(struct vty *vty,
 
        case RD_TYPE_IP:
                decode_rd_ip(pnt + 2, &rd_ip);
-               snprintf(rd_str, len, "%s:%d", inet_ntoa(rd_ip.ip),
-                        rd_ip.val);
+               snprintfrr(rd_str, len, "%pI4:%d", &rd_ip.ip, rd_ip.val);
                if (json)
                        json_object_string_add(json, "rd", rd_str);
                else
@@ -343,8 +342,9 @@ static void bgp_evpn_show_route_header(struct vty *vty, struct bgp *bgp,
        if (json)
                return;
 
-       vty_out(vty, "BGP table version is %" PRIu64 ", local router ID is %s\n",
-               tbl_ver, inet_ntoa(bgp->router_id));
+       vty_out(vty,
+               "BGP table version is %" PRIu64 ", local router ID is %pI4\n",
+               tbl_ver, &bgp->router_id);
        vty_out(vty,
                "Status codes: s suppressed, d damped, h history, * valid, > best, i - internal\n");
        vty_out(vty, "Origin codes: i - IGP, e - EGP, ? - incomplete\n");
@@ -368,6 +368,7 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
        json_object *json_import_rtl = NULL;
        json_object *json_export_rtl = NULL;
        char buf2[ETHER_ADDR_STRLEN];
+       char originator_ip[BUFSIZ] = {0};
 
        json_import_rtl = json_export_rtl = 0;
 
@@ -380,8 +381,10 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
                json_object_string_add(
                        json, "rd",
                        prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN));
-               json_object_string_add(json, "originatorIp",
-                                      inet_ntoa(bgp_vrf->originator_ip));
+               json_object_string_add(
+                       json, "originatorIp",
+                       inet_ntop(AF_INET, &bgp_vrf->originator_ip,
+                                 originator_ip, sizeof(originator_ip)));
                json_object_string_add(json, "advertiseGatewayMacip", "n/a");
                json_object_string_add(json, "advertiseSviMacIp", "n/a");
                json_object_to_json_string_ext(json,
@@ -409,8 +412,8 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
                        vrf_id_to_name(bgp_vrf->vrf_id));
                vty_out(vty, "  RD: %s\n",
                        prefix_rd2str(&bgp_vrf->vrf_prd, buf1, RD_ADDRSTRLEN));
-               vty_out(vty, "  Originator IP: %s\n",
-                       inet_ntoa(bgp_vrf->originator_ip));
+               vty_out(vty, "  Originator IP: %pI4\n",
+                       &bgp_vrf->originator_ip);
                vty_out(vty, "  Advertise-gw-macip : %s\n", "n/a");
                vty_out(vty, "  Advertise-svi-macip : %s\n", "n/a");
                vty_out(vty, "  Advertise-pip: %s\n",
@@ -473,6 +476,7 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
        json_object *json_import_rtl = NULL;
        json_object *json_export_rtl = NULL;
        struct bgp *bgp_evpn;
+       char buf[BUFSIZ] = {0};
 
        bgp_evpn = bgp_get_evpn();
 
@@ -487,9 +491,11 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
                        json, "rd",
                        prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
                json_object_string_add(json, "originatorIp",
-                                      inet_ntoa(vpn->originator_ip));
-               json_object_string_add(json, "mcastGroup",
-                               inet_ntoa(vpn->mcast_grp));
+                                      inet_ntop(AF_INET, &vpn->originator_ip,
+                                                buf, sizeof(buf)));
+               json_object_string_add(
+                       json, "mcastGroup",
+                       inet_ntop(AF_INET, &vpn->mcast_grp, buf, sizeof(buf)));
                /* per vni knob is enabled -- Enabled
                 * Global knob is enabled  -- Active
                 * default  -- Disabled
@@ -525,10 +531,8 @@ static void display_vni(struct vty *vty, struct bgpevpn *vpn, json_object *json)
                        vrf_id_to_name(vpn->tenant_vrf_id));
                vty_out(vty, "  RD: %s\n",
                        prefix_rd2str(&vpn->prd, buf1, sizeof(buf1)));
-               vty_out(vty, "  Originator IP: %s\n",
-                       inet_ntoa(vpn->originator_ip));
-               vty_out(vty, "  Mcast group: %s\n",
-                               inet_ntoa(vpn->mcast_grp));
+               vty_out(vty, "  Originator IP: %pI4\n", &vpn->originator_ip);
+               vty_out(vty, "  Mcast group: %pI4\n", &vpn->mcast_grp);
                if (!vpn->advertise_gw_macip &&
                    bgp_evpn && bgp_evpn->advertise_gw_macip)
                        vty_out(vty, "  Advertise-gw-macip : %s\n",
@@ -611,8 +615,8 @@ static void show_esi_routes(struct bgp *bgp,
                json_object *json_prefix = NULL;
                const struct prefix *p = bgp_dest_get_prefix(dest);
 
-               bgp_evpn_route2str((struct prefix_evpn *)p, prefix_str,
-                                  sizeof(prefix_str));
+               prefix2str((struct prefix_evpn *)p, prefix_str,
+                          sizeof(prefix_str));
 
                if (json)
                        json_prefix = json_object_new_object();
@@ -706,9 +710,8 @@ static void show_vni_routes(struct bgp *bgp, struct bgpevpn *vpn, int type,
                json_object *json_prefix = NULL;
                const struct prefix *p = bgp_dest_get_prefix(dest);
 
-               bgp_evpn_route2str(
-                       (struct prefix_evpn *)bgp_dest_get_prefix(dest),
-                       prefix_str, sizeof(prefix_str));
+               prefix2str((struct prefix_evpn *)bgp_dest_get_prefix(dest),
+                          prefix_str, sizeof(prefix_str));
 
                if (type && evp->prefix.route_type != type)
                        continue;
@@ -826,6 +829,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
        json_object *json_export_rtl = NULL;
        char buf1[10];
        char buf2[INET6_ADDRSTRLEN];
+       char buf3[BUFSIZ] = {0};
        char rt_buf[25];
        char *ecom_str;
        struct listnode *node, *nnode;
@@ -849,7 +853,8 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
                json_object_string_add(json_vni, "type", "L3");
                json_object_string_add(json_vni, "inKernel", "True");
                json_object_string_add(json_vni, "originatorIp",
-                                      inet_ntoa(bgp->originator_ip));
+                                      inet_ntop(AF_INET, &bgp->originator_ip,
+                                                buf3, sizeof(buf3)));
                json_object_string_add(
                        json_vni, "rd",
                        prefix_rd2str(&bgp->vrf_prd, buf2, RD_ADDRSTRLEN));
@@ -862,7 +867,9 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
                        json_vni, "advertisePip",
                        bgp->evpn_info->advertise_pip ? "Enabled" : "Disabled");
                json_object_string_add(json_vni, "sysIP",
-                                      inet_ntoa(bgp->evpn_info->pip_ip));
+                                      inet_ntop(AF_INET,
+                                                &bgp->evpn_info->pip_ip, buf3,
+                                                sizeof(buf3)));
                json_object_string_add(json_vni, "sysMAC",
                                       prefix_mac2str(&bgp->evpn_info->pip_rmac,
                                                      buf2, sizeof(buf2)));
@@ -951,6 +958,7 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
        struct bgpevpn *vpn = (struct bgpevpn *)bucket->data;
        char buf1[10];
        char buf2[RD_ADDRSTRLEN];
+       char buf3[BUFSIZ] = {0};
        char rt_buf[25];
        char *ecom_str;
        struct listnode *node, *nnode;
@@ -981,9 +989,11 @@ static void show_vni_entry(struct hash_bucket *bucket, void *args[])
                        json_vni, "rd",
                        prefix_rd2str(&vpn->prd, buf2, sizeof(buf2)));
                json_object_string_add(json_vni, "originatorIp",
-                                      inet_ntoa(vpn->originator_ip));
+                                      inet_ntop(AF_INET, &vpn->originator_ip,
+                                                buf3, sizeof(buf3)));
                json_object_string_add(json_vni, "mcastGroup",
-                                      inet_ntoa(vpn->mcast_grp));
+                                      inet_ntop(AF_INET, &vpn->mcast_grp, buf3,
+                                                sizeof(buf3)));
                /* per vni knob is enabled -- Enabled
                 * Global knob is enabled  -- Active
                 * default  -- Disabled
@@ -1095,6 +1105,7 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
        char rd_str[RD_ADDRSTRLEN];
        char buf[BUFSIZ];
        int no_display;
+       char router_id[BUFSIZ] = {0};
 
        unsigned long output_count = 0;
        unsigned long total_count = 0;
@@ -1186,8 +1197,11 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
                                                json_object_string_add(
                                                        json,
                                                        "bgpLocalRouterId",
-                                                       inet_ntoa(
-                                                       bgp->router_id));
+                                                       inet_ntop(
+                                                               AF_INET,
+                                                               &bgp->router_id,
+                                                               router_id,
+                                                               sizeof(router_id)));
                                                json_object_int_add(
                                                        json,
                                                        "defaultLocPrf",
@@ -1250,9 +1264,8 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
 
                                json_object_string_add(
                                        json_prefix_info, "prefix",
-                                       bgp_evpn_route2str(
-                                               (struct prefix_evpn *)p, buf,
-                                               BUFSIZ));
+                                       prefix2str((struct prefix_evpn *)p, buf,
+                                                  BUFSIZ));
 
                                json_object_int_add(json_prefix_info,
                                                    "prefixLen", p->prefixlen);
@@ -2441,7 +2454,7 @@ static void evpn_show_route_rd_macip(struct vty *vty, struct bgp *bgp,
                return;
        }
 
-       bgp_evpn_route2str(&p, prefix_str, sizeof(prefix_str));
+       prefix2str(&p, prefix_str, sizeof(prefix_str));
 
        /* Prefix and num paths displayed once per prefix. */
        route_vty_out_detail_header(vty, bgp, dest, prd, afi, safi, json);
@@ -2522,8 +2535,8 @@ static void evpn_show_route_rd(struct vty *vty, struct bgp *bgp,
                char prefix_str[BUFSIZ];
                int add_prefix_to_json = 0;
 
-               bgp_evpn_route2str((struct prefix_evpn *)evp, prefix_str,
-                                  sizeof(prefix_str));
+               prefix2str((struct prefix_evpn *)evp, prefix_str,
+                          sizeof(prefix_str));
 
                if (type && evp->prefix.route_type != type)
                        continue;
@@ -2668,8 +2681,8 @@ static void evpn_show_all_routes(struct vty *vty, struct bgp *bgp, int type,
                        int add_prefix_to_json = 0;
                        const struct prefix *p = bgp_dest_get_prefix(dest);
 
-                       bgp_evpn_route2str((struct prefix_evpn *)p, prefix_str,
-                                          sizeof(prefix_str));
+                       prefix2str((struct prefix_evpn *)p, prefix_str,
+                                  sizeof(prefix_str));
 
                        if (type && evp->prefix.route_type != type)
                                continue;
@@ -3988,33 +4001,51 @@ DEFUN(show_bgp_l2vpn_evpn_summary,
                                    show_established, uj);
 }
 
+int bgp_evpn_cli_parse_type(int *type, struct cmd_token **argv, int argc)
+{
+       int type_idx = 0;
+
+       if (argv_find(argv, argc, "type", &type_idx)) {
+               /* Specific type is requested */
+               if ((strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0)
+                   || (strmatch(argv[type_idx + 1]->arg, "2")))
+                       *type = BGP_EVPN_MAC_IP_ROUTE;
+               else if ((strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0)
+                        || (strmatch(argv[type_idx + 1]->arg, "3")))
+                       *type = BGP_EVPN_IMET_ROUTE;
+               else if ((strncmp(argv[type_idx + 1]->arg, "es", 2) == 0)
+                        || (strmatch(argv[type_idx + 1]->arg, "4")))
+                       *type = BGP_EVPN_ES_ROUTE;
+               else if ((strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0)
+                        || (strmatch(argv[type_idx + 1]->arg, "1")))
+                       *type = BGP_EVPN_AD_ROUTE;
+               else if ((strncmp(argv[type_idx + 1]->arg, "p", 1) == 0)
+                        || (strmatch(argv[type_idx + 1]->arg, "5")))
+                       *type = BGP_EVPN_IP_PREFIX_ROUTE;
+               else
+                       return -1;
+       }
+
+       return 0;
+}
+
 /*
  * Display global EVPN routing table.
  */
 DEFUN(show_bgp_l2vpn_evpn_route,
       show_bgp_l2vpn_evpn_route_cmd,
-      "show bgp l2vpn evpn route [detail] [type <ead|1|macip|2|multicast|3|es|4|prefix|5>] [json]",
+      "show bgp l2vpn evpn route [detail] [type "EVPN_TYPE_ALL_LIST"] [json]",
       SHOW_STR
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
+      EVPN_RT_HELP_STR
       "Display Detailed Information\n"
-      "Specify Route type\n"
-      "EAD (Type-1) route\n"
-      "EAD (Type-1) route\n"
-      "MAC-IP (Type-2) route\n"
-      "MAC-IP (Type-2) route\n"
-      "Multicast (Type-3) route\n"
-      "Multicast (Type-3) route\n"
-      "Ethernet Segment (Type-4) route\n"
-      "Ethernet Segment (Type-4) route\n"
-      "Prefix (Type-5) route\n"
-      "Prefix (Type-5) route\n"
+      EVPN_TYPE_HELP_STR
+      EVPN_TYPE_ALL_LIST_HELP_STR
       JSON_STR)
 {
        struct bgp *bgp;
-       int type_idx = 0;
        int detail = 0;
        int type = 0;
        bool uj = false;
@@ -4029,27 +4060,8 @@ DEFUN(show_bgp_l2vpn_evpn_route,
        if (uj)
                json = json_object_new_object();
 
-       /* get the type */
-       if (argv_find(argv, argc, "type", &type_idx)) {
-               /* Specific type is requested */
-               if ((strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0)
-                   || (strmatch(argv[type_idx + 1]->arg, "2")))
-                       type = BGP_EVPN_MAC_IP_ROUTE;
-               else if ((strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0)
-                        || (strmatch(argv[type_idx + 1]->arg, "3")))
-                       type = BGP_EVPN_IMET_ROUTE;
-               else if ((strncmp(argv[type_idx + 1]->arg, "es", 2) == 0)
-                        || (strmatch(argv[type_idx + 1]->arg, "4")))
-                       type = BGP_EVPN_ES_ROUTE;
-               else if ((strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0)
-                        || (strmatch(argv[type_idx + 1]->arg, "1")))
-                       type = BGP_EVPN_AD_ROUTE;
-               else if ((strncmp(argv[type_idx + 1]->arg, "p", 1) == 0)
-                        || (strmatch(argv[type_idx + 1]->arg, "5")))
-                       type = BGP_EVPN_IP_PREFIX_ROUTE;
-               else
-                       return CMD_WARNING;
-       }
+       if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
+               return CMD_WARNING;
 
        if (argv_find(argv, argc, "detail", &detail))
                detail = 1;
@@ -4069,20 +4081,16 @@ DEFUN(show_bgp_l2vpn_evpn_route,
  */
 DEFUN(show_bgp_l2vpn_evpn_route_rd,
       show_bgp_l2vpn_evpn_route_rd_cmd,
-      "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <ead|macip|multicast|es|prefix>] [json]",
+      "show bgp l2vpn evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type "EVPN_TYPE_ALL_LIST"] [json]",
       SHOW_STR
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
-      "Route Distinguisher\n"
-      "ASN:XX or A.B.C.D:XX\n"
-      "Specify Route type\n"
-      "EAD (Type-1) route\n"
-      "MAC-IP (Type-2) route\n"
-      "Multicast (Type-3) route\n"
-      "Ethernet Segment route\n"
-      "Prefix route\n"
+      EVPN_RT_HELP_STR
+      EVPN_RT_DIST_HELP_STR
+      EVPN_ASN_IP_HELP_STR
+      EVPN_TYPE_HELP_STR
+      EVPN_TYPE_ALL_LIST_HELP_STR
       JSON_STR)
 {
        struct bgp *bgp;
@@ -4090,7 +4098,6 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
        struct prefix_rd prd;
        int type = 0;
        int rd_idx = 0;
-       int type_idx = 0;
        bool uj = false;
        json_object *json = NULL;
 
@@ -4113,22 +4120,8 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
                }
        }
 
-       /* get the type */
-       if (argv_find(argv, argc, "type", &type_idx)) {
-               /* Specific type is requested */
-               if (strncmp(argv[type_idx + 1]->arg, "ma", 2) == 0)
-                       type = BGP_EVPN_MAC_IP_ROUTE;
-               else if (strncmp(argv[type_idx + 1]->arg, "mu", 2) == 0)
-                       type = BGP_EVPN_IMET_ROUTE;
-               else if (strncmp(argv[type_idx + 1]->arg, "es", 2) == 0)
-                       type = BGP_EVPN_ES_ROUTE;
-               else if (strncmp(argv[type_idx + 1]->arg, "ea", 2) == 0)
-                       type = BGP_EVPN_AD_ROUTE;
-               else if (strncmp(argv[type_idx + 1]->arg, "pr", 2) == 0)
-                       type = BGP_EVPN_IP_PREFIX_ROUTE;
-               else
-                       return CMD_WARNING;
-       }
+       if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
+               return CMD_WARNING;
 
        evpn_show_route_rd(vty, bgp, &prd, type, json);
 
@@ -4151,9 +4144,9 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd_macip,
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
-      "Route Distinguisher\n"
-      "ASN:XX or A.B.C.D:XX\n"
+      EVPN_RT_HELP_STR
+      EVPN_RT_DIST_HELP_STR
+      EVPN_ASN_IP_HELP_STR
       "MAC\n"
       "MAC address (e.g., 00:e0:ec:20:12:62)\n"
       "IP\n"
@@ -4227,7 +4220,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi,
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
+      EVPN_RT_HELP_STR
       "Ethernet Segment Identifier\n"
       "ESI ID\n"
       JSON_STR)
@@ -4268,18 +4261,21 @@ DEFUN(show_bgp_l2vpn_evpn_route_esi,
  * Display per-VNI EVPN routing table.
  */
 DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
-      "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <ead|macip|multicast> | vtep A.B.C.D>] [json]",
+      "show bgp l2vpn evpn route vni " CMD_VNI_RANGE " [<type <ead|1|macip|2|multicast|3> | vtep A.B.C.D>] [json]",
       SHOW_STR
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
+      EVPN_RT_HELP_STR
       "VXLAN Network Identifier\n"
       "VNI number\n"
-      "Specify Route type\n"
-      "EAD (Type-1) route\n"
-      "MAC-IP (Type-2) route\n"
-      "Multicast (Type-3) route\n"
+      EVPN_TYPE_HELP_STR
+      EVPN_TYPE_1_HELP_STR
+      EVPN_TYPE_1_HELP_STR
+      EVPN_TYPE_2_HELP_STR
+      EVPN_TYPE_2_HELP_STR
+      EVPN_TYPE_3_HELP_STR
+      EVPN_TYPE_3_HELP_STR
       "Remote VTEP\n"
       "Remote VTEP IP address\n"
       JSON_STR)
@@ -4289,6 +4285,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
        struct in_addr vtep_ip;
        int type = 0;
        int idx = 0;
+       int vtep_idx = 0;
        bool uj = false;
        json_object *json = NULL;
 
@@ -4308,24 +4305,14 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
 
        vni = strtoul(argv[idx + 3]->arg, NULL, 10);
 
-       if ((!uj && ((argc == (idx + 1 + 5)) && argv[idx + 4]->arg))
-           || (uj && ((argc == (idx + 1 + 6)) && argv[idx + 4]->arg))) {
-               if (strncmp(argv[idx + 4]->arg, "type", 4) == 0) {
-                       if (strncmp(argv[idx + 5]->arg, "ma", 2) == 0)
-                               type = BGP_EVPN_MAC_IP_ROUTE;
-                       else if (strncmp(argv[idx + 5]->arg, "mu", 2) == 0)
-                               type = BGP_EVPN_IMET_ROUTE;
-                       else if (strncmp(argv[idx + 5]->arg, "ea", 2) == 0)
-                               type = BGP_EVPN_AD_ROUTE;
-                       else
-                               return CMD_WARNING;
-               } else if (strncmp(argv[idx + 4]->arg, "vtep", 4) == 0) {
-                       if (!inet_aton(argv[idx + 5]->arg, &vtep_ip)) {
-                               vty_out(vty, "%% Malformed VTEP IP address\n");
-                               return CMD_WARNING;
-                       }
-               } else
+       if (bgp_evpn_cli_parse_type(&type, argv, argc) < 0)
+               return CMD_WARNING;
+
+       if (argv_find(argv, argc, "vtep", &vtep_idx)) {
+               if (!inet_aton(argv[vtep_idx + 1]->arg, &vtep_ip)) {
+                       vty_out(vty, "%% Malformed VTEP IP address\n");
                        return CMD_WARNING;
+               }
        }
 
        evpn_show_routes_vni(vty, bgp, vni, type, vtep_ip, json);
@@ -4349,7 +4336,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_macip,
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
+      EVPN_RT_HELP_STR
       "VXLAN Network Identifier\n"
       "VNI number\n"
       "MAC\n"
@@ -4419,10 +4406,10 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_multicast,
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
+      EVPN_RT_HELP_STR
       "VXLAN Network Identifier\n"
       "VNI number\n"
-      "Multicast (Type-3) route\n"
+      EVPN_TYPE_3_HELP_STR
       "Originating Router IP address\n"
       JSON_STR)
 {
@@ -4477,7 +4464,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni_all,
       BGP_STR
       L2VPN_HELP_STR
       EVPN_HELP_STR
-      "EVPN route information\n"
+      EVPN_RT_HELP_STR
       "VXLAN Network Identifier\n"
       "All VNIs\n"
       "Print Detailed Output\n"
@@ -4602,7 +4589,7 @@ DEFUN(show_bgp_l2vpn_evpn_import_rt,
        return CMD_SUCCESS;
 }
 
-DEFPY(test_es_add,
+DEFPY_HIDDEN(test_es_add,
       test_es_add_cmd,
       "[no$no] test es NAME$esi_str [state NAME$state_str]",
       NO_STR
@@ -4643,7 +4630,8 @@ DEFPY(test_es_add,
                        oper_up = false;
                vtep_ip = bgp->router_id;
 
-               ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up);
+               ret = bgp_evpn_local_es_add(bgp, &esi, vtep_ip, oper_up,
+                                           EVPN_MH_DF_PREF_MIN);
                if (ret == -1) {
                        vty_out(vty, "%%Failed to add ES\n");
                        return CMD_WARNING;
@@ -4652,7 +4640,7 @@ DEFPY(test_es_add,
        return CMD_SUCCESS;
 }
 
-DEFPY(test_es_vni_add,
+DEFPY_HIDDEN(test_es_vni_add,
       test_es_vni_add_cmd,
       "[no$no] test es NAME$esi_str vni (1-16777215)$vni",
       NO_STR
@@ -4704,32 +4692,36 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_summary, show_bgp_evpn_summary_cmd,
             "Summary of BGP neighbor status\n" JSON_STR)
 
 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route, show_bgp_evpn_route_cmd,
-            "show bgp evpn route [detail] [type <macip|multicast>]",
+            "show bgp evpn route [detail] [type <macip|2|multicast|3>]",
             SHOW_STR BGP_STR EVPN_HELP_STR
-            "EVPN route information\n"
+            EVPN_RT_HELP_STR
             "Display Detailed Information\n"
-            "Specify Route type\n"
-            "MAC-IP (Type-2) route\n"
-            "Multicast (Type-3) route\n")
+            EVPN_TYPE_HELP_STR
+            EVPN_TYPE_2_HELP_STR
+            EVPN_TYPE_2_HELP_STR
+            EVPN_TYPE_3_HELP_STR
+            EVPN_TYPE_3_HELP_STR)
 
 ALIAS_HIDDEN(
        show_bgp_l2vpn_evpn_route_rd, show_bgp_evpn_route_rd_cmd,
-       "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|multicast>]",
+       "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN [type <macip|2|multicast|3>]",
        SHOW_STR BGP_STR EVPN_HELP_STR
-       "EVPN route information\n"
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n"
-       "Specify Route type\n"
-       "MAC-IP (Type-2) route\n"
-       "Multicast (Type-3) route\n")
+       EVPN_RT_HELP_STR
+       EVPN_RT_DIST_HELP_STR
+       EVPN_ASN_IP_HELP_STR
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR)
 
 ALIAS_HIDDEN(
        show_bgp_l2vpn_evpn_route_rd_macip, show_bgp_evpn_route_rd_macip_cmd,
        "show bgp evpn route rd ASN:NN_OR_IP-ADDRESS:NN mac WORD [ip WORD]",
        SHOW_STR BGP_STR EVPN_HELP_STR
-       "EVPN route information\n"
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n"
+       EVPN_RT_HELP_STR
+       EVPN_RT_DIST_HELP_STR
+       EVPN_ASN_IP_HELP_STR
        "MAC\n"
        "MAC address (e.g., 00:e0:ec:20:12:62)\n"
        "IP\n"
@@ -4737,14 +4729,16 @@ ALIAS_HIDDEN(
 
 ALIAS_HIDDEN(
        show_bgp_l2vpn_evpn_route_vni, show_bgp_evpn_route_vni_cmd,
-       "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|multicast> | vtep A.B.C.D>]",
+       "show bgp evpn route vni " CMD_VNI_RANGE " [<type <macip|2|multicast|3> | vtep A.B.C.D>]",
        SHOW_STR BGP_STR EVPN_HELP_STR
-       "EVPN route information\n"
+       EVPN_RT_HELP_STR
        "VXLAN Network Identifier\n"
        "VNI number\n"
-       "Specify Route type\n"
-       "MAC-IP (Type-2) route\n"
-       "Multicast (Type-3) route\n"
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
        "Remote VTEP\n"
        "Remote VTEP IP address\n")
 
@@ -4752,7 +4746,7 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_macip,
             show_bgp_evpn_route_vni_macip_cmd,
             "show bgp evpn route vni " CMD_VNI_RANGE " mac WORD [ip WORD]",
             SHOW_STR BGP_STR EVPN_HELP_STR
-            "EVPN route information\n"
+            EVPN_RT_HELP_STR
             "VXLAN Network Identifier\n"
             "VNI number\n"
             "MAC\n"
@@ -4764,16 +4758,16 @@ ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_multicast,
             show_bgp_evpn_route_vni_multicast_cmd,
             "show bgp evpn route vni " CMD_VNI_RANGE " multicast A.B.C.D",
             SHOW_STR BGP_STR EVPN_HELP_STR
-            "EVPN route information\n"
+            EVPN_RT_HELP_STR
             "VXLAN Network Identifier\n"
             "VNI number\n"
-            "Multicast (Type-3) route\n"
+            EVPN_TYPE_3_HELP_STR
             "Originating Router IP address\n")
 
 ALIAS_HIDDEN(show_bgp_l2vpn_evpn_route_vni_all, show_bgp_evpn_route_vni_all_cmd,
             "show bgp evpn route vni all [detail] [vtep A.B.C.D]",
             SHOW_STR BGP_STR EVPN_HELP_STR
-            "EVPN route information\n"
+            EVPN_RT_HELP_STR
             "VXLAN Network Identifier\n"
             "All VNIs\n"
             "Print Detailed Output\n"
@@ -4854,8 +4848,8 @@ DEFUN_NOSH (exit_vni,
 DEFUN (bgp_evpn_vrf_rd,
        bgp_evpn_vrf_rd_cmd,
        "rd ASN:NN_OR_IP-ADDRESS:NN",
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n")
+       EVPN_RT_DIST_HELP_STR
+       EVPN_ASN_IP_HELP_STR)
 {
        int ret;
        struct prefix_rd prd;
@@ -4883,8 +4877,8 @@ DEFUN (no_bgp_evpn_vrf_rd,
        no_bgp_evpn_vrf_rd_cmd,
        "no rd ASN:NN_OR_IP-ADDRESS:NN",
        NO_STR
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n")
+       EVPN_RT_DIST_HELP_STR
+       EVPN_ASN_IP_HELP_STR)
 {
        int ret;
        struct prefix_rd prd;
@@ -4919,7 +4913,7 @@ DEFUN (no_bgp_evpn_vrf_rd_without_val,
        no_bgp_evpn_vrf_rd_without_val_cmd,
        "no rd",
        NO_STR
-       "Route Distinguisher\n")
+       EVPN_RT_DIST_HELP_STR)
 {
        struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp);
 
@@ -4939,8 +4933,8 @@ DEFUN (no_bgp_evpn_vrf_rd_without_val,
 DEFUN (bgp_evpn_vni_rd,
        bgp_evpn_vni_rd_cmd,
        "rd ASN:NN_OR_IP-ADDRESS:NN",
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n")
+       EVPN_RT_DIST_HELP_STR
+       EVPN_ASN_IP_HELP_STR)
 {
        struct prefix_rd prd;
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
@@ -4975,8 +4969,8 @@ DEFUN (no_bgp_evpn_vni_rd,
        no_bgp_evpn_vni_rd_cmd,
        "no rd ASN:NN_OR_IP-ADDRESS:NN",
        NO_STR
-       "Route Distinguisher\n"
-       "ASN:XX or A.B.C.D:XX\n")
+       EVPN_RT_DIST_HELP_STR
+       EVPN_ASN_IP_HELP_STR)
 {
        struct prefix_rd prd;
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
@@ -5018,7 +5012,7 @@ DEFUN (no_bgp_evpn_vni_rd_without_val,
        no_bgp_evpn_vni_rd_without_val_cmd,
        "no rd",
        NO_STR
-       "Route Distinguisher\n")
+       EVPN_RT_DIST_HELP_STR)
 {
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
        VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
@@ -5073,6 +5067,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
 {
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
+       char originator_ip[BUFSIZ] = {0};
        int idx_vrf = 3;
        const char *name = NULL;
        struct bgp *bgp = NULL;
@@ -5108,7 +5103,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
 
        if (!json) {
                vty_out(vty, "BGP VRF: %s\n", name);
-               vty_out(vty, "  Local-Ip: %s\n", inet_ntoa(bgp->originator_ip));
+               vty_out(vty, "  Local-Ip: %pI4\n", &bgp->originator_ip);
                vty_out(vty, "  L3-VNI: %u\n", bgp->l3vni);
                vty_out(vty, "  Rmac: %s\n",
                        prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
@@ -5137,7 +5132,9 @@ DEFUN (show_bgp_vrf_l3vni_info,
        } else {
                json_object_string_add(json, "vrf", name);
                json_object_string_add(json, "local-ip",
-                                      inet_ntoa(bgp->originator_ip));
+                                      inet_ntop(AF_INET, &bgp->originator_ip,
+                                                originator_ip,
+                                                sizeof(originator_ip)));
                json_object_int_add(json, "l3vni", bgp->l3vni);
                json_object_string_add(
                        json, "rmac",
@@ -5249,7 +5246,7 @@ DEFUN (no_bgp_evpn_vrf_rt,
        "import and export\n"
        "import\n"
        "export\n"
-       "ASN:XX or A.B.C.D:XX\n")
+       EVPN_ASN_IP_HELP_STR)
 {
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
        int rt_type, found_ecomdel;
@@ -5300,6 +5297,7 @@ DEFUN (no_bgp_evpn_vrf_rt,
        if (rt_type == RT_TYPE_IMPORT) {
                if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
                                                  ecomdel)) {
+                       ecommunity_free(&ecomdel);
                        vty_out(vty,
                                "%% RT specified does not match configuration for this VRF\n");
                        return CMD_WARNING;
@@ -5308,6 +5306,7 @@ DEFUN (no_bgp_evpn_vrf_rt,
        } else if (rt_type == RT_TYPE_EXPORT) {
                if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl,
                                                  ecomdel)) {
+                       ecommunity_free(&ecomdel);
                        vty_out(vty,
                                "%% RT specified does not match configuration for this VRF\n");
                        return CMD_WARNING;
@@ -5329,12 +5328,14 @@ DEFUN (no_bgp_evpn_vrf_rt,
                }
 
                if (!found_ecomdel) {
+                       ecommunity_free(&ecomdel);
                        vty_out(vty,
                                "%% RT specified does not match configuration for this VRF\n");
                        return CMD_WARNING;
                }
        }
 
+       ecommunity_free(&ecomdel);
        return CMD_SUCCESS;
 }
 
@@ -5413,7 +5414,7 @@ DEFUN (no_bgp_evpn_vni_rt,
        "import and export\n"
        "import\n"
        "export\n"
-       "ASN:XX or A.B.C.D:XX\n")
+       EVPN_ASN_IP_HELP_STR)
 {
        struct bgp *bgp = VTY_GET_CONTEXT(bgp);
        VTY_DECLVAR_CONTEXT_SUB(bgpevpn, vpn);
index 4d07f7d038ffb16c84bd37909137b7a4067b5f97..33f6e4f1b607060a35abb3f05a1c3bb689246af8 100644 (file)
@@ -28,4 +28,8 @@ extern void bgp_ethernetvpn_init(void);
 #define L2VPN_HELP_STR        "Layer 2 Virtual Private Network\n"
 #define EVPN_HELP_STR        "Ethernet Virtual Private Network\n"
 
+/* Parse type from "type <ead|1|...>", return -1 on failure */
+extern int bgp_evpn_cli_parse_type(int *type, struct cmd_token **argv,
+                                  int argc);
+
 #endif /* _QUAGGA_BGP_EVPN_VTY_H */
index 0308a30d54a9729ef03320df5cf92242ce9d9883..3162579688db9e64ff9ac49aa17cfff065454839 100644 (file)
@@ -507,14 +507,16 @@ DEFUN(no_as_path, no_bgp_as_path_cmd,
        /* Lookup asfilter. */
        asfilter = as_filter_lookup(aslist, regstr, type);
 
-       XFREE(MTYPE_TMP, regstr);
        bgp_regex_free(regex);
 
        if (asfilter == NULL) {
-               vty_out(vty, "\n");
+               vty_out(vty, "Regex entered %s does not exist\n", regstr);
+               XFREE(MTYPE_TMP, regstr);
                return CMD_WARNING_CONFIG_FAILED;
        }
 
+       XFREE(MTYPE_TMP, regstr);
+
        as_list_filter_delete(aslist, asfilter);
 
        return CMD_SUCCESS;
index 90e9236385845d8e5804645417c96d7425bdc5dc..55e7973f817ecf54af9092fb5be1053da12c7c94 100644 (file)
@@ -20,6 +20,8 @@
 
 #include "zebra.h"
 
+#include "lib/printfrr.h"
+
 #include "prefix.h"
 #include "lib_errors.h"
 
@@ -211,14 +213,11 @@ int bgp_flowspec_ip_address(enum bgp_flowspec_util_nlri_t type,
        switch (type) {
        case BGP_FLOWSPEC_RETURN_STRING:
                if (prefix_local.family == AF_INET6) {
-                       char str[BGP_FLOWSPEC_STRING_DISPLAY_MAX];
                        int ret;
 
-                       prefix2str(&prefix_local, str,
-                                  BGP_FLOWSPEC_STRING_DISPLAY_MAX);
-                       ret = snprintf(display, BGP_FLOWSPEC_STRING_DISPLAY_MAX,
-                                      "%s/off %u",
-                                      str, prefix_offset);
+                       ret = snprintfrr(
+                               display, BGP_FLOWSPEC_STRING_DISPLAY_MAX,
+                               "%pFX/off %u", &prefix_local, prefix_offset);
                        if (ret < 0) {
                                *error = -1;
                                break;
index d7df707a36b85e01080da269c21ee3a64f664d4f..4468408415b8f2597c8cc920c05a5f7cfeb87eb7 100644 (file)
@@ -704,8 +704,8 @@ bool bgp_update_delay_configured(struct bgp *bgp)
    on ending the update delay. */
 void bgp_update_delay_end(struct bgp *bgp)
 {
-       THREAD_TIMER_OFF(bgp->t_update_delay);
-       THREAD_TIMER_OFF(bgp->t_establish_wait);
+       THREAD_OFF(bgp->t_update_delay);
+       THREAD_OFF(bgp->t_establish_wait);
 
        /* Reset update-delay related state */
        bgp->update_delay_over = 1;
@@ -740,11 +740,12 @@ void bgp_update_delay_end(struct bgp *bgp)
        bgp->main_zebra_update_hold = 1;
        bgp->main_peers_update_hold = 1;
 
-       /* Resume the queue processing. This should trigger the event that would
-          take
-          care of processing any work that was queued during the read-only
-          mode. */
-       work_queue_unplug(bm->process_main_queue);
+       /*
+        * Resume the queue processing. This should trigger the event that would
+        * take care of processing any work that was queued during the read-only
+        * mode.
+        */
+       work_queue_unplug(bgp->process_queue);
 }
 
 /**
@@ -923,7 +924,7 @@ static int bgp_maxmed_onstartup_timer(struct thread *thread)
        zlog_info("Max med on startup ended - timer expired.");
 
        bgp = THREAD_ARG(thread);
-       THREAD_TIMER_OFF(bgp->t_maxmed_onstartup);
+       THREAD_OFF(bgp->t_maxmed_onstartup);
        bgp->maxmed_onstartup_over = 1;
 
        bgp_maxmed_update(bgp);
@@ -967,7 +968,7 @@ static int bgp_update_delay_timer(struct thread *thread)
        zlog_info("Update delay ended - timer expired.");
 
        bgp = THREAD_ARG(thread);
-       THREAD_TIMER_OFF(bgp->t_update_delay);
+       THREAD_OFF(bgp->t_update_delay);
        bgp_update_delay_end(bgp);
 
        return 0;
@@ -981,7 +982,7 @@ static int bgp_establish_wait_timer(struct thread *thread)
        zlog_info("Establish wait - timer expired.");
 
        bgp = THREAD_ARG(thread);
-       THREAD_TIMER_OFF(bgp->t_establish_wait);
+       THREAD_OFF(bgp->t_establish_wait);
        bgp_check_update_delay(bgp);
 
        return 0;
@@ -997,7 +998,7 @@ static void bgp_update_delay_begin(struct bgp *bgp)
        struct peer *peer;
 
        /* Stop the processing of queued work. Enqueue shall continue */
-       work_queue_plug(bm->process_main_queue);
+       work_queue_plug(bgp->process_queue);
 
        for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer))
                peer->update_delay_over = 0;
index 85c0eccc26371627251d6809ba7284dd4602874c..b9156df617abf14e21d43cb570f3955d685f8613 100644 (file)
@@ -31,8 +31,7 @@
 
 #define BGP_TIMER_OFF(T)                                                       \
        do {                                                                   \
-               if (T)                                                         \
-                       THREAD_TIMER_OFF(T);                                   \
+               THREAD_OFF(T);                                                 \
        } while (0)
 
 #define BGP_EVENT_ADD(P, E)                                                    \
index 412c8e3e5ec0e13dafef76c3e95cd2ec11d378c7..38455b5e02984977f77057c12b511a37e3e15c97 100644 (file)
@@ -31,7 +31,7 @@
 #include "network.h"           // for ERRNO_IO_RETRY
 #include "stream.h"            // for stream_get_endp, stream_getw_from, str...
 #include "ringbuf.h"           // for ringbuf_remain, ringbuf_peek, ringbuf_...
-#include "thread.h"            // for THREAD_OFF, THREAD_ARG, thread, thread...
+#include "thread.h"            // for THREAD_OFF, THREAD_ARG, thread...
 #include "zassert.h"           // for assert
 
 #include "bgpd/bgp_io.h"
@@ -39,6 +39,7 @@
 #include "bgpd/bgp_errors.h"   // for expanded error reference information
 #include "bgpd/bgp_fsm.h"      // for BGP_EVENT_ADD, bgp_event
 #include "bgpd/bgp_packet.h"   // for bgp_notify_send_with_data, bgp_notify...
+#include "bgpd/bgp_trace.h"    // for frrtraces
 #include "bgpd/bgpd.h"         // for peer, BGP_MARKER_SIZE, bgp_master, bm
 /* clang-format on */
 
@@ -234,6 +235,7 @@ static int bgp_process_reads(struct thread *thread)
                        assert(ringbuf_get(ibw, pkt->data, pktsize) == pktsize);
                        stream_set_endp(pkt, pktsize);
 
+                       frrtrace(2, frr_bgp, packet_read, peer, pkt);
                        frr_with_mutex(&peer->io_mtx) {
                                stream_fifo_push(peer->ibuf, pkt);
                        }
index fba954c432bcadeec01afd658941fbc072a90769..4f440cd1f822f8ef9cb6929052f190d337e90fe5 100644 (file)
@@ -215,7 +215,6 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi,
        int command;
        uint16_t flags = 0;
        size_t flags_pos = 0;
-       char addr[PREFIX_STRLEN];
 
        p = bgp_dest_get_prefix(dest);
        local_label = &(dest->local_label);
@@ -242,11 +241,11 @@ void bgp_reg_dereg_for_label(struct bgp_dest *dest, struct bgp_path_info *pi,
                         * always takes precedence over auto-assigned labels.
                         */
                        if (!have_label_to_reg) {
-                               if (BGP_DEBUG(labelpool, LABELPOOL)) {
-                                       prefix2str(p, addr, PREFIX_STRLEN);
-                                       zlog_debug("%s: Requesting label from LP for %s",
-                                                __func__, addr);
-                               }
+                               if (BGP_DEBUG(labelpool, LABELPOOL))
+                                       zlog_debug(
+                                               "%s: Requesting label from LP for %pFX",
+                                               __func__, p);
+
                                /* bgp_reg_for_label_callback() will call back
                                 * __func__ when it gets a label from the pool.
                                 * This means we'll never register FECs without
@@ -422,8 +421,8 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
                                  */
                                flog_err(
                                        EC_BGP_UPDATE_RCV,
-                                       "%s: IPv4 labeled-unicast NLRI is multicast address %s, ignoring",
-                                       peer->host, inet_ntoa(p.u.prefix4));
+                                       "%s: IPv4 labeled-unicast NLRI is multicast address %pI4, ignoring",
+                                       peer->host, &p.u.prefix4);
                                continue;
                        }
                }
index b082aa9c6abef3bf4cd54a064c75f28ecf43d876..21c880e95b2b79133f1130f588b87981373b9844 100644 (file)
@@ -60,6 +60,9 @@
 #include "bgpd/bgp_keepalives.h"
 #include "bgpd/bgp_network.h"
 #include "bgpd/bgp_errors.h"
+#include "lib/routing_nb.h"
+#include "bgpd/bgp_nb.h"
+#include "bgpd/bgp_evpn_mh.h"
 
 #ifdef ENABLE_BGP_VNC
 #include "bgpd/rfapi/rfapi_backend.h"
@@ -205,6 +208,8 @@ static __attribute__((__noreturn__)) void bgp_exit(int status)
        if (bgp_default)
                bgp_delete(bgp_default);
 
+       bgp_evpn_mh_finish();
+
        /* reverse bgp_dump_init */
        bgp_dump_finish();
 
@@ -370,9 +375,11 @@ static void bgp_vrf_terminate(void)
 }
 
 static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
+       &frr_bgp_info,
        &frr_filter_info,
        &frr_interface_info,
        &frr_route_map_info,
+       &frr_routing_info,
        &frr_vrf_info,
 };
 
@@ -497,6 +504,10 @@ int main(int argc, char **argv)
        /* Initializations. */
        bgp_vrf_init();
 
+       hook_register(routing_conf_event,
+                     routing_control_plane_protocols_name_validate);
+
+
        /* BGP related initialization.  */
        bgp_init((unsigned short)instance);
 
index b7f516eaf7893d077d0e29e7ca064a72f89e94de..ff5cfe05fbe80c53e544c3a489b31ecb96b83e06 100644 (file)
@@ -412,8 +412,9 @@ static void bgp_path_info_mpath_lb_update(struct bgp_path_info *path, bool set,
        struct bgp_path_info_mpath *mpath;
 
        if ((mpath = path->mpath) == NULL) {
-               if (!set)
+               if (!set || (cum_bw == 0 && !all_paths_lb))
                        return;
+
                mpath = bgp_path_info_mpath_get(path);
                if (!mpath)
                        return;
index 5ef3cf736daaf4f180e824fa899de8bd404c4e86..0c527efb8c4992fa26e70961deae8c53ba129e4e 100644 (file)
@@ -506,7 +506,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
 
        if (debug)
                zlog_debug(
-                       "%s: entry: leak-to=%s, p=%pRN, type=%d, sub_type=%d",
+                       "%s: entry: leak-to=%s, p=%pBD, type=%d, sub_type=%d",
                        __func__, bgp->name_pretty, bn, source_bpi->type,
                        source_bpi->sub_type);
 
@@ -547,7 +547,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
                        bgp_attr_unintern(&new_attr);
                        if (debug)
                                zlog_debug(
-                                       "%s: ->%s: %pRN: Found route, no change",
+                                       "%s: ->%s: %pBD: Found route, no change",
                                        __func__, bgp->name_pretty, bn);
                        return NULL;
                }
@@ -608,7 +608,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
                bgp_dest_unlock_node(bn);
 
                if (debug)
-                       zlog_debug("%s: ->%s: %pRN Found route, changed attr",
+                       zlog_debug("%s: ->%s: %pBD Found route, changed attr",
                                   __func__, bgp->name_pretty, bn);
 
                return bpi;
@@ -674,7 +674,7 @@ leak_update(struct bgp *bgp, /* destination bgp instance */
        bgp_process(bgp, bn, afi, safi);
 
        if (debug)
-               zlog_debug("%s: ->%s: %pRN: Added new route", __func__,
+               zlog_debug("%s: ->%s: %pBD: Added new route", __func__,
                           bgp->name_pretty, bn);
 
        return new;
@@ -929,7 +929,7 @@ void vpn_leak_from_vrf_withdraw(struct bgp *bgp_vpn,                /* to */
 
        if (debug) {
                zlog_debug(
-                       "%s: entry: leak-from=%s, p=%pRN, type=%d, sub_type=%d",
+                       "%s: entry: leak-from=%s, p=%pBD, type=%d, sub_type=%d",
                        __func__, bgp_vrf->name_pretty, path_vrf->net,
                        path_vrf->type, path_vrf->sub_type);
        }
@@ -1009,7 +1009,7 @@ void vpn_leak_from_vrf_withdraw_all(struct bgp *bgp_vpn, /* to */
                for (bn = bgp_table_top(table); bn; bn = bgp_route_next(bn)) {
                        bpi = bgp_dest_get_bgp_path_info(bn);
                        if (debug && bpi) {
-                               zlog_debug("%s: looking at prefix %pRN",
+                               zlog_debug("%s: looking at prefix %pBD",
                                           __func__, bn);
                        }
 
@@ -1106,13 +1106,9 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf,           /* to */
                return;
        }
 
-       if (debug) {
-               char buf_prefix[PREFIX_STRLEN];
-
-               prefix2str(p, buf_prefix, sizeof(buf_prefix));
-               zlog_debug("%s: updating %s to vrf %s", __func__,
-                               buf_prefix, bgp_vrf->name_pretty);
-       }
+       if (debug)
+               zlog_debug("%s: updating %pFX to vrf %s", __func__, p,
+                          bgp_vrf->name_pretty);
 
        /* shallow copy */
        static_attr = *path_vpn->attr;
@@ -1262,7 +1258,7 @@ vpn_leak_to_vrf_update_onevrf(struct bgp *bgp_vrf,            /* to */
        }
 
        if (debug)
-               zlog_debug("%s: pfx %pRN: num_labels %d", __func__,
+               zlog_debug("%s: pfx %pBD: num_labels %d", __func__,
                           path_vpn->net, num_labels);
 
        /*
@@ -1315,7 +1311,7 @@ void vpn_leak_to_vrf_withdraw(struct bgp *bgp_vpn,            /* from */
        int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF);
 
        if (debug)
-               zlog_debug("%s: entry: p=%pRN, type=%d, sub_type=%d", __func__,
+               zlog_debug("%s: entry: p=%pBD, type=%d, sub_type=%d", __func__,
                           path_vpn->net, path_vpn->type, path_vpn->sub_type);
 
        if (debug)
@@ -2581,7 +2577,7 @@ void vpn_leak_postchange_all(void)
  * also VRF Y should unimport its routes from VRF X table.
  * This will ensure VPN table is cleaned up appropriately.
  */
-int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
+void bgp_vpn_leak_unimport(struct bgp *from_bgp)
 {
        struct bgp *to_bgp;
        const char *tmp_name;
@@ -2593,7 +2589,7 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
        int debug;
 
        if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF)
-               return 0;
+               return;
 
        debug = (BGP_DEBUG(vpn, VPN_LEAK_TO_VRF) |
                     BGP_DEBUG(vpn, VPN_LEAK_FROM_VRF));
@@ -2662,7 +2658,7 @@ int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty)
                        }
                }
        }
-       return 0;
+       return;
 }
 
 /* When a router bgp is configured, there could be a bgp vrf
@@ -2691,8 +2687,7 @@ void bgp_vpn_leak_export(struct bgp *from_bgp)
        idir = BGP_VPN_POLICY_DIR_FROMVPN;
        edir = BGP_VPN_POLICY_DIR_TOVPN;
 
-       export_name = (from_bgp->name ? XSTRDUP(MTYPE_TMP, from_bgp->name)
-                              : XSTRDUP(MTYPE_TMP, VRF_DEFAULT_NAME));
+       export_name = from_bgp->name ? from_bgp->name : VRF_DEFAULT_NAME;
 
        for (afi = 0; afi < AFI_MAX; ++afi) {
                /* vrf leak is for IPv4 and IPv6 Unicast only */
index ccd0d961691dd2c76dde19b1e01fd18c5138cd0d..df2544d608f7cd00d1c76ca4b81e92a6097a1a39 100644 (file)
@@ -266,7 +266,7 @@ extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
 extern void vpn_leak_postchange_all(void);
 extern void vpn_handle_router_id_update(struct bgp *bgp, bool withdraw,
                                        bool is_config);
-extern int bgp_vpn_leak_unimport(struct bgp *from_bgp, struct vty *vty);
+extern void bgp_vpn_leak_unimport(struct bgp *from_bgp);
 extern void bgp_vpn_leak_export(struct bgp *from_bgp);
 
 #endif /* _QUAGGA_BGP_MPLSVPN_H */
diff --git a/bgpd/bgp_nb.c b/bgpd/bgp_nb.c
new file mode 100644 (file)
index 0000000..333ca3c
--- /dev/null
@@ -0,0 +1,7889 @@
+/*
+ * Bgp northbound callbacks registery
+ * Copyright (C) 2020  Nvidia
+ *                    Chirag Shah
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "northbound.h"
+#include "libfrr.h"
+#include "bgpd/bgp_nb.h"
+
+/* clang-format off */
+const struct frr_yang_module_info frr_bgp_info = {
+       .name = "frr-bgp",
+       .nodes = {
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp,
+                               .create = bgp_router_create,
+                               .destroy = bgp_router_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-as",
+                       .cbs = {
+                               .modify = bgp_global_local_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/router-id",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_router_id,
+                               .modify = bgp_global_router_id_modify,
+                               .destroy = bgp_global_router_id_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/identifier",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_confederation_identifier,
+                               .modify = bgp_global_confederation_identifier_modify,
+                               .destroy = bgp_global_confederation_identifier_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/member-as",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_confederation_member_as,
+                               .create = bgp_global_confederation_member_as_create,
+                               .destroy = bgp_global_confederation_member_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_med_config,
+                               .apply_finish = bgp_global_med_config_apply_finish,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/enable-med-admin",
+                       .cbs = {
+                               .modify = bgp_global_med_config_enable_med_admin_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-admin",
+                       .cbs = {
+                               .modify = bgp_global_med_config_max_med_admin_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-time",
+                       .cbs = {
+                               .modify = bgp_global_med_config_max_med_onstart_up_time_modify,
+                               .destroy = bgp_global_med_config_max_med_onstart_up_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-value",
+                       .cbs = {
+                               .modify = bgp_global_med_config_max_med_onstart_up_value_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_route_reflector,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/route-reflector-cluster-id",
+                       .cbs = {
+                               .modify = bgp_global_route_reflector_route_reflector_cluster_id_modify,
+                               .destroy = bgp_global_route_reflector_route_reflector_cluster_id_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/no-client-reflect",
+                       .cbs = {
+                               .modify = bgp_global_route_reflector_no_client_reflect_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/allow-outbound-policy",
+                       .cbs = {
+                               .modify = bgp_global_route_reflector_allow_outbound_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options",
+                       .cbs = {
+                               .apply_finish = bgp_global_route_selection_options_apply_finish,
+                               .cli_show = cli_show_router_bgp_route_selection,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/always-compare-med",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_always_compare_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/deterministic-med",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_deterministic_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/confed-med",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_confed_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/missing-as-worst-med",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_missing_as_worst_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/aspath-confed",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_aspath_confed_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/ignore-as-path-length",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_ignore_as_path_length_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/external-compare-router-id",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_external_compare_router_id_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/allow-multiple-as",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_allow_multiple_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/multi-path-as-set",
+                       .cbs = {
+                               .modify = bgp_global_route_selection_options_multi_path_as_set_modify,
+                               .destroy = bgp_global_route_selection_options_multi_path_as_set_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config",
+                       .cbs = {
+                               .cli_show = cli_show_router_global_neighbor_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/dynamic-neighbors-limit",
+                       .cbs = {
+                               .modify = bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify,
+                               .destroy = bgp_global_global_neighbor_config_dynamic_neighbors_limit_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/log-neighbor-changes",
+                       .cbs = {
+                               .modify = bgp_global_global_neighbor_config_log_neighbor_changes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/wpkt-quanta",
+                       .cbs = {
+                               .modify = bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/rpkt-quanta",
+                       .cbs = {
+                               .modify = bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/enabled",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_enabled_modify,
+                               .destroy = bgp_global_graceful_restart_enabled_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/graceful-restart-disable",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_graceful_restart_disable_modify,
+                               .destroy = bgp_global_graceful_restart_graceful_restart_disable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/preserve-fw-entry",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_preserve_fw_entry_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/restart-time",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_restart_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/stale-routes-time",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_stale_routes_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/selection-deferral-time",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_selection_deferral_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/rib-stale-time",
+                       .cbs = {
+                               .modify = bgp_global_graceful_restart_rib_stale_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/subgroup-pkt-queue-size",
+                       .cbs = {
+                               .cli_show = cli_show_router_global_update_group_config_subgroup_pkt_queue_size,
+                               .modify = bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/coalesce-time",
+                       .cbs = {
+                               .cli_show = cli_show_router_global_update_group_config_coalesce_time,
+                               .modify = bgp_global_global_update_group_config_coalesce_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/rmap-delay-time",
+                       .cbs = {
+                               .modify = bgp_global_global_config_timers_rmap_delay_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/update-delay-time",
+                       .cbs = {
+                               .modify = bgp_global_global_config_timers_update_delay_time_modify,
+                               .destroy = bgp_global_global_config_timers_update_delay_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/establish-wait-time",
+                       .cbs = {
+                               .modify = bgp_global_global_config_timers_establish_wait_time_modify,
+                               .destroy = bgp_global_global_config_timers_establish_wait_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/connect-retry-interval",
+                       .cbs = {
+                               .modify = bgp_global_global_config_timers_connect_retry_interval_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/hold-time",
+                       .cbs = {
+                               .modify = bgp_global_global_config_timers_hold_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/keepalive",
+                       .cbs = {
+                               .modify = bgp_global_global_config_timers_keepalive_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/instance-type-view",
+                       .cbs = {
+                               .modify = bgp_global_instance_type_view_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-multihop-connected-route-check",
+                       .cbs = {
+                               .cli_show = cli_show_router_global_ebgp_multihop_connected_route_check,
+                               .modify = bgp_global_ebgp_multihop_connected_route_check_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/fast-external-failover",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_fast_external_failover,
+                               .modify = bgp_global_fast_external_failover_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-pref",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_local_pref,
+                               .modify = bgp_global_local_pref_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/default-shutdown",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_default_shutdown,
+                               .modify = bgp_global_default_shutdown_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-requires-policy",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_ebgp_requires_policy,
+                               .modify = bgp_global_ebgp_requires_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-hostname",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_show_hostname,
+                               .modify = bgp_global_show_hostname_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-nexthop-hostname",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_show_nexthop_hostname,
+                               .modify = bgp_global_show_nexthop_hostname_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/import-check",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_import_check,
+                               .modify = bgp_global_import_check_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-shutdown/enable",
+                       .cbs = {
+                               .cli_show = cli_show_router_bgp_graceful_shutdown,
+                               .modify = bgp_global_graceful_shutdown_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list",
+                       .cbs = {
+                               .create = bgp_global_bmp_config_target_list_create,
+                               .destroy = bgp_global_bmp_config_target_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/incoming-session/session-list",
+                       .cbs = {
+                               .create = bgp_global_bmp_config_target_list_incoming_session_session_list_create,
+                               .destroy = bgp_global_bmp_config_target_list_incoming_session_session_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list",
+                       .cbs = {
+                               .create = bgp_global_bmp_config_target_list_outgoing_session_session_list_create,
+                               .destroy = bgp_global_bmp_config_target_list_outgoing_session_session_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/min-retry-time",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_outgoing_session_session_list_min_retry_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/max-retry-time",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_outgoing_session_session_list_max_retry_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/mirror",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_mirror_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/stats-time",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_stats_time_modify,
+                               .destroy = bgp_global_bmp_config_target_list_stats_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv4-access-list",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_ipv4_access_list_modify,
+                               .destroy = bgp_global_bmp_config_target_list_ipv4_access_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv6-access-list",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_ipv6_access_list_modify,
+                               .destroy = bgp_global_bmp_config_target_list_ipv6_access_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi",
+                       .cbs = {
+                               .create = bgp_global_bmp_config_target_list_afi_safis_afi_safi_create,
+                               .destroy = bgp_global_bmp_config_target_list_afi_safis_afi_safi_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/mirror-buffer-limit",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_mirror_buffer_limit_modify,
+                               .destroy = bgp_global_bmp_config_mirror_buffer_limit_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_header,
+                               .cli_show_end = cli_show_bgp_global_afi_safi_header_end,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_create,
+                               .destroy = bgp_neighbors_neighbor_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-interface",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_local_interface_modify,
+                               .destroy = bgp_neighbors_neighbor_local_interface_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-port",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_local_port_modify,
+                               .destroy = bgp_neighbors_neighbor_local_port_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/peer-group",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_peer_group_modify,
+                               .destroy = bgp_neighbors_neighbor_peer_group_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/password",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_password_modify,
+                               .destroy = bgp_neighbors_neighbor_password_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ttl-security",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_ttl_security_modify,
+                               .destroy = bgp_neighbors_neighbor_ttl_security_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/solo",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_solo_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/enforce-first-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_enforce_first_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/description",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_description_modify,
+                               .destroy = bgp_neighbors_neighbor_description_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/passive-mode",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_passive_mode_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/dynamic-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_capability_options_dynamic_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/strict-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_capability_options_strict_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/extended-nexthop-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_capability_options_extended_nexthop_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/capability-negotiate",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_capability_options_capability_negotiate_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/override-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_capability_options_override_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/ip",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_update_source_ip_modify,
+                               .destroy = bgp_neighbors_neighbor_update_source_ip_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/interface",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_update_source_interface_modify,
+                               .destroy = bgp_neighbors_neighbor_update_source_interface_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify,
+                               .destroy = bgp_neighbors_neighbor_neighbor_remote_as_remote_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/enabled",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_ebgp_multihop_enabled_modify,
+                               .destroy = bgp_neighbors_neighbor_ebgp_multihop_enabled_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/multihop-ttl",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_modify,
+                               .destroy = bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/disable-connected-check",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_ebgp_multihop_disable_connected_check_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/local-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_local_as_local_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-prepend",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_local_as_no_prepend_modify,
+                               .destroy = bgp_neighbors_neighbor_local_as_no_prepend_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-replace-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_local_as_no_replace_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/enable",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_bfd_options_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/detect-multiplier",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_bfd_options_detect_multiplier_modify,
+                               .destroy = bgp_neighbors_neighbor_bfd_options_detect_multiplier_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/required-min-rx",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_bfd_options_required_min_rx_modify,
+                               .destroy = bgp_neighbors_neighbor_bfd_options_required_min_rx_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/desired-min-tx",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_bfd_options_desired_min_tx_modify,
+                               .destroy = bgp_neighbors_neighbor_bfd_options_desired_min_tx_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/session-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_bfd_options_session_type_modify,
+                               .destroy = bgp_neighbors_neighbor_bfd_options_session_type_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/check-cp-failure",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_bfd_options_check_cp_failure_modify,
+                               .destroy = bgp_neighbors_neighbor_bfd_options_check_cp_failure_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/enable",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_admin_shutdown_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/message",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_admin_shutdown_message_modify,
+                               .destroy = bgp_neighbors_neighbor_admin_shutdown_message_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/enable",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_graceful_restart_enable_modify,
+                               .destroy = bgp_neighbors_neighbor_graceful_restart_enable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-helper",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_modify,
+                               .destroy = bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-disable",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_modify,
+                               .destroy = bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/advertise-interval",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_timers_advertise_interval_modify,
+                               .destroy = bgp_neighbors_neighbor_timers_advertise_interval_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/connect-time",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_timers_connect_time_modify,
+                               .destroy = bgp_neighbors_neighbor_timers_connect_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/hold-time",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_timers_hold_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/keepalive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_timers_keepalive_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/enabled",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_enabled_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/v6only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_v6only_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/peer-group",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_peer_group_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_peer_group_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/password",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_password_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_password_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ttl-security",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_ttl_security_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_ttl_security_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/solo",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_solo_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/enforce-first-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_enforce_first_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/description",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_description_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_description_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/passive-mode",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_passive_mode_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/dynamic-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_capability_options_dynamic_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/strict-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_capability_options_strict_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/extended-nexthop-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_capability_options_extended_nexthop_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/capability-negotiate",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_capability_options_capability_negotiate_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/override-capability",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_capability_options_override_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/ip",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_update_source_ip_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_update_source_ip_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/interface",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_update_source_interface_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_update_source_interface_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/enabled",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/multihop-ttl",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/disable-connected-check",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_ebgp_multihop_disable_connected_check_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/local-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_local_as_local_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-prepend",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-replace-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/enable",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/detect-multiplier",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/required-min-rx",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/desired-min-tx",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/session-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/check-cp-failure",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/enable",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_admin_shutdown_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/message",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/enable",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-helper",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-disable",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/advertise-interval",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/connect-time",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_timers_connect_time_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_timers_connect_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/hold-time",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_timers_hold_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/keepalive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_timers_keepalive_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/enabled",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_enabled_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_create,
+                               .destroy = bgp_peer_groups_peer_group_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv4-listen-range",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_ipv4_listen_range_create,
+                               .destroy = bgp_peer_groups_peer_group_ipv4_listen_range_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv6-listen-range",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_ipv6_listen_range_create,
+                               .destroy = bgp_peer_groups_peer_group_ipv6_listen_range_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/password",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_password_modify,
+                               .destroy = bgp_peer_groups_peer_group_password_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ttl-security",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_ttl_security_modify,
+                               .destroy = bgp_peer_groups_peer_group_ttl_security_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/solo",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_solo_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/enforce-first-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_enforce_first_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/description",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_description_modify,
+                               .destroy = bgp_peer_groups_peer_group_description_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/passive-mode",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_passive_mode_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/dynamic-capability",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_capability_options_dynamic_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/strict-capability",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_capability_options_strict_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/extended-nexthop-capability",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_capability_options_extended_nexthop_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/capability-negotiate",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_capability_options_capability_negotiate_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/override-capability",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_capability_options_override_capability_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/ip",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_update_source_ip_modify,
+                               .destroy = bgp_peer_groups_peer_group_update_source_ip_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/interface",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_update_source_interface_modify,
+                               .destroy = bgp_peer_groups_peer_group_update_source_interface_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/enabled",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_ebgp_multihop_enabled_modify,
+                               .destroy = bgp_peer_groups_peer_group_ebgp_multihop_enabled_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/multihop-ttl",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_modify,
+                               .destroy = bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/disable-connected-check",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_ebgp_multihop_disable_connected_check_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/local-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_local_as_local_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-prepend",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_local_as_no_prepend_modify,
+                               .destroy = bgp_peer_groups_peer_group_local_as_no_prepend_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_local_as_no_replace_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/enable",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_bfd_options_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/detect-multiplier",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_bfd_options_detect_multiplier_modify,
+                               .destroy = bgp_peer_groups_peer_group_bfd_options_detect_multiplier_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/required-min-rx",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_bfd_options_required_min_rx_modify,
+                               .destroy = bgp_peer_groups_peer_group_bfd_options_required_min_rx_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/desired-min-tx",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_bfd_options_desired_min_tx_modify,
+                               .destroy = bgp_peer_groups_peer_group_bfd_options_desired_min_tx_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/session-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_bfd_options_session_type_modify,
+                               .destroy = bgp_peer_groups_peer_group_bfd_options_session_type_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/check-cp-failure",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_bfd_options_check_cp_failure_modify,
+                               .destroy = bgp_peer_groups_peer_group_bfd_options_check_cp_failure_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/enable",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_admin_shutdown_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/message",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_admin_shutdown_message_modify,
+                               .destroy = bgp_peer_groups_peer_group_admin_shutdown_message_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/enable",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_graceful_restart_enable_modify,
+                               .destroy = bgp_peer_groups_peer_group_graceful_restart_enable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-helper",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_modify,
+                               .destroy = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-disable",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_modify,
+                               .destroy = bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/advertise-interval",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_timers_advertise_interval_modify,
+                               .destroy = bgp_peer_groups_peer_group_timers_advertise_interval_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/connect-time",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_timers_connect_time_modify,
+                               .destroy = bgp_peer_groups_peer_group_timers_connect_time_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/hold-time",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_timers_hold_time_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/keepalive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_timers_keepalive_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/enabled",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_network_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/backdoor",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/label-index",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_aggregate_route,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/origin",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/match-med",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/suppress-map",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/distance",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_distance_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/access-list-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/enable",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reuse-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/suppress-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/unreach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ebgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/cluster-length-list",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/metric",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/rmap-policy-import",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_admin_distance_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rd",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label-auto",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/nexthop",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-vpn",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vrf-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-import",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/redirect-rt",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-rt-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-rt-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rt-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_network_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/label-index",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_aggregate_route,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/origin",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/match-med",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/suppress-map",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/distance",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/access-list-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/enable",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reuse-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/suppress-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/unreach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/cluster-length-list",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/rmap-policy-import",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_admin_distance_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rd",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label-auto",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/nexthop",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vpn",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-vpn",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vrf-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-import",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/redirect-rt",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-rt-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-rt-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rt-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ebgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/enable",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reuse-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/suppress-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/unreach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/maximum-paths",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/enable",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reuse-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/suppress-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/unreach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_network_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/backdoor",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/label-index",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/as-set",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/summary-only",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/origin",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/match-med",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/suppress-map",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/distance",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/access-list-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/enable",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reuse-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/suppress-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/unreach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_network_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/backdoor",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_backdoor_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/label-index",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_aggregate_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/as-set",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_as_set_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/summary-only",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_summary_only_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/origin",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/match-med",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/suppress-map",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safi_admin_distance_route_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_unicast_admin_distance_route,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/distance",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/access-list-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish,
+                               .cli_show = cli_show_bgp_global_afi_safi_route_flap_dampening,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/enable",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reuse-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/suppress-above",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/unreach-decay",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-flowspec/flow-spec-config/interface",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config",
+                       .cbs = {
+                               .apply_finish = bgp_global_afi_safis_afi_safi_network_config_apply_finish,
+                               .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy,
+                               .cli_show = cli_show_bgp_global_afi_safi_network_config,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/label-index",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_label_index_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list",
+                       .cbs = {
+                               .create = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_create,
+                               .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/label-index",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_label_index_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_modify,
+                               .destroy = bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/pre-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_pre_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/post-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_post_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/pre-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_pre_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/post-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_post_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/pre-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_pre_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/post-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_post_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/pre-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_pre_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/post-policy",
+                       .cbs = {
+                               .modify = bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_post_policy_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list",
+                       .cbs = {
+                               .create = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify,
+                               .destroy = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration",
+                       .cbs = {
+                               .modify = bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify,
+                       }
+               },
+               {
+                       .xpath = NULL,
+               },
+       }
+};
diff --git a/bgpd/bgp_nb.h b/bgpd/bgp_nb.h
new file mode 100644 (file)
index 0000000..5320214
--- /dev/null
@@ -0,0 +1,3596 @@
+/*
+ * Bgp northbound callbacks api interfaces
+ * Copyright (C) 2020  Nvidia
+ *                    Chirag Shah
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_BGP_NB_H_
+#define _FRR_BGP_NB_H_
+
+#include "northbound.h"
+
+extern const struct frr_yang_module_info frr_bgp_info;
+
+/* prototypes */
+int bgp_router_create(struct nb_cb_create_args *args);
+int bgp_router_destroy(struct nb_cb_destroy_args *args);
+int bgp_global_local_as_modify(struct nb_cb_modify_args *args);
+int bgp_global_router_id_modify(struct nb_cb_modify_args *args);
+int bgp_global_router_id_destroy(struct nb_cb_destroy_args *args);
+int bgp_global_confederation_identifier_modify(struct nb_cb_modify_args *args);
+int bgp_global_confederation_identifier_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_confederation_member_as_create(struct nb_cb_create_args *args);
+int bgp_global_confederation_member_as_destroy(struct nb_cb_destroy_args *args);
+int bgp_global_med_config_enable_med_admin_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_med_config_max_med_admin_modify(struct nb_cb_modify_args *args);
+int bgp_global_med_config_max_med_onstart_up_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_med_config_max_med_onstart_up_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_med_config_max_med_onstart_up_value_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_reflector_route_reflector_cluster_id_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_reflector_route_reflector_cluster_id_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_route_reflector_no_client_reflect_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_reflector_allow_outbound_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_always_compare_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_deterministic_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_confed_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_missing_as_worst_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_aspath_confed_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_ignore_as_path_length_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_external_compare_router_id_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_allow_multiple_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_multi_path_as_set_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_route_selection_options_multi_path_as_set_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_neighbor_config_dynamic_neighbors_limit_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_global_neighbor_config_log_neighbor_changes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_enabled_modify(struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_enabled_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_graceful_restart_preserve_fw_entry_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_restart_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_stale_routes_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_selection_deferral_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_graceful_restart_rib_stale_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_update_group_config_coalesce_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_config_timers_rmap_delay_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_config_timers_update_delay_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_config_timers_update_delay_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_global_config_timers_establish_wait_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_config_timers_establish_wait_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_global_config_timers_connect_retry_interval_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_config_timers_hold_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_global_config_timers_keepalive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_instance_type_view_modify(struct nb_cb_modify_args *args);
+int bgp_global_ebgp_multihop_connected_route_check_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_fast_external_failover_modify(struct nb_cb_modify_args *args);
+int bgp_global_local_pref_modify(struct nb_cb_modify_args *args);
+int bgp_global_default_shutdown_modify(struct nb_cb_modify_args *args);
+int bgp_global_ebgp_requires_policy_modify(struct nb_cb_modify_args *args);
+int bgp_global_show_hostname_modify(struct nb_cb_modify_args *args);
+int bgp_global_show_nexthop_hostname_modify(struct nb_cb_modify_args *args);
+int bgp_global_import_check_modify(struct nb_cb_modify_args *args);
+int bgp_global_graceful_shutdown_enable_modify(struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_create(struct nb_cb_create_args *args);
+int bgp_global_bmp_config_target_list_destroy(struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_incoming_session_session_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_bmp_config_target_list_incoming_session_session_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_min_retry_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_max_retry_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_mirror_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_stats_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_stats_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_ipv4_access_list_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_ipv4_access_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_ipv6_access_list_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_ipv6_access_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_mirror_buffer_limit_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_mirror_buffer_limit_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_create(struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_create(struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_local_interface_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_local_interface_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_local_port_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_local_port_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_peer_group_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_peer_group_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_password_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_password_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_ttl_security_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_ttl_security_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_solo_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_enforce_first_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_description_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_description_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_passive_mode_modify(struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_capability_options_dynamic_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_capability_options_strict_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_capability_options_extended_nexthop_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_capability_options_capability_negotiate_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_capability_options_override_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_update_source_ip_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_update_source_ip_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_update_source_interface_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_update_source_interface_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_ebgp_multihop_enabled_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_ebgp_multihop_enabled_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_ebgp_multihop_disable_connected_check_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_local_as_local_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_local_as_no_prepend_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_local_as_no_prepend_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_local_as_no_replace_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_detect_multiplier_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_detect_multiplier_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_bfd_options_required_min_rx_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_required_min_rx_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_bfd_options_desired_min_tx_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_desired_min_tx_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_bfd_options_session_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_session_type_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_bfd_options_check_cp_failure_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_bfd_options_check_cp_failure_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_admin_shutdown_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_admin_shutdown_message_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_admin_shutdown_message_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_graceful_restart_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_graceful_restart_enable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_timers_advertise_interval_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_timers_advertise_interval_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_timers_connect_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_timers_connect_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_timers_hold_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_timers_keepalive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_enabled_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_create(struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_destroy(struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_v6only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_peer_group_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_peer_group_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_password_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_password_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_ttl_security_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_ttl_security_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_solo_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_enforce_first_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_description_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_description_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_passive_mode_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_capability_options_dynamic_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_capability_options_strict_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_capability_options_extended_nexthop_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_capability_options_capability_negotiate_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_capability_options_override_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_update_source_ip_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_update_source_ip_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_update_source_interface_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_update_source_interface_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_disable_connected_check_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_local_as_local_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_admin_shutdown_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_timers_connect_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_timers_connect_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_timers_hold_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_timers_keepalive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_enabled_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_create(struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_destroy(struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_ipv4_listen_range_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_ipv4_listen_range_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_ipv6_listen_range_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_ipv6_listen_range_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_password_modify(struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_password_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_ttl_security_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_ttl_security_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_solo_modify(struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_enforce_first_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_description_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_description_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_passive_mode_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_capability_options_dynamic_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_capability_options_strict_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_capability_options_extended_nexthop_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_capability_options_capability_negotiate_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_capability_options_override_capability_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_update_source_ip_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_update_source_ip_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_update_source_interface_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_update_source_interface_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_ebgp_multihop_enabled_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_ebgp_multihop_enabled_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_ebgp_multihop_disable_connected_check_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_local_as_local_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_local_as_no_prepend_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_local_as_no_prepend_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_local_as_no_replace_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_bfd_options_required_min_rx_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_required_min_rx_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_bfd_options_session_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_session_type_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_admin_shutdown_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_admin_shutdown_message_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_admin_shutdown_message_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_graceful_restart_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_graceful_restart_enable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_timers_advertise_interval_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_timers_advertise_interval_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_timers_connect_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_timers_connect_time_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_timers_hold_time_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_timers_keepalive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_label_index_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_create(
+       struct nb_cb_create_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_label_index_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args);
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args);
+
+/*
+ * Callback registered with routing_nb lib to validate only
+ * one instance of bgp instance is allowed
+ */
+int routing_control_plane_protocols_name_validate(
+       struct nb_cb_create_args *args);
+
+/* Optional 'cli_show' callbacks. */
+void cli_show_router_bgp(struct vty *vty, struct lyd_node *dnode,
+                        bool show_defaults);
+void cli_show_router_bgp_router_id(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults);
+void cli_show_router_bgp_route_selection(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults);
+void cli_show_router_bgp_ebgp_requires_policy(struct vty *vty,
+                                             struct lyd_node *dnode,
+                                             bool show_defaults);
+void cli_show_router_bgp_default_shutdown(struct vty *vty,
+                                         struct lyd_node *dnode,
+                                         bool show_defaults);
+void cli_show_router_bgp_import_check(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults);
+void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults);
+void cli_show_router_bgp_show_nexthop_hostname(struct vty *vty,
+                                              struct lyd_node *dnode,
+                                              bool show_defaults);
+void cli_show_router_bgp_fast_external_failover(struct vty *vty,
+                                               struct lyd_node *dnode,
+                                               bool show_defaults);
+void cli_show_router_global_neighbor_config(struct vty *vty,
+                                           struct lyd_node *dnode,
+                                           bool show_defaults);
+void cli_show_router_global_update_group_config_subgroup_pkt_queue_size(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_router_global_update_group_config_coalesce_time(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_router_global_ebgp_multihop_connected_route_check(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_router_bgp_local_pref(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_router_bgp_route_reflector(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults);
+void cli_show_router_bgp_confederation_identifier(struct vty *vty,
+                                                 struct lyd_node *dnode,
+                                                 bool show_defaults);
+void cli_show_router_bgp_confederation_member_as(struct vty *vty,
+                                                struct lyd_node *dnode,
+                                                bool show_defaults);
+void cli_show_router_bgp_graceful_shutdown(struct vty *vty,
+                                          struct lyd_node *dnode,
+                                          bool show_defaults);
+void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults);
+void cli_show_bgp_global_afi_safi_header(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults);
+void cli_show_bgp_global_afi_safi_header_end(struct vty *vty,
+                                            struct lyd_node *dnode);
+void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
+                                                struct lyd_node *dnode,
+                                                bool show_defaults);
+void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
+                                                       struct lyd_node *dnode,
+                                                       bool show_defaults);
+void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
+                                                      struct lyd_node *dnode,
+                                                      bool show_defaults);
+void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults);
+
+void bgp_global_route_selection_options_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safis_afi_safi_network_config_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safi_aggregate_route_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safi_admin_distance_route_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+void bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish(
+       struct nb_cb_apply_finish_args *args);
+
+/* xpath macros */
+/* route-list */
+#define FRR_BGP_GLOBAL_XPATH                                                   \
+       "/frr-routing:routing/control-plane-protocols/"                        \
+       "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/"              \
+       "frr-bgp:bgp"
+
+#define FRR_BGP_GLOBAL_AS_XPATH                                                \
+       "/frr-routing:routing/control-plane-protocols/"                        \
+       "control-plane-protocol[type='%s'][name='%s'][vrf='%s']/"              \
+       "frr-bgp:bgp/local-as"
+#define FRR_BGP_AFI_SAFI_REDIST_XPATH                                          \
+       "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/"                  \
+       "redistribution-list[route-type='%s'][route-instance='%s']"
+
+#endif
diff --git a/bgpd/bgp_nb_config.c b/bgpd/bgp_nb_config.c
new file mode 100644 (file)
index 0000000..66dfa2a
--- /dev/null
@@ -0,0 +1,32481 @@
+/*
+ * Bgp northbound config callbacks
+ * Copyright (C) 2020  Nvidia
+ *                    Chirag Shah
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "northbound.h"
+#include "libfrr.h"
+#include "log.h"
+#include "bgpd/bgp_nb.h"
+#include "bgpd/bgp_nb.h"
+#include "bgpd/bgpd.h"
+#include "bgpd/bgp_vty.h"
+#include "bgpd/bgp_mplsvpn.h"
+#include "bgpd/bgp_fsm.h"
+#include "bgpd/bgp_addpath.h"
+#include "bgpd/bgp_updgrp.h"
+#include "bgpd/bgp_io.h"
+#include "bgpd/bgp_damp.h"
+
+FRR_CFG_DEFAULT_ULONG(BGP_CONNECT_RETRY,
+        { .val_ulong = 10, .match_profile = "datacenter", },
+        { .val_ulong = 120 },
+)
+FRR_CFG_DEFAULT_ULONG(BGP_HOLDTIME,
+        { .val_ulong = 9, .match_profile = "datacenter", },
+        { .val_ulong = 180 },
+)
+FRR_CFG_DEFAULT_ULONG(BGP_KEEPALIVE,
+        { .val_ulong = 3, .match_profile = "datacenter", },
+        { .val_ulong = 60 },
+)
+
+int routing_control_plane_protocols_name_validate(
+       struct nb_cb_create_args *args)
+{
+       const char *name;
+
+       name = yang_dnode_get_string(args->dnode, "./name");
+       if (!strmatch(name, "bgp")) {
+               snprintf(args->errmsg, args->errmsg_len,
+                        "per vrf only one bgp instance is supported.");
+               return NB_ERR_VALIDATION;
+       }
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp
+ */
+int bgp_router_create(struct nb_cb_create_args *args)
+{
+       const struct lyd_node *vrf_dnode;
+       struct bgp *bgp;
+       struct vrf *vrf;
+       const char *name = NULL;
+       as_t as;
+       enum bgp_instance_type inst_type;
+       bool is_view_inst = false;
+       int ret;
+       int is_new_bgp = 0;
+
+       inst_type = BGP_INSTANCE_TYPE_DEFAULT;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               vrf_dnode = yang_dnode_get_parent(args->dnode,
+                                                 "control-plane-protocol");
+               vrf = nb_running_get_entry(vrf_dnode, NULL, true);
+
+               if (strmatch(vrf->name, VRF_DEFAULT_NAME)) {
+                       name = NULL;
+               } else {
+                       name = vrf->name;
+                       inst_type = BGP_INSTANCE_TYPE_VRF;
+               }
+
+               as = yang_dnode_get_uint32(args->dnode, "./global/local-as");
+
+               is_view_inst = yang_dnode_get_bool(
+                       args->dnode, "./global/instance-type-view");
+               if (is_view_inst)
+                       inst_type = BGP_INSTANCE_TYPE_VIEW;
+
+               if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                       is_new_bgp = (bgp_lookup(as, name) == NULL);
+
+               ret = bgp_get_vty(&bgp, &as, name, inst_type);
+               if (ret == BGP_ERR_INSTANCE_MISMATCH) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "BGP instance name and AS number mismatch\nBGP instance is already running; AS is %u, input-as %u",
+                               bgp->as, as);
+
+                       return NB_ERR_INCONSISTENCY;
+               }
+               /*
+                * If we just instantiated the default instance, complete
+                * any pending VRF-VPN leaking that was configured via
+                * earlier "router bgp X vrf FOO" blocks.
+                */
+               if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
+                       vpn_leak_postchange_all();
+
+               if (inst_type == BGP_INSTANCE_TYPE_VRF)
+                       bgp_vpn_leak_export(bgp);
+
+               UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO);
+
+               nb_running_set_entry(args->dnode, bgp);
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_router_destroy(struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+
+               if (!bgp)
+                       return NB_OK;
+
+               if (bgp->l3vni) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "Please unconfigure l3vni %u", bgp->l3vni);
+                       return NB_ERR_VALIDATION;
+               }
+
+               /* Cannot delete default instance if vrf instances exist */
+               if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
+                       struct listnode *node;
+                       struct bgp *tmp_bgp;
+
+                       for (ALL_LIST_ELEMENTS_RO(bm->bgp, node, tmp_bgp)) {
+                               if (tmp_bgp->inst_type
+                                   == BGP_INSTANCE_TYPE_VRF) {
+                                       snprintf(
+                                               args->errmsg, args->errmsg_len,
+                                               "Cannot delete default BGP instance. Dependent VRF instances exist\n");
+                                       return NB_ERR_VALIDATION;
+                               }
+                       }
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_unset_entry(args->dnode);
+
+               bgp_vpn_leak_unimport(bgp);
+               bgp_delete(bgp);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-as
+ */
+int bgp_global_local_as_modify(struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       as_t as;
+       const struct lyd_node *vrf_dnode;
+       const char *vrf_name;
+       const char *name = NULL;
+       enum bgp_instance_type inst_type;
+       int ret;
+       bool is_view_inst = false;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               as = yang_dnode_get_uint32(args->dnode, NULL);
+
+               inst_type = BGP_INSTANCE_TYPE_DEFAULT;
+
+               vrf_dnode = yang_dnode_get_parent(args->dnode,
+                                                 "control-plane-protocol");
+               vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf");
+
+               if (strmatch(vrf_name, VRF_DEFAULT_NAME)) {
+                       name = NULL;
+               } else {
+                       name = vrf_name;
+                       inst_type = BGP_INSTANCE_TYPE_VRF;
+               }
+
+               is_view_inst = yang_dnode_get_bool(args->dnode,
+                                                  "../instance-type-view");
+               if (is_view_inst)
+                       inst_type = BGP_INSTANCE_TYPE_VIEW;
+
+               ret = bgp_lookup_by_as_name_type(&bgp, &as, name, inst_type);
+               if (ret == BGP_ERR_INSTANCE_MISMATCH) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "BGP instance name and AS number mismatch\nBGP instance is already running; input-as %u",
+                               as);
+
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               /* NOTE: handled in bgp_global_create callback, the as change
+                * will be rejected in validate phase.
+                */
+               as = yang_dnode_get_uint32(args->dnode, NULL);
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+               if (bgp->as != as) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "BGP instance is already running; AS is %u",
+                                bgp->as);
+                       return NB_ERR_INCONSISTENCY;
+               }
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/router-id
+ */
+int bgp_global_router_id_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       struct in_addr router_id;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+       yang_dnode_get_ipv4(&router_id, args->dnode, NULL);
+       bgp_router_id_static_set(bgp, router_id);
+
+       return NB_OK;
+}
+
+int bgp_global_router_id_destroy(struct nb_cb_destroy_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       struct in_addr router_id;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       router_id.s_addr = 0;
+       bgp_router_id_static_set(bgp, router_id);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/identifier
+ */
+int bgp_global_confederation_identifier_modify(struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       as_t as;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               as = yang_dnode_get_uint32(args->dnode, NULL);
+               if (!as) {
+                       snprintf(args->errmsg, args->errmsg_len, "Invalid AS.");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               as = yang_dnode_get_uint32(args->dnode, NULL);
+
+               bgp_confederation_id_set(bgp, as);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_confederation_identifier_destroy(struct nb_cb_destroy_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       bgp_confederation_id_unset(bgp);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/confederation/member-as
+ */
+int bgp_global_confederation_member_as_create(struct nb_cb_create_args *args)
+{
+       as_t my_as, as;
+       struct bgp *bgp;
+       int ret;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               my_as = yang_dnode_get_uint32(args->dnode,
+                                             "../../../global/local-as");
+               as = yang_dnode_get_uint32(args->dnode, NULL);
+               if (my_as == as) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "Local member-AS %u not allowed in confed peer list",
+                               my_as);
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+               as = yang_dnode_get_uint32(args->dnode, NULL);
+
+               ret = bgp_confederation_peers_add(bgp, as);
+               if (ret == BGP_ERR_INVALID_AS) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "Local member-AS not alloed in confed peer list");
+                       return NB_ERR_INCONSISTENCY;
+               }
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_confederation_member_as_destroy(struct nb_cb_destroy_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       as_t as;
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+       as = yang_dnode_get_uint32(args->dnode, NULL);
+
+       bgp_confederation_peers_remove(bgp, as);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config
+ */
+void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args)
+{
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       bgp_maxmed_update(bgp);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/enable-med-admin
+ */
+int bgp_global_med_config_enable_med_admin_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       bgp->v_maxmed_admin = yang_dnode_get_bool(args->dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-admin
+ */
+int bgp_global_med_config_max_med_admin_modify(struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       uint32_t med_admin_val;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               med_admin_val = yang_dnode_get_uint32(args->dnode, NULL);
+
+               /* enable_med_admin is required to be enabled for max-med-admin
+                * non default value.
+                */
+               if (med_admin_val != BGP_MAXMED_VALUE_DEFAULT
+                   && !yang_dnode_get_bool(args->dnode,
+                                           "../enable-med-admin")) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "enable med admin is not set");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               med_admin_val = yang_dnode_get_uint32(args->dnode, NULL);
+
+               bgp->maxmed_admin_value = med_admin_val;
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-time
+ */
+int bgp_global_med_config_max_med_onstart_up_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               bgp->v_maxmed_onstartup =
+                       yang_dnode_get_uint32(args->dnode, NULL);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_med_config_max_med_onstart_up_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               /* Cancel max-med onstartup if its on */
+               if (bgp->t_maxmed_onstartup) {
+                       THREAD_OFF(bgp->t_maxmed_onstartup);
+                       bgp->maxmed_onstartup_over = 1;
+               }
+
+               bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED;
+               /* Resetting onstartup value as part of dependent node is
+                * detroyed.
+                */
+               bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT;
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/med-config/max-med-onstart-up-value
+ */
+int bgp_global_med_config_max_med_onstart_up_value_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       uint32_t onstartup_val;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               onstartup_val = yang_dnode_get_uint32(args->dnode, NULL);
+
+               if (!yang_dnode_exists(args->dnode,
+                                      "../max-med-onstart-up-time")
+                   && onstartup_val != BGP_MAXMED_VALUE_DEFAULT) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "max-med-onstart-up-time is not set.");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               bgp->maxmed_onstartup_value =
+                       yang_dnode_get_uint32(args->dnode, NULL);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/route-reflector-cluster-id
+ */
+int bgp_global_route_reflector_route_reflector_cluster_id_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       struct in_addr cluster_id;
+       const struct lyd_node_leaf_list *dleaf;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       dleaf = (const struct lyd_node_leaf_list *)args->dnode;
+       if (dleaf->value_type == LY_TYPE_STRING)
+               yang_dnode_get_ipv4(&cluster_id, args->dnode, NULL);
+       else
+               (void)inet_aton(dleaf->value_str, &cluster_id);
+
+       bgp_cluster_id_set(bgp, &cluster_id);
+
+       if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len))
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+int bgp_global_route_reflector_route_reflector_cluster_id_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       bgp_cluster_id_unset(bgp);
+
+       if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len))
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/no-client-reflect
+ */
+int bgp_global_route_reflector_no_client_reflect_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT);
+
+       if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len))
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-reflector/allow-outbound-policy
+ */
+int bgp_global_route_reflector_allow_outbound_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
+
+       update_group_announce_rrclients(bgp);
+
+       if (bgp_clear_star_soft_out(bgp->name, args->errmsg, args->errmsg_len))
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options
+ */
+void bgp_global_route_selection_options_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       bgp_recalculate_all_bestpaths(bgp);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/always-compare-med
+ */
+int bgp_global_route_selection_options_always_compare_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED);
+
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/deterministic-med
+ */
+int bgp_global_route_selection_options_deterministic_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       int bestpath_per_as_used;
+       afi_t afi;
+       safi_t safi;
+       struct peer *peer;
+       struct listnode *node;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+
+               if (!bgp)
+                       return NB_OK;
+
+               /* for deconfiguring deterministic-med case */
+               if (!yang_dnode_get_bool(args->dnode, NULL)
+                   && CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
+                       bestpath_per_as_used = 0;
+
+                       for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
+                               FOREACH_AFI_SAFI (afi, safi)
+                                       if (bgp_addpath_dmed_required(
+                                                   peer->addpath_type[afi]
+                                                                     [safi])) {
+                                               bestpath_per_as_used = 1;
+                                               break;
+                                       }
+
+                               if (bestpath_per_as_used)
+                                       break;
+                       }
+
+                       if (bestpath_per_as_used) {
+                               snprintf(
+                                       args->errmsg, args->errmsg_len,
+                                       "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use");
+                               return NB_ERR_VALIDATION;
+                       }
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               if (yang_dnode_get_bool(args->dnode, NULL))
+                       SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED);
+               else
+                       UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/confed-med
+ */
+int bgp_global_route_selection_options_confed_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/missing-as-worst-med
+ */
+int bgp_global_route_selection_options_missing_as_worst_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/aspath-confed
+ */
+int bgp_global_route_selection_options_aspath_confed_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/ignore-as-path-length
+ */
+int bgp_global_route_selection_options_ignore_as_path_length_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/external-compare-router-id
+ */
+int bgp_global_route_selection_options_external_compare_router_id_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/allow-multiple-as
+ */
+int bgp_global_route_selection_options_allow_multiple_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               if (yang_dnode_get_bool(args->dnode, NULL)) {
+                       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+                       if (yang_dnode_get_bool(args->dnode,
+                                               "../multi-path-as-set")) {
+                               SET_FLAG(bgp->flags,
+                                        BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+                       }
+               } else {
+                       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
+                       /* unset as-set */
+                       UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+               }
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/route-selection-options/multi-path-as-set
+ */
+int bgp_global_route_selection_options_multi_path_as_set_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               if (!CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
+                       SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+
+               } else
+                       zlog_debug(
+                               "%s multi-path-as-set as part of allow-multiple-as modify cb.",
+                               __func__);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_route_selection_options_multi_path_as_set_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+               /* Only unset if it set, it is possible allow_multiple_as_modify
+                * unset this.
+                */
+               if (CHECK_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET)) {
+                       UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+
+                       bgp_recalculate_all_bestpaths(bgp);
+               }
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/dynamic-neighbors-limit
+ */
+int bgp_global_global_neighbor_config_dynamic_neighbors_limit_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       uint32_t listen_limit;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       listen_limit = yang_dnode_get_uint32(args->dnode, NULL);
+
+       bgp_listen_limit_set(bgp, listen_limit);
+
+       return NB_OK;
+}
+
+int bgp_global_global_neighbor_config_dynamic_neighbors_limit_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       bgp_listen_limit_unset(bgp);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/log-neighbor-changes
+ */
+int bgp_global_global_neighbor_config_log_neighbor_changes_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/wpkt-quanta
+ */
+int bgp_global_global_neighbor_config_packet_quanta_config_wpkt_quanta_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       uint32_t quanta;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       quanta = yang_dnode_get_uint32(args->dnode, NULL);
+
+       if (atomic_load_explicit(&bgp->wpkt_quanta, memory_order_relaxed)
+           == BGP_WRITE_PACKET_MAX)
+               bgp_wpkt_quanta_config_vty(bgp, quanta, true);
+       else
+               bgp_wpkt_quanta_config_vty(bgp, quanta, false);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-neighbor-config/packet-quanta-config/rpkt-quanta
+ */
+int bgp_global_global_neighbor_config_packet_quanta_config_rpkt_quanta_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       uint32_t quanta;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       quanta = yang_dnode_get_uint32(args->dnode, NULL);
+
+       if (atomic_load_explicit(&bgp->rpkt_quanta, memory_order_relaxed)
+           == BGP_READ_PACKET_MAX)
+               bgp_rpkt_quanta_config_vty(bgp, quanta, true);
+       else
+               bgp_rpkt_quanta_config_vty(bgp, quanta, false);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/enabled
+ */
+int bgp_global_graceful_restart_enabled_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_graceful_restart_enabled_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/graceful-restart-disable
+ */
+int bgp_global_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/preserve-fw-entry
+ */
+int bgp_global_graceful_restart_preserve_fw_entry_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/restart-time
+ */
+int bgp_global_graceful_restart_restart_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/stale-routes-time
+ */
+int bgp_global_graceful_restart_stale_routes_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/selection-deferral-time
+ */
+int bgp_global_graceful_restart_selection_deferral_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-restart/rib-stale-time
+ */
+int bgp_global_graceful_restart_rib_stale_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/subgroup-pkt-queue-size
+ */
+int bgp_global_global_update_group_config_subgroup_pkt_queue_size_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       uint32_t max_size;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       max_size = yang_dnode_get_uint32(args->dnode, NULL);
+
+       bgp_default_subgroup_pkt_queue_max_set(bgp, max_size);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-update-group-config/coalesce-time
+ */
+int bgp_global_global_update_group_config_coalesce_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+       uint32_t coalesce_time;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       coalesce_time = yang_dnode_get_uint32(args->dnode, NULL);
+
+       if (coalesce_time != BGP_DEFAULT_SUBGROUP_COALESCE_TIME) {
+               bgp->heuristic_coalesce = false;
+               bgp->coalesce_time = coalesce_time;
+       } else {
+               bgp->heuristic_coalesce = true;
+               bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/rmap-delay-time
+ */
+int bgp_global_global_config_timers_rmap_delay_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/update-delay-time
+ */
+int bgp_global_global_config_timers_update_delay_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_global_config_timers_update_delay_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/establish-wait-time
+ */
+int bgp_global_global_config_timers_establish_wait_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_global_config_timers_establish_wait_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/connect-retry-interval
+ */
+int bgp_global_global_config_timers_connect_retry_interval_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/hold-time
+ */
+int bgp_global_global_config_timers_hold_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       unsigned long keepalive = 0;
+       unsigned long holdtime = 0;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               holdtime = yang_dnode_get_uint16(args->dnode, NULL);
+               /* Holdtime value check. */
+               if (holdtime < 3 && holdtime != 0) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "hold time value must be either 0 or greater than 3");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               keepalive = yang_dnode_get_uint16(args->dnode, "../keepalive");
+               holdtime = yang_dnode_get_uint16(args->dnode, NULL);
+
+               bgp_timers_set(bgp, keepalive, holdtime,
+                              DFLT_BGP_CONNECT_RETRY);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/global-config-timers/keepalive
+ */
+int bgp_global_global_config_timers_keepalive_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       unsigned long keepalive = 0;
+       unsigned long holdtime = 0;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time");
+               /* Holdtime value check. */
+               if (holdtime < 3 && holdtime != 0) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "hold time value must be either 0 or greater than 3");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               keepalive = yang_dnode_get_uint16(args->dnode, NULL);
+               holdtime = yang_dnode_get_uint16(args->dnode, "../hold-time");
+
+               bgp_timers_set(bgp, keepalive, holdtime,
+                              DFLT_BGP_CONNECT_RETRY);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/instance-type-view
+ */
+int bgp_global_instance_type_view_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-multihop-connected-route-check
+ */
+int bgp_global_ebgp_multihop_connected_route_check_modify(
+       struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
+
+       if (bgp_clear_star_soft_in(bgp->name, args->errmsg, args->errmsg_len))
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/fast-external-failover
+ */
+int bgp_global_fast_external_failover_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+       if (!yang_dnode_get_bool(args->dnode, NULL)) {
+               SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER);
+       } else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/local-pref
+ */
+int bgp_global_local_pref_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+       struct bgp *bgp;
+       uint32_t local_pref;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+       local_pref = yang_dnode_get_uint32(args->dnode, NULL);
+
+       bgp_default_local_preference_set(bgp, local_pref);
+
+       if (bgp_clear_star_soft_in(bgp->name, args->errmsg, args->errmsg_len))
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/default-shutdown
+ */
+int bgp_global_default_shutdown_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+       bgp->autoshutdown = yang_dnode_get_bool(args->dnode, NULL);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/ebgp-requires-policy
+ */
+int bgp_global_ebgp_requires_policy_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-hostname
+ */
+int bgp_global_show_hostname_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/show-nexthop-hostname
+ */
+int bgp_global_show_nexthop_hostname_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/import-check
+ */
+int bgp_global_import_check_modify(struct nb_cb_modify_args *args)
+{
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       struct bgp *bgp;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       if (yang_dnode_get_bool(args->dnode, NULL))
+               SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
+       else
+               UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
+
+       bgp_static_redo_import_check(bgp);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/graceful-shutdown/enable
+ */
+int bgp_global_graceful_shutdown_enable_modify(struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+               if (yang_dnode_get_bool(args->dnode, NULL))
+                       SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
+               else
+                       UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
+
+               bgp_static_redo_import_check(bgp);
+               bgp_redistribute_redo(bgp);
+
+               if (bgp_clear_star_soft_out(bgp->name, args->errmsg,
+                                           args->errmsg_len))
+                       return NB_ERR_INCONSISTENCY;
+
+               if (bgp_clear_star_soft_in(bgp->name, args->errmsg,
+                                          args->errmsg_len))
+                       return NB_ERR_INCONSISTENCY;
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list
+ */
+int bgp_global_bmp_config_target_list_create(struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/incoming-session/session-list
+ */
+int bgp_global_bmp_config_target_list_incoming_session_session_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_incoming_session_session_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list
+ */
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/min-retry-time
+ */
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_min_retry_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/outgoing-session/session-list/max-retry-time
+ */
+int bgp_global_bmp_config_target_list_outgoing_session_session_list_max_retry_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/mirror
+ */
+int bgp_global_bmp_config_target_list_mirror_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/stats-time
+ */
+int bgp_global_bmp_config_target_list_stats_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_stats_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv4-access-list
+ */
+int bgp_global_bmp_config_target_list_ipv4_access_list_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_ipv4_access_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/ipv6-access-list
+ */
+int bgp_global_bmp_config_target_list_ipv6_access_list_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_ipv6_access_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/mirror-buffer-limit
+ */
+int bgp_global_bmp_config_mirror_buffer_limit_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_bmp_config_mirror_buffer_limit_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi
+ */
+int bgp_global_afi_safis_afi_safi_create(struct nb_cb_create_args *args)
+{
+       const struct lyd_node *vrf_dnode;
+       const char *vrf_name;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               vrf_dnode = yang_dnode_get_parent(args->dnode,
+                                                 "control-plane-protocol");
+               vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf");
+               af_name = yang_dnode_get_string(args->dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if ((!strmatch(vrf_name, VRF_DEFAULT_NAME))
+                   && safi != SAFI_UNICAST && safi != SAFI_MULTICAST
+                   && safi != SAFI_EVPN) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor
+ */
+int bgp_neighbors_neighbor_create(struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-interface
+ */
+int bgp_neighbors_neighbor_local_interface_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_local_interface_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-port
+ */
+int bgp_neighbors_neighbor_local_port_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_local_port_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/peer-group
+ */
+int bgp_neighbors_neighbor_peer_group_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_peer_group_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/password
+ */
+int bgp_neighbors_neighbor_password_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_password_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ttl-security
+ */
+int bgp_neighbors_neighbor_ttl_security_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_ttl_security_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/solo
+ */
+int bgp_neighbors_neighbor_solo_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/enforce-first-as
+ */
+int bgp_neighbors_neighbor_enforce_first_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/description
+ */
+int bgp_neighbors_neighbor_description_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_description_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/passive-mode
+ */
+int bgp_neighbors_neighbor_passive_mode_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/dynamic-capability
+ */
+int bgp_neighbors_neighbor_capability_options_dynamic_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/strict-capability
+ */
+int bgp_neighbors_neighbor_capability_options_strict_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/extended-nexthop-capability
+ */
+int bgp_neighbors_neighbor_capability_options_extended_nexthop_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/capability-negotiate
+ */
+int bgp_neighbors_neighbor_capability_options_capability_negotiate_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/capability-options/override-capability
+ */
+int bgp_neighbors_neighbor_capability_options_override_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/ip
+ */
+int bgp_neighbors_neighbor_update_source_ip_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_update_source_ip_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/update-source/interface
+ */
+int bgp_neighbors_neighbor_update_source_interface_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_update_source_interface_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as-type
+ */
+int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/neighbor-remote-as/remote-as
+ */
+int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_neighbor_remote_as_remote_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/enabled
+ */
+int bgp_neighbors_neighbor_ebgp_multihop_enabled_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_ebgp_multihop_enabled_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/multihop-ttl
+ */
+int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_ebgp_multihop_multihop_ttl_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/ebgp-multihop/disable-connected-check
+ */
+int bgp_neighbors_neighbor_ebgp_multihop_disable_connected_check_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/local-as
+ */
+int bgp_neighbors_neighbor_local_as_local_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-prepend
+ */
+int bgp_neighbors_neighbor_local_as_no_prepend_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_local_as_no_prepend_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/local-as/no-replace-as
+ */
+int bgp_neighbors_neighbor_local_as_no_replace_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/enable
+ */
+int bgp_neighbors_neighbor_bfd_options_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/detect-multiplier
+ */
+int bgp_neighbors_neighbor_bfd_options_detect_multiplier_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_bfd_options_detect_multiplier_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/required-min-rx
+ */
+int bgp_neighbors_neighbor_bfd_options_required_min_rx_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_bfd_options_required_min_rx_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/desired-min-tx
+ */
+int bgp_neighbors_neighbor_bfd_options_desired_min_tx_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_bfd_options_desired_min_tx_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/session-type
+ */
+int bgp_neighbors_neighbor_bfd_options_session_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_bfd_options_session_type_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/bfd-options/check-cp-failure
+ */
+int bgp_neighbors_neighbor_bfd_options_check_cp_failure_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_bfd_options_check_cp_failure_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/enable
+ */
+int bgp_neighbors_neighbor_admin_shutdown_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/admin-shutdown/message
+ */
+int bgp_neighbors_neighbor_admin_shutdown_message_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_admin_shutdown_message_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/enable
+ */
+int bgp_neighbors_neighbor_graceful_restart_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_graceful_restart_enable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-helper
+ */
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_helper_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/graceful-restart/graceful-restart-disable
+ */
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/advertise-interval
+ */
+int bgp_neighbors_neighbor_timers_advertise_interval_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_timers_advertise_interval_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/connect-time
+ */
+int bgp_neighbors_neighbor_timers_connect_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_timers_connect_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/hold-time
+ */
+int bgp_neighbors_neighbor_timers_hold_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/timers/keepalive
+ */
+int bgp_neighbors_neighbor_timers_keepalive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/enabled
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_enabled_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor
+ */
+int bgp_neighbors_unnumbered_neighbor_create(struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/v6only
+ */
+int bgp_neighbors_unnumbered_neighbor_v6only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/peer-group
+ */
+int bgp_neighbors_unnumbered_neighbor_peer_group_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_peer_group_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/password
+ */
+int bgp_neighbors_unnumbered_neighbor_password_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_password_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ttl-security
+ */
+int bgp_neighbors_unnumbered_neighbor_ttl_security_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_ttl_security_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/solo
+ */
+int bgp_neighbors_unnumbered_neighbor_solo_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/enforce-first-as
+ */
+int bgp_neighbors_unnumbered_neighbor_enforce_first_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/description
+ */
+int bgp_neighbors_unnumbered_neighbor_description_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_description_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/passive-mode
+ */
+int bgp_neighbors_unnumbered_neighbor_passive_mode_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/dynamic-capability
+ */
+int bgp_neighbors_unnumbered_neighbor_capability_options_dynamic_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/strict-capability
+ */
+int bgp_neighbors_unnumbered_neighbor_capability_options_strict_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/extended-nexthop-capability
+ */
+int bgp_neighbors_unnumbered_neighbor_capability_options_extended_nexthop_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/capability-negotiate
+ */
+int bgp_neighbors_unnumbered_neighbor_capability_options_capability_negotiate_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/capability-options/override-capability
+ */
+int bgp_neighbors_unnumbered_neighbor_capability_options_override_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/ip
+ */
+int bgp_neighbors_unnumbered_neighbor_update_source_ip_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_update_source_ip_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/update-source/interface
+ */
+int bgp_neighbors_unnumbered_neighbor_update_source_interface_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_update_source_interface_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as-type
+ */
+int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/neighbor-remote-as/remote-as
+ */
+int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_neighbor_remote_as_remote_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/enabled
+ */
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_enabled_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/multihop-ttl
+ */
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_multihop_ttl_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/ebgp-multihop/disable-connected-check
+ */
+int bgp_neighbors_unnumbered_neighbor_ebgp_multihop_disable_connected_check_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/local-as
+ */
+int bgp_neighbors_unnumbered_neighbor_local_as_local_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-prepend
+ */
+int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_local_as_no_prepend_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/local-as/no-replace-as
+ */
+int bgp_neighbors_unnumbered_neighbor_local_as_no_replace_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/enable
+ */
+int bgp_neighbors_unnumbered_neighbor_bfd_options_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/detect-multiplier
+ */
+int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_bfd_options_detect_multiplier_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/required-min-rx
+ */
+int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_bfd_options_required_min_rx_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/desired-min-tx
+ */
+int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_bfd_options_desired_min_tx_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/session-type
+ */
+int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_bfd_options_session_type_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/bfd-options/check-cp-failure
+ */
+int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_bfd_options_check_cp_failure_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/enable
+ */
+int bgp_neighbors_unnumbered_neighbor_admin_shutdown_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/admin-shutdown/message
+ */
+int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_admin_shutdown_message_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/enable
+ */
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_enable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-helper
+ */
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_helper_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/graceful-restart/graceful-restart-disable
+ */
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/advertise-interval
+ */
+int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_timers_advertise_interval_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/connect-time
+ */
+int bgp_neighbors_unnumbered_neighbor_timers_connect_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_timers_connect_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/hold-time
+ */
+int bgp_neighbors_unnumbered_neighbor_timers_hold_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/timers/keepalive
+ */
+int bgp_neighbors_unnumbered_neighbor_timers_keepalive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/enabled
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_enabled_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group
+ */
+int bgp_peer_groups_peer_group_create(struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv4-listen-range
+ */
+int bgp_peer_groups_peer_group_ipv4_listen_range_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_ipv4_listen_range_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ipv6-listen-range
+ */
+int bgp_peer_groups_peer_group_ipv6_listen_range_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_ipv6_listen_range_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/password
+ */
+int bgp_peer_groups_peer_group_password_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_password_destroy(struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ttl-security
+ */
+int bgp_peer_groups_peer_group_ttl_security_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_ttl_security_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/solo
+ */
+int bgp_peer_groups_peer_group_solo_modify(struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/enforce-first-as
+ */
+int bgp_peer_groups_peer_group_enforce_first_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/description
+ */
+int bgp_peer_groups_peer_group_description_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_description_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/passive-mode
+ */
+int bgp_peer_groups_peer_group_passive_mode_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/dynamic-capability
+ */
+int bgp_peer_groups_peer_group_capability_options_dynamic_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/strict-capability
+ */
+int bgp_peer_groups_peer_group_capability_options_strict_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/extended-nexthop-capability
+ */
+int bgp_peer_groups_peer_group_capability_options_extended_nexthop_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/capability-negotiate
+ */
+int bgp_peer_groups_peer_group_capability_options_capability_negotiate_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/capability-options/override-capability
+ */
+int bgp_peer_groups_peer_group_capability_options_override_capability_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/ip
+ */
+int bgp_peer_groups_peer_group_update_source_ip_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_update_source_ip_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/update-source/interface
+ */
+int bgp_peer_groups_peer_group_update_source_interface_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_update_source_interface_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as-type
+ */
+int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/neighbor-remote-as/remote-as
+ */
+int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_neighbor_remote_as_remote_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/enabled
+ */
+int bgp_peer_groups_peer_group_ebgp_multihop_enabled_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_ebgp_multihop_enabled_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/multihop-ttl
+ */
+int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_ebgp_multihop_multihop_ttl_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/ebgp-multihop/disable-connected-check
+ */
+int bgp_peer_groups_peer_group_ebgp_multihop_disable_connected_check_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/local-as
+ */
+int bgp_peer_groups_peer_group_local_as_local_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-prepend
+ */
+int bgp_peer_groups_peer_group_local_as_no_prepend_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_local_as_no_prepend_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/local-as/no-replace-as
+ */
+int bgp_peer_groups_peer_group_local_as_no_replace_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/enable
+ */
+int bgp_peer_groups_peer_group_bfd_options_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/detect-multiplier
+ */
+int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_bfd_options_detect_multiplier_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/required-min-rx
+ */
+int bgp_peer_groups_peer_group_bfd_options_required_min_rx_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_bfd_options_required_min_rx_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/desired-min-tx
+ */
+int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_bfd_options_desired_min_tx_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/session-type
+ */
+int bgp_peer_groups_peer_group_bfd_options_session_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_bfd_options_session_type_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/bfd-options/check-cp-failure
+ */
+int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_bfd_options_check_cp_failure_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/enable
+ */
+int bgp_peer_groups_peer_group_admin_shutdown_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/admin-shutdown/message
+ */
+int bgp_peer_groups_peer_group_admin_shutdown_message_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_admin_shutdown_message_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/enable
+ */
+int bgp_peer_groups_peer_group_graceful_restart_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_graceful_restart_enable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-helper
+ */
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_helper_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/graceful-restart/graceful-restart-disable
+ */
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_graceful_restart_graceful_restart_disable_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/advertise-interval
+ */
+int bgp_peer_groups_peer_group_timers_advertise_interval_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_timers_advertise_interval_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/connect-time
+ */
+int bgp_peer_groups_peer_group_timers_connect_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_timers_connect_time_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/hold-time
+ */
+int bgp_peer_groups_peer_group_timers_hold_time_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/timers/keepalive
+ */
+int bgp_peer_groups_peer_group_timers_keepalive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/enabled
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+void bgp_global_afi_safis_afi_safi_network_config_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       struct prefix prefix;
+       bool is_backdoor = false;
+       uint32_t label_index = BGP_INVALID_LABEL_INDEX;
+       const char *rmap_name = NULL;
+       afi_t afi;
+       safi_t safi;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
+
+       is_backdoor = yang_dnode_get_bool(args->dnode, "./backdoor");
+
+       if (yang_dnode_exists(args->dnode, "./label-index"))
+               label_index =
+                       yang_dnode_get_uint32(args->dnode, "./label-index");
+
+       if (yang_dnode_exists(args->dnode, "./rmap-policy-export"))
+               rmap_name = yang_dnode_get_string(args->dnode,
+                                                 "./rmap-policy-export");
+
+       bgp_static_set(bgp, NULL, &prefix, afi, safi, rmap_name, is_backdoor,
+                      label_index, args->errmsg, args->errmsg_len);
+}
+
+static int bgp_global_afi_safis_afi_safi_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       struct prefix prefix;
+       uint32_t label_index = BGP_INVALID_LABEL_INDEX;
+       const char *rmap_name = NULL;
+       bool is_backdoor = false;
+       afi_t afi;
+       safi_t safi;
+       int ret;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
+
+       if (yang_dnode_exists(args->dnode, "./rmap-policy-export"))
+               rmap_name = yang_dnode_get_string(args->dnode,
+                                                 "./rmap-policy-export");
+
+       if (yang_dnode_exists(args->dnode, "./label-index"))
+               label_index =
+                       yang_dnode_get_uint32(args->dnode, "./label-index");
+
+       if (yang_dnode_exists(args->dnode, "./backdoor"))
+               is_backdoor = yang_dnode_get_bool(args->dnode, "./backdoor");
+
+       ret = bgp_static_set(bgp, "no", &prefix, afi, safi, rmap_name,
+                            is_backdoor, label_index, args->errmsg,
+                            args->errmsg_len);
+       if (ret < 0)
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_create(
+       struct nb_cb_create_args *args)
+{
+       /* Handled in network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/backdoor
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in unicast_network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/label-index
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       struct prefix prefix;
+       uint32_t label_index;
+       afi_t afi;
+       safi_t safi;
+       struct bgp_dest *dest;
+       struct bgp_static *bgp_static;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+               yang_dnode_get_prefix(&prefix, args->dnode, "../prefix");
+               apply_mask(&prefix);
+
+               label_index = yang_dnode_get_uint32(args->dnode, NULL);
+
+               dest = bgp_node_get(bgp->route[afi][safi], &prefix);
+               bgp_static = bgp_dest_get_bgp_static_info(dest);
+               if (bgp_static) {
+                       if (bgp_static->label_index != label_index) {
+                               snprintf(
+                                       args->errmsg, args->errmsg_len,
+                                       "Cannot change label-index: curr %u input %u\n",
+                                       bgp_static->label_index, label_index);
+                               return NB_ERR_VALIDATION;
+                       }
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       /* Handled in unicast_network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/network-config/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in unicast_network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       /* rmap destory alone is not supported by backend, the entire network
+        * config needs to be destroyed.
+        */
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+void bgp_global_afi_safi_aggregate_route_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       struct prefix prefix;
+       const char *rmap_name = NULL;
+       afi_t afi;
+       safi_t safi;
+       uint8_t as_set = 0;
+       int summary_only = 0;
+       uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
+       bool match_med = false;
+       const char *suppress_map = NULL;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
+
+       if (yang_dnode_exists(args->dnode, "./as-set"))
+               as_set = yang_dnode_get_bool(args->dnode, "./as-set");
+
+       summary_only = yang_dnode_get_bool(args->dnode, "./summary-only");
+
+       if (yang_dnode_exists(args->dnode, "./rmap-policy-export"))
+               rmap_name = yang_dnode_get_string(args->dnode,
+                                                 "./rmap-policy-export");
+
+       origin = yang_dnode_get_enum(args->dnode, "./origin");
+       match_med = yang_dnode_get_bool(args->dnode, "./match-med");
+       if (yang_dnode_exists(args->dnode, "./suppress-map"))
+               suppress_map =
+                       yang_dnode_get_string(args->dnode, "./suppress-map");
+
+       bgp_aggregate_set(bgp, &prefix, afi, safi, rmap_name, summary_only,
+                         as_set, origin, match_med, suppress_map, args->errmsg,
+                         args->errmsg_len);
+}
+
+static int
+bgp_global_afi_safi_aggregate_route_destroy(struct nb_cb_destroy_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       struct prefix prefix;
+       afi_t afi;
+       safi_t safi;
+       int ret;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       yang_dnode_get_prefix(&prefix, args->dnode, "./prefix");
+
+       ret = bgp_aggregate_unset(bgp, &prefix, afi, safi, args->errmsg,
+                                 args->errmsg_len);
+
+       if (ret < 0)
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_aggregate_route_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/summary-only
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/origin
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/match-med
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/suppress-map
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+void bgp_global_afi_safi_admin_distance_route_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       const char *prefix_str = NULL;
+       const char *access_list_str = NULL;
+       uint8_t distance;
+       afi_t afi;
+       safi_t safi;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+       prefix_str = yang_dnode_get_string(args->dnode, "./prefix");
+       distance = yang_dnode_get_uint8(args->dnode, "./distance");
+       if (yang_dnode_exists(args->dnode, "./access-list-policy-export"))
+               access_list_str = yang_dnode_get_string(
+                       args->dnode, "./access-list-policy-export");
+
+       bgp_distance_set(distance, prefix_str, access_list_str, afi, safi,
+                        args->errmsg, args->errmsg_len);
+}
+
+static int bgp_global_afi_safi_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       const char *prefix_str = NULL;
+       const char *access_list_str = NULL;
+       uint8_t distance;
+       afi_t afi;
+       safi_t safi;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+       prefix_str = yang_dnode_get_string(args->dnode, "./prefix");
+       distance = yang_dnode_get_uint8(args->dnode, "./distance");
+       if (yang_dnode_exists(args->dnode, "./access-list-policy-export"))
+               access_list_str = yang_dnode_get_string(
+                       args->dnode, "./access-list-policy-export");
+
+       if (bgp_distance_unset(distance, prefix_str, access_list_str, afi, safi,
+                              args->errmsg, args->errmsg_len)
+           != CMD_SUCCESS)
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/distance
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance-route/access-list-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+void bgp_global_afi_safis_afi_safi_route_flap_dampening_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int half = DEFAULT_HALF_LIFE * 60;
+       int reuse = DEFAULT_REUSE;
+       int suppress = DEFAULT_SUPPRESS;
+       int max;
+       char ab_xpath[XPATH_MAXLEN];
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       if (!yang_dnode_get_bool(args->dnode, "./enable")) {
+               bgp_damp_disable(bgp, afi, safi);
+       } else {
+               half = yang_dnode_get_uint8(args->dnode, "./reach-decay");
+               half *= 60;
+               reuse = yang_dnode_get_uint16(args->dnode, "./reuse-above");
+
+               suppress =
+                       yang_dnode_get_uint16(args->dnode, "./suppress-above");
+
+               max = yang_dnode_get_uint8(args->dnode, "./unreach-decay");
+               yang_dnode_get_path(args->dnode, ab_xpath, sizeof(ab_xpath));
+               strlcat(ab_xpath, "/unreach-decay", sizeof(ab_xpath));
+               if (yang_get_default_uint8(ab_xpath) == max)
+                       max = half * 4;
+               else
+                       max *= 60;
+
+               bgp_damp_enable(bgp, afi, safi, half, reuse, suppress, max);
+       }
+}
+
+static int
+bgp_global_afi_safi_route_flap_validation(struct nb_cb_modify_args *args)
+{
+       int reuse;
+       int suppress;
+
+       if (yang_dnode_exists(args->dnode, "../supress-above")
+           && yang_dnode_exists(args->dnode, "../reuse-above")) {
+               suppress =
+                       yang_dnode_get_uint16(args->dnode, "../suppress-above");
+               reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above");
+               if (suppress < reuse) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "Suppress value cannot be less than reuse value \n");
+                       return NB_ERR_VALIDATION;
+               }
+       }
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/enable
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               return bgp_global_afi_safi_route_flap_validation(args);
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/reuse-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       int reuse = DEFAULT_REUSE;
+       int suppress = DEFAULT_SUPPRESS;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               if (yang_dnode_exists(args->dnode, "../suppress-above"))
+                       suppress = yang_dnode_get_uint16(args->dnode,
+                                                        "../suppress-above");
+               reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above");
+               if (suppress < reuse) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "Suppress value cannot be less than reuse value \n");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/suppress-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/route-flap-dampening/unreach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       uint16_t maxpaths, default_maxpaths;
+       int ret;
+       char xpath[XPATH_MAXLEN];
+       char afi_xpath[XPATH_MAXLEN];
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+       maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+
+       snprintf(xpath, sizeof(xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp",
+                "bgp", bgp->name ? bgp->name : VRF_DEFAULT_NAME);
+       snprintf(
+               afi_xpath, sizeof(afi_xpath),
+               "/global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+       strlcat(xpath, afi_xpath, sizeof(xpath));
+       default_maxpaths = yang_get_default_uint16(xpath);
+
+       ret = bgp_maxpaths_config_vty(bgp, afi, safi, BGP_PEER_EBGP, maxpaths,
+                                     0, maxpaths != default_maxpaths ? 1 : 0,
+                                     args->errmsg, args->errmsg_len);
+       if (ret != CMD_SUCCESS)
+               return NB_ERR_INCONSISTENCY;
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ebgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       uint16_t maxpaths;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+               if (maxpaths > MULTIPATH_NUM) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "maxpaths %u is out of range %u", maxpaths,
+                                MULTIPATH_NUM);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp
+ */
+void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       uint16_t maxpaths, default_maxpaths;
+       char xpath[XPATH_MAXLEN];
+       char afi_xpath[XPATH_MAXLEN];
+       uint16_t options = 0;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       maxpaths = yang_dnode_get_uint16(args->dnode, "./maximum-paths");
+       if (yang_dnode_get_bool(args->dnode, "./cluster-length-list"))
+               options = BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN;
+
+       snprintf(xpath, sizeof(xpath), FRR_BGP_GLOBAL_XPATH, "frr-bgp:bgp",
+                "bgp", bgp->name ? bgp->name : VRF_DEFAULT_NAME);
+       snprintf(
+               afi_xpath, sizeof(afi_xpath),
+               "/global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+       strlcat(xpath, afi_xpath, sizeof(xpath));
+       default_maxpaths = yang_get_default_uint16(xpath);
+
+       bgp_maxpaths_config_vty(bgp, afi, safi, BGP_PEER_IBGP, maxpaths,
+                               options, maxpaths != default_maxpaths ? 1 : 0,
+                               args->errmsg, args->errmsg_len);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       uint16_t maxpaths;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+               if (maxpaths > MULTIPATH_NUM) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "maxpaths %u is out of range %u", maxpaths,
+                                MULTIPATH_NUM);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp/cluster-length-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+void bgp_global_afi_safi_ip_unicast_redistribution_list_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int route_type;
+       int route_instance;
+       struct bgp_redist *red;
+       bool changed = false;
+       struct route_map *route_map = NULL;
+       const char *rmap_name = NULL;
+       uint32_t metric = 0;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       route_type = yang_dnode_get_enum(args->dnode, "./route-type");
+       route_instance = yang_dnode_get_uint16(args->dnode, "./route-instance");
+
+       red = bgp_redist_add(bgp, afi, route_type, route_instance);
+
+       if (yang_dnode_exists(args->dnode, "./rmap-policy-import")) {
+               rmap_name = yang_dnode_get_string(args->dnode,
+                                                 "./rmap-policy-import");
+               route_map = route_map_lookup_by_name(rmap_name);
+
+               changed = bgp_redistribute_rmap_set(red, rmap_name, route_map);
+       }
+
+       if (yang_dnode_exists(args->dnode, "./metric")) {
+               metric = yang_dnode_get_uint32(args->dnode, "./metric");
+               changed |= bgp_redistribute_metric_set(bgp, red, afi,
+                                                      route_type, metric);
+       }
+
+       bgp_redistribute_set(bgp, afi, route_type, route_instance, changed);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int route_type;
+       int route_instance;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+               bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+               route_type = yang_dnode_get_enum(args->dnode, "./route-type");
+               route_instance =
+                       yang_dnode_get_uint16(args->dnode, "./route-instance");
+
+               bgp_redistribute_unset(bgp, afi, route_type, route_instance);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/metric
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/rmap-policy-import
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int
+bgp_global_afi_safis_admin_distance_modify(struct nb_cb_apply_finish_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       uint8_t distance_ebgp, distance_ibgp, distance_local;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       distance_ebgp = yang_dnode_get_uint8(args->dnode, "./external");
+       distance_ibgp = yang_dnode_get_uint8(args->dnode, "./internal");
+       distance_local = yang_dnode_get_uint8(args->dnode, "./local");
+
+       bgp->distance_ebgp[afi][safi] = distance_ebgp;
+       bgp->distance_ibgp[afi][safi] = distance_ibgp;
+       bgp->distance_local[afi][safi] = distance_local;
+
+       bgp_announce_routes_distance_update(bgp, afi, safi);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance
+ */
+void bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       bgp_global_afi_safis_admin_distance_modify(args);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       const char *rd_str = NULL;
+       struct prefix_rd prd;
+
+       bgp = nb_running_get_entry(args->dnode, NULL, true);
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+       rd_str = yang_dnode_get_string(args->dnode, NULL);
+       if (!str2prefix_rd(rd_str, &prd)) {
+               snprintf(args->errmsg, args->errmsg_len, "Malformed rd %s\n",
+                        rd_str);
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       /*
+        * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+        */
+       vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                          bgp);
+
+       bgp->vpn_policy[afi].tovpn_rd = prd;
+       SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET);
+
+       /* post-change: re-export vpn routes */
+       vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                           bgp);
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       const char *rd_str = NULL;
+       struct prefix_rd prd;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       rd_str = yang_dnode_get_string(args->dnode, NULL);
+       if (str2prefix_rd(rd_str, &prd)) {
+               snprintf(args->errmsg, args->errmsg_len, "Malformed rd %s \n",
+                        rd_str);
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       /*
+        * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+        */
+       vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                          bgp);
+
+       UNSET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_RD_SET);
+
+       /* post-change: re-export vpn routes */
+       vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                           bgp);
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rd
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, false,
+                                            args->errmsg, args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify(
+                       args);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/label-auto
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       struct prefix p;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       yang_dnode_get_prefix(&p, args->dnode, NULL);
+
+       /*
+        * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+        */
+       vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                          bgp);
+
+       bgp->vpn_policy[afi].tovpn_nexthop = p;
+       SET_FLAG(bgp->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
+
+       /* post-change: re-export vpn routes */
+       vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                           bgp);
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       struct prefix p;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       yang_dnode_get_prefix(&p, args->dnode, NULL);
+
+       /*
+        * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
+        */
+       vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                          bgp);
+       UNSET_FLAG(bgp->vpn_policy[afi].flags,
+                  BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
+       /* post-change: re-export vpn routes */
+       vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, bgp_get_default(),
+                           bgp);
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/nexthop
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, false,
+                                            args->errmsg, args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify(
+       struct nb_cb_modify_args *args, const char *direction_str,
+       bool is_enable)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int previous_state;
+       int flag;
+       vpn_policy_direction_t dir;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       if (!strcmp(direction_str, "import")) {
+               flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT;
+               dir = BGP_VPN_POLICY_DIR_FROMVPN;
+       } else if (!strcmp(direction_str, "export")) {
+               flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT;
+               dir = BGP_VPN_POLICY_DIR_TOVPN;
+       } else {
+               snprintf(args->errmsg, args->errmsg_len,
+                        "unknown direction %s\n", direction_str);
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag);
+
+       if (is_enable) {
+               SET_FLAG(bgp->af_flags[afi][safi], flag);
+               if (!previous_state) {
+                       /* trigger export current vrf */
+                       vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+               }
+       } else {
+               if (previous_state) {
+                       /* trigger un-export current vrf */
+                       vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+               }
+               UNSET_FLAG(bgp->af_flags[afi][safi], flag);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify(
+       struct nb_cb_modify_args *args)
+{
+       bool is_enable = false;
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+
+               if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type
+                   && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "import|export vpn valid only for bgp vrf or default instance");
+                       return NB_ERR_VALIDATION;
+               }
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               if (yang_dnode_get_bool(args->dnode, NULL))
+                       is_enable = true;
+
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify(
+                       args, "import", is_enable);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-vpn
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify(
+       struct nb_cb_modify_args *args)
+{
+       bool is_enable = false;
+       struct bgp *bgp;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+
+               if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type
+                   && BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "import|export vpn valid only for bgp vrf or default instance");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               if (yang_dnode_get_bool(args->dnode, NULL))
+                       is_enable = true;
+
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_export_vpn_modify(
+                       args, "export", is_enable);
+       }
+
+       return NB_OK;
+}
+
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create(
+       struct nb_cb_create_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int ret = 0;
+       as_t as;
+       struct bgp *vrf_bgp, *bgp_default;
+       const char *import_name;
+       char *vname;
+       enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF;
+       struct listnode *node;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       as = bgp->as;
+       import_name = yang_dnode_get_string(args->dnode, "./vrf");
+
+       if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type)
+            && (strcmp(import_name, VRF_DEFAULT_NAME) == 0))
+           || (bgp->name && (strcmp(import_name, bgp->name) == 0))) {
+               snprintf(args->errmsg, args->errmsg_len,
+                        "Cannot %s vrf %s into itself\n", "import",
+                        import_name);
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       bgp_default = bgp_get_default();
+       if (!bgp_default) {
+               /* Auto-create assuming the same AS */
+               ret = bgp_get_vty(&bgp_default, &as, NULL,
+                                 BGP_INSTANCE_TYPE_DEFAULT);
+
+               if (ret) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "VRF default is not configured as a bgp instance");
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       vrf_bgp = bgp_lookup_by_name(import_name);
+       if (!vrf_bgp) {
+               if (strcmp(import_name, VRF_DEFAULT_NAME) == 0)
+                       vrf_bgp = bgp_default;
+               else
+                       /* Auto-create assuming the same AS */
+                       ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type);
+
+               if (ret) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "VRF %s is not configured as a bgp instance\n",
+                                import_name);
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       /* Already importing from "import_vrf"? */
+       for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
+                                 vname)) {
+               if (strcmp(vname, import_name) == 0) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "already importing from vrf %s", import_name);
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       vrf_import_from_vrf(bgp, vrf_bgp, afi, safi);
+
+       return NB_OK;
+}
+
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int ret = 0;
+       as_t as;
+       struct bgp *vrf_bgp, *bgp_default;
+       const char *import_name;
+       enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       as = bgp->as;
+       import_name = yang_dnode_get_string(args->dnode, "./vrf");
+
+       if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type)
+            && (strcmp(import_name, VRF_DEFAULT_NAME) == 0))
+           || (bgp->name && (strcmp(import_name, bgp->name) == 0))) {
+               snprintf(args->errmsg, args->errmsg_len,
+                        "Cannot %s vrf %s into itself\n", "unimport",
+                        import_name);
+               return NB_ERR_INCONSISTENCY;
+       }
+
+       bgp_default = bgp_get_default();
+       if (!bgp_default) {
+               /* Auto-create assuming the same AS */
+               ret = bgp_get_vty(&bgp_default, &as, NULL,
+                                 BGP_INSTANCE_TYPE_DEFAULT);
+
+               if (ret) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len, "%s",
+                               "VRF default is not configured as a bgp instance");
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       vrf_bgp = bgp_lookup_by_name(import_name);
+       if (!vrf_bgp) {
+               if (strcmp(import_name, VRF_DEFAULT_NAME) == 0)
+                       vrf_bgp = bgp_default;
+               else
+                       /* Auto-create assuming the same AS */
+                       ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type);
+
+               if (ret) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "VRF %s is not configured as a bgp instance\n",
+                                import_name);
+                       return NB_ERR_INCONSISTENCY;
+               }
+       }
+
+       vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi);
+
+       return NB_OK;
+}
+
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vrf-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create(
+       struct nb_cb_create_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, true, args->errmsg,
+                                            args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify(
+       struct nb_cb_modify_args *args, const char *dstr)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       const char *rmap_str = NULL;
+       int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
+       vpn_policy_direction_t dir;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       if (!strcmp(dstr, "import")) {
+               rmap_str = yang_dnode_get_string(args->dnode, NULL);
+               dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1;
+       } else if (!strcmp(dstr, "export")) {
+               rmap_str = yang_dnode_get_string(args->dnode, NULL);
+               dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1;
+       } else if (!strcmp(dstr, "both")) {
+               dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1;
+               dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1;
+       }
+
+       for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
+               if (!dodir[dir])
+                       continue;
+
+               vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+
+               if (bgp->vpn_policy[afi].rmap_name[dir])
+                       XFREE(MTYPE_ROUTE_MAP_NAME,
+                             bgp->vpn_policy[afi].rmap_name[dir]);
+               bgp->vpn_policy[afi].rmap_name[dir] =
+                       XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
+               bgp->vpn_policy[afi].rmap[dir] =
+                       route_map_lookup_by_name(rmap_str);
+               if (!bgp->vpn_policy[afi].rmap[dir])
+                       return NB_OK;
+
+
+               vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+       }
+
+       return NB_OK;
+}
+
+static int bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args, const char *dstr)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
+       vpn_policy_direction_t dir;
+
+       af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+       af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+       bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+       if (!strcmp(dstr, "import")) {
+               dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1;
+       } else if (!strcmp(dstr, "export")) {
+               dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1;
+       } else if (!strcmp(dstr, "both")) {
+               dodir[BGP_VPN_POLICY_DIR_FROMVPN] = 1;
+               dodir[BGP_VPN_POLICY_DIR_TOVPN] = 1;
+       }
+
+       for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
+               if (!dodir[dir])
+                       continue;
+
+               vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+
+               if (bgp->vpn_policy[afi].rmap_name[dir])
+                       XFREE(MTYPE_ROUTE_MAP_NAME,
+                             bgp->vpn_policy[afi].rmap_name[dir]);
+               bgp->vpn_policy[afi].rmap_name[dir] = NULL;
+               bgp->vpn_policy[afi].rmap[dir] = NULL;
+
+               vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-import
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, false,
+                                            args->errmsg, args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify(
+                       args, "import");
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, false,
+                                            args->errmsg, args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy(
+                       args, "import");
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify(
+                       args, "export");
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy(
+                       args, "export");
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/redirect-rt
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-rt-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/export-rt-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rt-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create(
+       struct nb_cb_create_args *args)
+{
+       /* Handled in network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in unicast_network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/label-index
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in unicast_network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in unicast_network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_aggregate_route_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/summary-only
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/origin
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/match-med
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/suppress-map
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/distance
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/access-list-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/enable
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               return bgp_global_afi_safi_route_flap_validation(args);
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/reuse-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       int reuse = DEFAULT_REUSE;
+       int suppress = DEFAULT_SUPPRESS;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               if (yang_dnode_exists(args->dnode, "../suppress-above"))
+                       suppress = yang_dnode_get_uint16(args->dnode,
+                                                        "../suppress-above");
+               reuse = yang_dnode_get_uint16(args->dnode, "../reuse-above");
+               if (suppress < reuse) {
+                       snprintf(
+                               args->errmsg, args->errmsg_len,
+                               "Suppress value cannot be less than reuse value \n");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/suppress-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/route-flap-dampening/unreach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ebgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       uint16_t maxpaths;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+               if (maxpaths > MULTIPATH_NUM) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "maxpaths %u is out of range %u", maxpaths,
+                                MULTIPATH_NUM);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/use-multiple-paths/ibgp/cluster-length-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       const struct lyd_node *af_dnode;
+       struct bgp *bgp;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+       int route_type;
+       int route_instance;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+               bgp = nb_running_get_entry(af_dnode, NULL, true);
+
+               route_type = yang_dnode_get_enum(args->dnode, "./route-type");
+               route_instance =
+                       yang_dnode_get_uint16(args->dnode, "./route-instance");
+
+               bgp_redistribute_unset(bgp, afi, route_type, route_instance);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/rmap-policy-import
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance
+ */
+void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       bgp_global_afi_safis_admin_distance_modify(args);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rd
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, false,
+                                            args->errmsg, args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rd_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/label-auto
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/nexthop
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, false,
+                                            args->errmsg, args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_nexthop_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vpn
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-vpn
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-vrf-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create(
+       struct nb_cb_create_args *args)
+{
+       struct bgp *bgp;
+       const struct lyd_node *af_dnode;
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               bgp = nb_running_get_entry(args->dnode, NULL, false);
+               if (!bgp)
+                       return NB_OK;
+               af_dnode = yang_dnode_get_parent(args->dnode, "afi-safi");
+               af_name = yang_dnode_get_string(af_dnode, "./afi-safi-name");
+               yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+               if (!vpn_policy_check_import(bgp, afi, safi, true, args->errmsg,
+                                            args->errmsg_len))
+                       return NB_ERR_VALIDATION;
+
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs_create(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-import
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify(
+                       args, "import");
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy(
+                       args, "import");
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_modify(
+                       args, "export");
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy(
+                       args, "export");
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/redirect-rt
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/import-rt-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/export-rt-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rt-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ebgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       uint16_t maxpaths;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+               if (maxpaths > MULTIPATH_NUM) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "maxpaths %u is out of range %u", maxpaths,
+                                MULTIPATH_NUM);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/enable
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               return bgp_global_afi_safi_route_flap_validation(args);
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/reuse-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/suppress-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast/route-flap-dampening/unreach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ebgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       uint16_t maxpaths;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+               if (maxpaths > MULTIPATH_NUM) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "maxpaths %u is out of range %u", maxpaths,
+                                MULTIPATH_NUM);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/maximum-paths
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+       struct nb_cb_modify_args *args)
+{
+       uint16_t maxpaths;
+
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               maxpaths = yang_dnode_get_uint16(args->dnode, NULL);
+               if (maxpaths > MULTIPATH_NUM) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "maxpaths %u is out of range %u", maxpaths,
+                                MULTIPATH_NUM);
+                       return NB_ERR_VALIDATION;
+               }
+               break;
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/use-multiple-paths/ibgp/cluster-length-list
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/enable
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               return bgp_global_afi_safi_route_flap_validation(args);
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/reuse-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/suppress-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast/route-flap-dampening/unreach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create(
+       struct nb_cb_create_args *args)
+{
+       /* Handled in network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/backdoor
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/label-index
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/as-set
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/summary-only
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/origin
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/match-med
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/aggregate-route/suppress-map
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/distance
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route/access-list-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/distance
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route/access-list-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_access_list_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/enable
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               return bgp_global_afi_safi_route_flap_validation(args);
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/reuse-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/suppress-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/route-flap-dampening/unreach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance
+ */
+void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       bgp_global_afi_safis_admin_distance_modify(args);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/local
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/enable
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+               return bgp_global_afi_safi_route_flap_validation(args);
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/reuse-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_reuse_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/suppress-above
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_suppress_above_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/route-flap-dampening/unreach-decay
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_unreach_decay_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/filter-config/rmap-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_create(
+       struct nb_cb_create_args *args)
+{
+       /* Handled in network_config_apply_finish callback */
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
+
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/backdoor
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_backdoor_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/label-index
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_label_index_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/network-config/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/as-set
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_as_set_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/summary-only
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_summary_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/origin
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_origin_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/match-med
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_match_med_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/aggregate-route/suppress-map
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+               return NB_OK;
+       case NB_EV_APPLY:
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance
+ */
+void bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args)
+{
+       bgp_global_afi_safis_admin_distance_modify(args);
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local
+ */
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify(
+       struct nb_cb_modify_args *args)
+{
+       /* Handled in admin_distance_apply_finish callback */
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-flowspec/flow-spec-config/interface
+ */
+int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_ipv4_flowspec_flow_spec_config_interface_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/label-index
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv4-unicast/network-config/prefix-list/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv4_unicast_network_config_prefix_list_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/label-index
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_label_index_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/l3vpn-ipv6-unicast/network-config/prefix-list/rmap-policy-export
+ */
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_global_afi_safis_afi_safi_l3vpn_ipv6_unicast_network_config_prefix_list_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/pre-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-unicast/common-config/post-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_unicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/pre-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv4-multicast/common-config/post-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv4_multicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/pre-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-unicast/common-config/post-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_unicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/pre-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_pre_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/bmp-config/target-list/afi-safis/afi-safi/ipv6-multicast/common-config/post-policy
+ */
+int bgp_global_bmp_config_target_list_afi_safis_afi_safi_ipv6_multicast_common_config_post_policy_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration
+ */
+int bgp_neighbors_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/neighbors/unnumbered-neighbor/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration
+ */
+int bgp_neighbors_unnumbered_neighbor_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/send-default-route
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_send_default_route_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/default-originate-options/rmap-policy-export
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_default_originate_options_rmap_policy_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-send
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-receive
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/orf-capability/orf-both
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-import
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-import
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/plist-export
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_plist_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-import
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/access-list-export
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_access_list_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-import
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/as-path-filter-list-export
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_as_path_filter_list_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-import
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_import_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-unicast/filter-config/unsupress-map-export
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_unicast_filter_config_unsupress_map_export_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-local-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_local_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-send
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-receive
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/orf-capability/orf-both
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-unicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-send
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-receive
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/orf-capability/orf-both
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-multicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-send
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-receive
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/orf-capability/orf-both
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-multicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_multicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-send
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-receive
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/orf-capability/orf-both
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-labeled-unicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-send
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_send_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-receive
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_receive_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/orf-capability/orf-both
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_orf_capability_orf_both_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-labeled-unicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_labeled_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv4-unicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv4_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/add-paths/path-type
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_add_paths_path_type_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_create(
+       struct nb_cb_create_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/max-prefixes
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_max_prefixes_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tr-restart-timer
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tr_restart_timer_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-shutdown-threshold-pct
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_shutdown_threshold_pct_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/prefix-limit/direction-list/prefix-limit-options/tw-warning-only
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_prefix_limit_direction_list_prefix_limit_options_tw_warning_only_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-all-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_all_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/private-as/remove-private-as-replace
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_private_as_remove_private_as_replace_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-ext-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_ext_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/send-community/send-large-community
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_send_community_send_large_community_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l3vpn-ipv6-unicast/weight/weight-attribute
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l3vpn_ipv6_unicast_weight_weight_attribute_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/allow-own-origin-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_allow_own_origin_as_destroy(
+       struct nb_cb_destroy_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/as-path-options/replace-peer-as
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_as_path_options_replace_peer_as_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/as-path-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_as_path_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/next-hop-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_next_hop_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/attr-unchanged/med-unchanged
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_attr_unchanged_med_unchanged_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/nexthop-self/next-hop-self-force
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_nexthop_self_next_hop_self_force_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/l2vpn-evpn/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_l2vpn_evpn_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv4-flowspec/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv4_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-reflector/route-reflector-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_reflector_route_reflector_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/route-server/route-server-client
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_route_server_route_server_client_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/peer-groups/peer-group/afi-safis/afi-safi/ipv6-flowspec/soft-reconfiguration
+ */
+int bgp_peer_groups_peer_group_afi_safis_afi_safi_ipv6_flowspec_soft_reconfiguration_modify(
+       struct nb_cb_modify_args *args)
+{
+       switch (args->event) {
+       case NB_EV_VALIDATE:
+       case NB_EV_PREPARE:
+       case NB_EV_ABORT:
+       case NB_EV_APPLY:
+               /* TODO: implement me. */
+               break;
+       }
+
+       return NB_OK;
+}
index 0d8214e4d6ea7b87a82623d395f4f52dd2085eab..29cca99fd76410369e24490cdc855a8774241176 100644 (file)
@@ -757,10 +757,10 @@ static void bgp_show_nexthop_paths(struct vty *vty, struct bgp *bgp,
                if (dest->pdest) {
                        prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest),
                                        buf1, sizeof(buf1));
-                       vty_out(vty, "    %d/%d %pRN RD %s %s flags 0x%x\n",
+                       vty_out(vty, "    %d/%d %pBD RD %s %s flags 0x%x\n",
                                afi, safi, dest, buf1, bgp_path->name_pretty, path->flags);
                } else
-                       vty_out(vty, "    %d/%d %pRN %s flags 0x%x\n",
+                       vty_out(vty, "    %d/%d %pBD %s flags 0x%x\n",
                                afi, safi, dest, bgp_path->name_pretty, path->flags);
        }
 }
index e97c34bb5e230c25efea47c34ef2e4deee9c8887..64b10c025219e69464fb610b4385633e1fb00835 100644 (file)
@@ -315,15 +315,12 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,
        bnc->change_flags = 0;
 
        /* debug print the input */
-       if (BGP_DEBUG(nht, NHT)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&nhr->prefix, buf, sizeof(buf));
+       if (BGP_DEBUG(nht, NHT))
                zlog_debug(
-                       "%s(%u): Rcvd NH update %s(%u) - metric %d/%d #nhops %d/%d flags 0x%x",
-                       bnc->bgp->name_pretty, bnc->bgp->vrf_id, buf,
+                       "%s(%u): Rcvd NH update %pFX(%u) - metric %d/%d #nhops %d/%d flags 0x%x",
+                       bnc->bgp->name_pretty, bnc->bgp->vrf_id, &nhr->prefix,
                        bnc->srte_color, nhr->metric, bnc->metric,
                        nhr->nexthop_num, bnc->nexthop_num, bnc->flags);
-       }
 
        if (nhr->metric != bnc->metric)
                bnc->change_flags |= BGP_NEXTHOP_METRIC_CHANGED;
@@ -454,14 +451,10 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
 
        bnc = bnc_find(tree, &nhr.prefix, nhr.srte_color);
        if (!bnc) {
-               if (BGP_DEBUG(nht, NHT)) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(&nhr.prefix, buf, sizeof(buf));
+               if (BGP_DEBUG(nht, NHT))
                        zlog_debug(
-                               "parse nexthop update(%s(%u)(%s)): bnc info not found",
-                               buf, nhr.srte_color, bgp->name_pretty);
-               }
+                               "parse nexthop update(%pFX(%u)(%s)): bnc info not found",
+                               &nhr.prefix, nhr.srte_color, bgp->name_pretty);
                return;
        }
 
@@ -757,7 +750,7 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
                                    path->sub_type, path->attr, dest)) {
                                if (BGP_DEBUG(nht, NHT))
                                        zlog_debug(
-                                               "%s: prefix %pRN (vrf %s), ignoring path due to martian or self-next-hop",
+                                               "%s: prefix %pBD (vrf %s), ignoring path due to martian or self-next-hop",
                                                __func__, dest, bgp_path->name);
                        } else
                                bnc_is_valid_nexthop =
@@ -771,12 +764,12 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)
                                prefix_rd2str((struct prefix_rd *)bgp_dest_get_prefix(dest->pdest),
                                        buf1, sizeof(buf1));
                                zlog_debug(
-                                       "... eval path %d/%d %pRN RD %s %s flags 0x%x",
+                                       "... eval path %d/%d %pBD RD %s %s flags 0x%x",
                                        afi, safi, dest, buf1,
                                        bgp_path->name_pretty, path->flags);
                        } else
                                zlog_debug(
-                                       "... eval path %d/%d %pRN %s flags 0x%x",
+                                       "... eval path %d/%d %pBD %s flags 0x%x",
                                        afi, safi, dest, bgp_path->name_pretty,
                                        path->flags);
                }
index 6c077878b56ad2cb779de7058ce80e8a32c14300..a23acda0a85ce654ef1f13062d22e9e5a93652ad 100644 (file)
@@ -63,6 +63,7 @@
 #include "bgpd/bgp_io.h"
 #include "bgpd/bgp_keepalives.h"
 #include "bgpd/bgp_flowspec.h"
+#include "bgpd/bgp_trace.h"
 
 DEFINE_HOOK(bgp_packet_dump,
                (struct peer *peer, uint8_t type, bgp_size_t size,
@@ -402,12 +403,13 @@ int bgp_generate_updgrp_packets(struct thread *thread)
        /*
         * The code beyond this part deals with update packets, proceed only
         * if peer is Established and updates are not on hold (as part of
-        * update-delay post processing).
+        * update-delay processing).
         */
        if (peer->status != Established)
                return 0;
 
-       if (peer->bgp->main_peers_update_hold)
+       if ((peer->bgp->main_peers_update_hold)
+           || bgp_update_delay_active(peer->bgp))
                return 0;
 
        if (peer->t_routeadv)
@@ -566,9 +568,9 @@ void bgp_open_send(struct peer *peer)
 
        if (bgp_debug_neighbor_events(peer))
                zlog_debug(
-                       "%s sending OPEN, version %d, my as %u, holdtime %d, id %s",
+                       "%s sending OPEN, version %d, my as %u, holdtime %d, id %pI4",
                        peer->host, BGP_VERSION_4, local_as, send_holdtime,
-                       inet_ntoa(peer->local_id));
+                       &peer->local_id);
 
        /* Dump packet if debug option is set. */
        /* bgp_packet_dump (s); */
@@ -1022,8 +1024,8 @@ static int bgp_collision_detect(struct peer *new, struct in_addr remote_id)
                                    && peer->local_as == peer->as)
                                        flog_err(
                                                EC_BGP_ROUTER_ID_SAME,
-                                               "Peer's router-id %s is the same as ours",
-                                               inet_ntoa(remote_id));
+                                               "Peer's router-id %pI4 is the same as ours",
+                                               &remote_id);
 
                                /* 3. Otherwise, the local system closes newly
                                   created
@@ -1115,9 +1117,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
        /* Receive OPEN message log  */
        if (bgp_debug_neighbor_events(peer))
                zlog_debug(
-                       "%s rcv OPEN, version %d, remote-as (in open) %u, holdtime %d, id %s",
-                       peer->host, version, remote_as, holdtime,
-                       inet_ntoa(remote_id));
+                       "%s rcv OPEN, version %d, remote-as (in open) %u, holdtime %d, id %pI4",
+                       peer->host, version, remote_as, holdtime, &remote_id);
 
        /* BEGIN to read the capability here, but dont do it yet */
        mp_capability = 0;
@@ -1219,8 +1220,8 @@ static int bgp_open_receive(struct peer *peer, bgp_size_t size)
            || (peer->sort == BGP_PEER_IBGP
                && ntohl(peer->local_id.s_addr) == ntohl(remote_id.s_addr))) {
                if (bgp_debug_neighbor_events(peer))
-                       zlog_debug("%s bad OPEN, wrong router identifier %s",
-                                  peer->host, inet_ntoa(remote_id));
+                       zlog_debug("%s bad OPEN, wrong router identifier %pI4",
+                                  peer->host, &remote_id);
                bgp_notify_send_with_data(peer, BGP_NOTIFY_OPEN_ERR,
                                          BGP_NOTIFY_OPEN_BAD_BGP_IDENT,
                                          notify_data_remote_id, 4);
@@ -1782,6 +1783,9 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size)
 
        peer->update_time = bgp_clock();
 
+       /* Notify BGP Conditional advertisement scanner process */
+       peer->advmap_table_change = true;
+
        return Receive_UPDATE_message;
 }
 
@@ -2367,6 +2371,7 @@ int bgp_process_packet(struct thread *thread)
                 */
                switch (type) {
                case BGP_MSG_OPEN:
+                       frrtrace(2, frr_bgp, open_process, peer, size);
                        atomic_fetch_add_explicit(&peer->open_in, 1,
                                                  memory_order_relaxed);
                        mprc = bgp_open_receive(peer, size);
@@ -2377,6 +2382,7 @@ int bgp_process_packet(struct thread *thread)
                                        __func__, peer->host);
                        break;
                case BGP_MSG_UPDATE:
+                       frrtrace(2, frr_bgp, update_process, peer, size);
                        atomic_fetch_add_explicit(&peer->update_in, 1,
                                                  memory_order_relaxed);
                        peer->readtime = monotime(NULL);
@@ -2388,6 +2394,7 @@ int bgp_process_packet(struct thread *thread)
                                        __func__, peer->host);
                        break;
                case BGP_MSG_NOTIFY:
+                       frrtrace(2, frr_bgp, notification_process, peer, size);
                        atomic_fetch_add_explicit(&peer->notify_in, 1,
                                                  memory_order_relaxed);
                        mprc = bgp_notify_receive(peer, size);
@@ -2398,6 +2405,7 @@ int bgp_process_packet(struct thread *thread)
                                        __func__, peer->host);
                        break;
                case BGP_MSG_KEEPALIVE:
+                       frrtrace(2, frr_bgp, keepalive_process, peer, size);
                        peer->readtime = monotime(NULL);
                        atomic_fetch_add_explicit(&peer->keepalive_in, 1,
                                                  memory_order_relaxed);
@@ -2410,6 +2418,7 @@ int bgp_process_packet(struct thread *thread)
                        break;
                case BGP_MSG_ROUTE_REFRESH_NEW:
                case BGP_MSG_ROUTE_REFRESH_OLD:
+                       frrtrace(2, frr_bgp, refresh_process, peer, size);
                        atomic_fetch_add_explicit(&peer->refresh_in, 1,
                                                  memory_order_relaxed);
                        mprc = bgp_route_refresh_receive(peer, size);
@@ -2420,6 +2429,7 @@ int bgp_process_packet(struct thread *thread)
                                        __func__, peer->host);
                        break;
                case BGP_MSG_CAPABILITY:
+                       frrtrace(2, frr_bgp, capability_process, peer, size);
                        atomic_fetch_add_explicit(&peer->dynamic_cap_in, 1,
                                                  memory_order_relaxed);
                        mprc = bgp_capability_receive(peer, size);
index f6e5c196cacb39aa15f43ec60bcdcd7ca03b5b09..f7dd08443f2f143982e33e63d7bfccf92465c95b 100644 (file)
@@ -23,6 +23,8 @@
 #include "jhash.h"
 #include "pbr.h"
 
+#include "lib/printfrr.h"
+
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_pbr.h"
 #include "bgpd/bgp_debug.h"
@@ -1438,7 +1440,6 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api)
        int i = 0;
        char return_string[512];
        char *ptr = return_string;
-       char buff[64];
        int nb_items = 0;
        int delta, len = sizeof(return_string);
 
@@ -1449,12 +1450,10 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api)
                struct prefix *p = &(api->src_prefix);
 
                if (api->src_prefix_offset)
-                       delta = snprintf(ptr, len, "@src %s/off%u",
-                                      prefix2str(p, buff, 64),
-                                      api->src_prefix_offset);
+                       delta = snprintfrr(ptr, len, "@src %pFX/off%u", p,
+                                          api->src_prefix_offset);
                else
-                       delta = snprintf(ptr, len, "@src %s",
-                                      prefix2str(p, buff, 64));
+                       delta = snprintfrr(ptr, len, "@src %pFX", p);
                len -= delta;
                ptr += delta;
                INCREMENT_DISPLAY(ptr, nb_items, len);
@@ -1464,12 +1463,10 @@ void bgp_pbr_print_policy_route(struct bgp_pbr_entry_main *api)
 
                INCREMENT_DISPLAY(ptr, nb_items, len);
                if (api->dst_prefix_offset)
-                       delta = snprintf(ptr, len, "@dst %s/off%u",
-                                      prefix2str(p, buff, 64),
-                                      api->dst_prefix_offset);
+                       delta = snprintfrr(ptr, len, "@dst %pFX/off%u", p,
+                                          api->dst_prefix_offset);
                else
-                       delta = snprintf(ptr, len, "@dst %s",
-                                        prefix2str(p, buff, 64));
+                       delta = snprintfrr(ptr, len, "@dst %pFX", p);
                len -= delta;
                ptr += delta;
        }
index 6ba56c7011628a3b71d5fc633181092105d3906f..097ab9254e47010bde9aabe9ab60e396e87da70e 100644 (file)
@@ -29,6 +29,8 @@
 #include "filter.h"
 #include "frrstr.h"
 
+#include "lib/printfrr.h"
+
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_rd.h"
 #include "bgpd/bgp_attr.h"
@@ -182,8 +184,7 @@ char *prefix_rd2str(const struct prefix_rd *prd, char *buf, size_t size)
                return buf;
        } else if (type == RD_TYPE_IP) {
                decode_rd_ip(pnt + 2, &rd_ip);
-               snprintf(buf, size, "%s:%hu", inet_ntoa(rd_ip.ip),
-                        rd_ip.val);
+               snprintfrr(buf, size, "%pI4:%hu", &rd_ip.ip, rd_ip.val);
                return buf;
        }
 #ifdef ENABLE_BGP_VNC
@@ -210,6 +211,6 @@ void form_auto_rd(struct in_addr router_id,
 
        prd->family = AF_UNSPEC;
        prd->prefixlen = 64;
-       snprintf(buf, sizeof(buf), "%s:%hu", inet_ntoa(router_id), rd_id);
+       snprintfrr(buf, sizeof(buf), "%pI4:%hu", &router_id, rd_id);
        (void)str2prefix_rd(buf, prd);
 }
index 15c1df847391cdcdb161e53e6f1970cd319a74ba..8a237e329e2acfcd6c970000764a5567e8a9e87c 100644 (file)
@@ -70,6 +70,7 @@
 #include "bgpd/bgp_addpath.h"
 #include "bgpd/bgp_mac.h"
 #include "bgpd/bgp_network.h"
+#include "bgpd/bgp_trace.h"
 
 #ifdef ENABLE_BGP_VNC
 #include "bgpd/rfapi/rfapi_backend.h"
@@ -84,6 +85,9 @@
 #include "bgpd/bgp_flowspec.h"
 #include "bgpd/bgp_flowspec_util.h"
 #include "bgpd/bgp_pbr.h"
+#include "northbound.h"
+#include "northbound_cli.h"
+#include "bgpd/bgp_nb.h"
 
 #ifndef VTYSH_EXTRACT_PL
 #include "bgpd/bgp_route_clippy.c"
@@ -115,6 +119,14 @@ DEFINE_HOOK(bgp_process,
             struct peer *peer, bool withdraw),
            (bgp, afi, safi, bn, peer, withdraw))
 
+/** Test if path is suppressed. */
+static bool bgp_path_suppressed(struct bgp_path_info *pi)
+{
+       if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
+               return false;
+
+       return listcount(pi->extra->aggr_suppressors) > 0;
+}
 
 struct bgp_dest *bgp_afi_node_get(struct bgp_table *table, afi_t afi,
                                  safi_t safi, const struct prefix *p,
@@ -216,7 +228,7 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
                        unsigned refcount;
 
                        bpi = bgp_path_info_lock(bpi);
-                       refcount = bpi->net->lock - 1;
+                       refcount = bgp_dest_get_lock_count(bpi->net) - 1;
                        bgp_dest_unlock_node((struct bgp_dest *)bpi->net);
                        if (!refcount)
                                bpi->net = NULL;
@@ -314,8 +326,8 @@ static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
        if (CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_SCHEDULED)) {
                if (BGP_DEBUG(update, UPDATE_OUT))
                        zlog_debug(
-                               "Route %pRN is in workqueue and being processed, not deferred.",
-                               bgp_dest_to_rnode(dest));
+                               "Route %pBD is in workqueue and being processed, not deferred.",
+                               dest);
 
                return 0;
        }
@@ -359,14 +371,12 @@ static int bgp_dest_set_defer_flag(struct bgp_dest *dest, bool delete)
         */
        if (set_flag && table) {
                if (bgp && (bgp->gr_info[afi][safi].t_select_deferral)) {
+                       if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
+                               bgp->gr_info[afi][safi].gr_deferred++;
                        SET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
-                       if (dest->rt_node == NULL)
-                               dest->rt_node = listnode_add(
-                                       bgp->gr_info[afi][safi].route_list,
-                                       dest);
                        if (BGP_DEBUG(update, UPDATE_OUT))
-                               zlog_debug("DEFER route %pRN, dest %p, node %p",
-                                          dest, dest, dest->rt_node);
+                               zlog_debug("DEFER route %pBD, dest %p", dest,
+                                          dest);
                        return 0;
                }
        }
@@ -550,6 +560,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
        bool same_esi;
        bool old_proxy;
        bool new_proxy;
+       bool new_origin, exist_origin;
 
        *paths_eq = 0;
 
@@ -723,18 +734,18 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
                        *reason = bgp_path_selection_evpn_lower_ip;
                        if (debug)
                                zlog_debug(
-                                       "%s: %s wins over %s due to same MM seq %u and lower IP %s",
+                                       "%s: %s wins over %s due to same MM seq %u and lower IP %pI4",
                                        pfx_buf, new_buf, exist_buf, new_mm_seq,
-                                       inet_ntoa(new->attr->nexthop));
+                                       &new->attr->nexthop);
                        return 1;
                }
                if (nh_cmp > 0) {
                        *reason = bgp_path_selection_evpn_lower_ip;
                        if (debug)
                                zlog_debug(
-                                       "%s: %s loses to %s due to same MM seq %u and higher IP %s",
+                                       "%s: %s loses to %s due to same MM seq %u and higher IP %pI4",
                                        pfx_buf, new_buf, exist_buf, new_mm_seq,
-                                       inet_ntoa(new->attr->nexthop));
+                                       &new->attr->nexthop);
                        return 0;
                }
        }
@@ -794,8 +805,12 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
         *  - BGP_ROUTE_AGGREGATE
         *  - BGP_ROUTE_REDISTRIBUTE
         */
-       if (!(new->sub_type == BGP_ROUTE_NORMAL ||
-             new->sub_type == BGP_ROUTE_IMPORTED)) {
+       new_origin = !(new->sub_type == BGP_ROUTE_NORMAL ||
+                      new->sub_type == BGP_ROUTE_IMPORTED);
+       exist_origin = !(exist->sub_type == BGP_ROUTE_NORMAL ||
+                        exist->sub_type == BGP_ROUTE_IMPORTED);
+
+       if (new_origin && !exist_origin) {
                *reason = bgp_path_selection_local_route;
                if (debug)
                        zlog_debug(
@@ -804,8 +819,7 @@ static int bgp_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
                return 1;
        }
 
-       if (!(exist->sub_type == BGP_ROUTE_NORMAL ||
-             exist->sub_type == BGP_ROUTE_IMPORTED)) {
+       if (!new_origin && exist_origin) {
                *reason = bgp_path_selection_local_route;
                if (debug)
                        zlog_debug(
@@ -1288,6 +1302,7 @@ static enum filter_type bgp_input_filter(struct peer *peer,
                                         safi_t safi)
 {
        struct bgp_filter *filter;
+       enum filter_type ret = FILTER_PERMIT;
 
        filter = &peer->filter[afi][safi];
 
@@ -1299,26 +1314,43 @@ static enum filter_type bgp_input_filter(struct peer *peer,
        if (DISTRIBUTE_IN_NAME(filter)) {
                FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
 
-               if (access_list_apply(DISTRIBUTE_IN(filter), p) == FILTER_DENY)
-                       return FILTER_DENY;
+               if (access_list_apply(DISTRIBUTE_IN(filter), p)
+                   == FILTER_DENY) {
+                       ret = FILTER_DENY;
+                       goto done;
+               }
        }
 
        if (PREFIX_LIST_IN_NAME(filter)) {
                FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
 
-               if (prefix_list_apply(PREFIX_LIST_IN(filter), p) == PREFIX_DENY)
-                       return FILTER_DENY;
+               if (prefix_list_apply(PREFIX_LIST_IN(filter), p)
+                   == PREFIX_DENY) {
+                       ret = FILTER_DENY;
+                       goto done;
+               }
        }
 
        if (FILTER_LIST_IN_NAME(filter)) {
                FILTER_EXIST_WARN(FILTER_LIST, as, filter);
 
                if (as_list_apply(FILTER_LIST_IN(filter), attr->aspath)
-                   == AS_FILTER_DENY)
-                       return FILTER_DENY;
+                   == AS_FILTER_DENY) {
+                       ret = FILTER_DENY;
+                       goto done;
+               }
        }
 
-       return FILTER_PERMIT;
+done:
+       if (frrtrace_enabled(frr_bgp, input_filter)) {
+               char pfxprint[PREFIX2STR_BUFFER];
+
+               prefix2str(p, pfxprint, sizeof(pfxprint));
+               frrtrace(5, frr_bgp, input_filter, peer, pfxprint, afi, safi,
+                        ret == FILTER_PERMIT ? "permit" : "deny");
+       }
+
+       return ret;
 #undef FILTER_EXIST_WARN
 }
 
@@ -1328,6 +1360,7 @@ static enum filter_type bgp_output_filter(struct peer *peer,
                                          safi_t safi)
 {
        struct bgp_filter *filter;
+       enum filter_type ret = FILTER_PERMIT;
 
        filter = &peer->filter[afi][safi];
 
@@ -1339,27 +1372,43 @@ static enum filter_type bgp_output_filter(struct peer *peer,
        if (DISTRIBUTE_OUT_NAME(filter)) {
                FILTER_EXIST_WARN(DISTRIBUTE, distribute, filter);
 
-               if (access_list_apply(DISTRIBUTE_OUT(filter), p) == FILTER_DENY)
-                       return FILTER_DENY;
+               if (access_list_apply(DISTRIBUTE_OUT(filter), p)
+                   == FILTER_DENY) {
+                       ret = FILTER_DENY;
+                       goto done;
+               }
        }
 
        if (PREFIX_LIST_OUT_NAME(filter)) {
                FILTER_EXIST_WARN(PREFIX_LIST, prefix, filter);
 
                if (prefix_list_apply(PREFIX_LIST_OUT(filter), p)
-                   == PREFIX_DENY)
-                       return FILTER_DENY;
+                   == PREFIX_DENY) {
+                       ret = FILTER_DENY;
+                       goto done;
+               }
        }
 
        if (FILTER_LIST_OUT_NAME(filter)) {
                FILTER_EXIST_WARN(FILTER_LIST, as, filter);
 
                if (as_list_apply(FILTER_LIST_OUT(filter), attr->aspath)
-                   == AS_FILTER_DENY)
-                       return FILTER_DENY;
+                   == AS_FILTER_DENY) {
+                       ret = FILTER_DENY;
+                       goto done;
+               }
        }
 
-       return FILTER_PERMIT;
+       if (frrtrace_enabled(frr_bgp, output_filter)) {
+               char pfxprint[PREFIX2STR_BUFFER];
+
+               prefix2str(p, pfxprint, sizeof(pfxprint));
+               frrtrace(5, frr_bgp, output_filter, peer, pfxprint, afi, safi,
+                        ret == FILTER_PERMIT ? "permit" : "deny");
+       }
+
+done:
+       return ret;
 #undef FILTER_EXIST_WARN
 }
 
@@ -1613,7 +1662,34 @@ void bgp_attr_add_gshut_community(struct attr *attr)
 }
 
 
-static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
+/* Notify BGP Conditional advertisement scanner process. */
+void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp)
+{
+       struct peer *temp_peer;
+       struct peer *peer = SUBGRP_PEER(subgrp);
+       struct listnode *temp_node, *temp_nnode = NULL;
+       afi_t afi = SUBGRP_AFI(subgrp);
+       safi_t safi = SUBGRP_SAFI(subgrp);
+       struct bgp *bgp = SUBGRP_INST(subgrp);
+       struct bgp_filter *filter = &peer->filter[afi][safi];
+
+       if (!ADVERTISE_MAP_NAME(filter))
+               return;
+
+       for (ALL_LIST_ELEMENTS(bgp->peer, temp_node, temp_nnode, temp_peer)) {
+               if (!CHECK_FLAG(peer->flags, PEER_FLAG_CONFIG_NODE))
+                       continue;
+
+               if (peer != temp_peer)
+                       continue;
+
+               temp_peer->advmap_table_change = true;
+               break;
+       }
+}
+
+
+void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
 {
        if (family == AF_INET) {
                attr->nexthop.s_addr = INADDR_ANY;
@@ -1627,7 +1703,8 @@ static void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr)
 
 bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
                             struct update_subgroup *subgrp,
-                            const struct prefix *p, struct attr *attr)
+                            const struct prefix *p, struct attr *attr,
+                            bool skip_rmap_check)
 {
        struct bgp_filter *filter;
        struct peer *from;
@@ -1635,7 +1712,6 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
        struct peer *onlypeer;
        struct bgp *bgp;
        struct attr *piattr;
-       char buf[PREFIX_STRLEN];
        route_map_result_t ret;
        int transparent;
        int reflect;
@@ -1671,9 +1747,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
                 * though they can have peer pointers that reference other
                 * systems
                 */
-               prefix2str(p, buf, PREFIX_STRLEN);
-               zlog_debug("%s: pfx %s bgp_direct->vpn route peer safe",
-                          __func__, buf);
+               zlog_debug("%s: pfx %pFX bgp_direct->vpn route peer safe",
+                          __func__, p);
                samepeer_safe = 1;
        }
 #endif
@@ -1706,10 +1781,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
        }
 
        /* Aggregate-address suppress check. */
-       if (pi->extra && pi->extra->suppress)
-               if (!UNSUPPRESS_MAP_NAME(filter)) {
-                       return false;
-               }
+       if (bgp_path_suppressed(pi) && !UNSUPPRESS_MAP_NAME(filter))
+               return false;
 
        /*
         * If we are doing VRF 2 VRF leaking via the import
@@ -1726,11 +1799,10 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
                mpls_label_t label = bgp_adv_label(dest, pi, peer, afi, safi);
                if (!bgp_is_valid_label(&label)) {
                        if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
-                               zlog_debug("u%" PRIu64 ":s%" PRIu64" %s/%d is filtered - no label (%p)",
+                               zlog_debug("u%" PRIu64 ":s%" PRIu64
+                                          " %pFX is filtered - no label (%p)",
                                           subgrp->update_group->id, subgrp->id,
-                                          inet_ntop(p->family, &p->u.prefix,
-                                                    buf, SU_ADDRSTRLEN),
-                                          p->prefixlen, &label);
+                                          p, &label);
                        return false;
                }
        }
@@ -1771,9 +1843,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
            && (IPV4_ADDR_SAME(&onlypeer->remote_id, &piattr->originator_id))) {
                if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
                        zlog_debug(
-                               "%s [Update:SEND] %s originator-id is same as remote router-id",
-                               onlypeer->host,
-                               prefix2str(p, buf, sizeof(buf)));
+                               "%s [Update:SEND] %pFX originator-id is same as remote router-id",
+                               onlypeer->host, p);
                return false;
        }
 
@@ -1788,10 +1859,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
                                if (bgp_debug_update(NULL, p,
                                                     subgrp->update_group, 0))
                                        zlog_debug(
-                                               "%s [Update:SEND] %s is filtered via ORF",
-                                               peer->host,
-                                               prefix2str(p, buf,
-                                                          sizeof(buf)));
+                                               "%s [Update:SEND] %pFX is filtered via ORF",
+                                               peer->host, p);
                                return false;
                        }
                }
@@ -1799,8 +1868,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
        /* Output filter check. */
        if (bgp_output_filter(peer, p, piattr, afi, safi) == FILTER_DENY) {
                if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
-                       zlog_debug("%s [Update:SEND] %s is filtered",
-                                  peer->host, prefix2str(p, buf, sizeof(buf)));
+                       zlog_debug("%s [Update:SEND] %pFX is filtered",
+                                  peer->host, p);
                return false;
        }
 
@@ -1950,7 +2019,8 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
        bgp_peer_as_override(bgp, afi, safi, peer, attr);
 
        /* Route map & unsuppress-map apply. */
-       if (ROUTE_MAP_OUT_NAME(filter) || (pi->extra && pi->extra->suppress)) {
+       if (!skip_rmap_check
+           && (ROUTE_MAP_OUT_NAME(filter) || bgp_path_suppressed(pi))) {
                struct bgp_path_info rmap_path = {0};
                struct bgp_path_info_extra dummy_rmap_path_extra = {0};
                struct attr dummy_attr = {0};
@@ -1975,7 +2045,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
 
                SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
 
-               if (pi->extra && pi->extra->suppress)
+               if (bgp_path_suppressed(pi))
                        ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
                                              RMAP_BGP, &rmap_path);
                else
@@ -1986,8 +2056,9 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
 
                if (ret == RMAP_DENYMATCH) {
                        if (bgp_debug_update(NULL, p, subgrp->update_group, 0))
-                               zlog_debug("%s [Update:SEND] %s is filtered by route-map",
-                               peer->host, prefix2str(p, buf, sizeof(buf)));
+                               zlog_debug(
+                                       "%s [Update:SEND] %pFX is filtered by route-map",
+                                       peer->host, p);
 
                        bgp_attr_flush(attr);
                        return false;
@@ -2268,10 +2339,11 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
                        if (debug) {
                                bgp_path_info_path_with_addpath_rx_str(
                                        new_select, path_buf);
-                               zlog_debug("%s: %s is the bestpath from AS %u",
-                                          pfx_buf, path_buf,
-                                          aspath_get_first_as(
-                                                  new_select->attr->aspath));
+                               zlog_debug(
+                                       "%pBD: %s is the bestpath from AS %u",
+                                       dest, path_buf,
+                                       aspath_get_first_as(
+                                               new_select->attr->aspath));
                        }
                }
        }
@@ -2345,8 +2417,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
                else
                        snprintf(path_buf, sizeof(path_buf), "NONE");
                zlog_debug(
-                       "%s: After path selection, newbest is %s oldbest was %s",
-                       pfx_buf, path_buf,
+                       "%pBD: After path selection, newbest is %s oldbest was %s",
+                       dest, path_buf,
                        old_select ? old_select->peer->host : "NONE");
        }
 
@@ -2361,8 +2433,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
                        if (pi == new_select) {
                                if (debug)
                                        zlog_debug(
-                                               "%s: %s is the bestpath, add to the multipath list",
-                                               pfx_buf, path_buf);
+                                               "%pBD: %s is the bestpath, add to the multipath list",
+                                               dest, path_buf);
                                bgp_mp_list_add(&mp_list, pi);
                                continue;
                        }
@@ -2379,8 +2451,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
                        if (!bgp_path_info_nexthop_cmp(pi, new_select)) {
                                if (debug)
                                        zlog_debug(
-                                               "%s: %s has the same nexthop as the bestpath, skip it",
-                                               pfx_buf, path_buf);
+                                               "%pBD: %s has the same nexthop as the bestpath, skip it",
+                                               dest, path_buf);
                                continue;
                        }
 
@@ -2391,8 +2463,8 @@ void bgp_best_selection(struct bgp *bgp, struct bgp_dest *dest,
                        if (paths_eq) {
                                if (debug)
                                        zlog_debug(
-                                               "%s: %s is equivalent to the bestpath, add to the multipath list",
-                                               pfx_buf, path_buf);
+                                               "%pBD: %s is equivalent to the bestpath, add to the multipath list",
+                                               dest, path_buf);
                                bgp_mp_list_add(&mp_list, pi);
                        }
                }
@@ -2432,12 +2504,8 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp,
        onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
                                                 : NULL);
 
-       if (BGP_DEBUG(update, UPDATE_OUT)) {
-               char buf_prefix[PREFIX_STRLEN];
-               prefix2str(p, buf_prefix, sizeof(buf_prefix));
-               zlog_debug("%s: p=%s, selected=%p", __func__, buf_prefix,
-                          selected);
-       }
+       if (BGP_DEBUG(update, UPDATE_OUT))
+               zlog_debug("%s: p=%pFX, selected=%p", __func__, p, selected);
 
        /* First update is deferred until ORF or ROUTE-REFRESH is received */
        if (onlypeer && CHECK_FLAG(onlypeer->af_sflags[afi][safi],
@@ -2450,7 +2518,8 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp,
        /* Announcement to the subgroup.  If the route is filtered withdraw it.
         */
        if (selected) {
-               if (subgroup_announce_check(dest, selected, subgrp, p, &attr))
+               if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
+                                           false))
                        bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected);
                else
                        bgp_adj_out_unset_subgroup(dest, subgrp, 1,
@@ -2601,7 +2670,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
                        debug = bgp_debug_bestpath(dest);
                if (debug)
                        zlog_debug(
-                               "%s: bgp delete in progress, ignoring event, p=%pRN",
+                               "%s: bgp delete in progress, ignoring event, p=%pBD",
                                __func__, dest);
                return;
        }
@@ -2625,7 +2694,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
 
        debug = bgp_debug_bestpath(dest);
        if (debug)
-               zlog_debug("%s: p=%pRN afi=%s, safi=%s start", __func__, dest,
+               zlog_debug("%s: p=%pBD afi=%s, safi=%s start", __func__, dest,
                           afi2str(afi), safi2str(safi));
 
        /* The best path calculation for the route is deferred if
@@ -2633,7 +2702,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
         */
        if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
                if (BGP_DEBUG(update, UPDATE_OUT))
-                       zlog_debug("SELECT_DEFER falg set for route %p", dest);
+                       zlog_debug("SELECT_DEFER flag set for route %p", dest);
                return;
        }
 
@@ -2686,7 +2755,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
 
        if (debug)
                zlog_debug(
-                       "%s: p=%pRN afi=%s, safi=%s, old_select=%p, new_select=%p",
+                       "%s: p=%pBD afi=%s, safi=%s, old_select=%p, new_select=%p",
                        __func__, dest, afi2str(afi), safi2str(safi),
                        old_select, new_select);
 
@@ -2849,37 +2918,39 @@ int bgp_best_path_select_defer(struct bgp *bgp, afi_t afi, safi_t safi)
        struct bgp_dest *dest;
        int cnt = 0;
        struct afi_safi_info *thread_info;
-       struct listnode *node = NULL, *nnode = NULL;
 
-       if (bgp->gr_info[afi][safi].t_route_select)
+       if (bgp->gr_info[afi][safi].t_route_select) {
+               struct thread *t = bgp->gr_info[afi][safi].t_route_select;
+
+               thread_info = THREAD_ARG(t);
+               XFREE(MTYPE_TMP, thread_info);
                BGP_TIMER_OFF(bgp->gr_info[afi][safi].t_route_select);
+       }
 
        if (BGP_DEBUG(update, UPDATE_OUT)) {
                zlog_debug("%s: processing route for %s : cnt %d", __func__,
                           get_afi_safi_str(afi, safi, false),
-                          listcount(bgp->gr_info[afi][safi].route_list));
+                          bgp->gr_info[afi][safi].gr_deferred);
        }
 
        /* Process the route list */
-       node = listhead(bgp->gr_info[afi][safi].route_list);
-       while (node) {
-               dest = listgetdata(node);
-               nnode = node->next;
-               list_delete_node(bgp->gr_info[afi][safi].route_list, node);
-               dest->rt_node = NULL;
-
-               if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
-                       UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
-                       bgp_process_main_one(bgp, dest, afi, safi);
-                       cnt++;
-                       if (cnt >= BGP_MAX_BEST_ROUTE_SELECT)
-                               break;
+       for (dest = bgp_table_top(bgp->rib[afi][safi]); dest;
+            dest = bgp_route_next(dest)) {
+               if (!CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER))
+                       continue;
+
+               UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
+               bgp->gr_info[afi][safi].gr_deferred--;
+               bgp_process_main_one(bgp, dest, afi, safi);
+               cnt++;
+               if (cnt >= BGP_MAX_BEST_ROUTE_SELECT) {
+                       bgp_dest_unlock_node(dest);
+                       break;
                }
-               node = nnode;
        }
 
        /* Send EOR message when all routes are processed */
-       if (list_isempty(bgp->gr_info[afi][safi].route_list)) {
+       if (bgp->gr_info[afi][safi].gr_deferred) {
                bgp_send_delayed_eor(bgp);
                /* Send route processing complete message to RIB */
                bgp_zebra_update(afi, safi, bgp->vrf_id,
@@ -2941,18 +3012,21 @@ static void bgp_processq_del(struct work_queue *wq, void *data)
        XFREE(MTYPE_BGP_PROCESS_QUEUE, pqnode);
 }
 
-void bgp_process_queue_init(void)
+void bgp_process_queue_init(struct bgp *bgp)
 {
-       if (!bm->process_main_queue)
-               bm->process_main_queue =
-                       work_queue_new(bm->master, "process_main_queue");
+       if (!bgp->process_queue) {
+               char name[BUFSIZ];
+
+               snprintf(name, BUFSIZ, "process_queue %s", bgp->name_pretty);
+               bgp->process_queue = work_queue_new(bm->master, name);
+       }
 
-       bm->process_main_queue->spec.workfunc = &bgp_process_wq;
-       bm->process_main_queue->spec.del_item_data = &bgp_processq_del;
-       bm->process_main_queue->spec.max_retries = 0;
-       bm->process_main_queue->spec.hold = 50;
+       bgp->process_queue->spec.workfunc = &bgp_process_wq;
+       bgp->process_queue->spec.del_item_data = &bgp_processq_del;
+       bgp->process_queue->spec.max_retries = 0;
+       bgp->process_queue->spec.hold = 50;
        /* Use a higher yield value of 50ms for main queue processing */
-       bm->process_main_queue->spec.yield = 50 * 1000L;
+       bgp->process_queue->spec.yield = 50 * 1000L;
 }
 
 static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
@@ -2972,7 +3046,7 @@ static struct bgp_process_queue *bgp_processq_alloc(struct bgp *bgp)
 void bgp_process(struct bgp *bgp, struct bgp_dest *dest, afi_t afi, safi_t safi)
 {
 #define ARBITRARY_PROCESS_QLEN         10000
-       struct work_queue *wq = bm->process_main_queue;
+       struct work_queue *wq = bgp->process_queue;
        struct bgp_process_queue *pqnode;
        int pqnode_reuse = 0;
 
@@ -3029,13 +3103,13 @@ void bgp_add_eoiu_mark(struct bgp *bgp)
 {
        struct bgp_process_queue *pqnode;
 
-       if (bm->process_main_queue == NULL)
+       if (bgp->process_queue == NULL)
                return;
 
        pqnode = bgp_processq_alloc(bgp);
 
        SET_FLAG(pqnode->flags, BGP_PROCESS_QUEUE_EOIU_MARKER);
-       work_queue_add(bm->process_main_queue, pqnode);
+       work_queue_add(bgp->process_queue, pqnode);
 }
 
 static int bgp_maximum_prefix_restart_timer(struct thread *thread)
@@ -3167,7 +3241,8 @@ bool bgp_maximum_prefix_overflow(struct peer *peer, afi_t afi, safi_t safi,
                UNSET_FLAG(peer->af_sflags[afi][safi],
                           PEER_STATUS_PREFIX_LIMIT);
 
-       if (pcount > (pcount * peer->pmax_threshold[afi][safi] / 100)) {
+       if (pcount
+           > (peer->pmax[afi][safi] * peer->pmax_threshold[afi][safi] / 100)) {
                if (CHECK_FLAG(peer->af_sflags[afi][safi],
                               PEER_STATUS_PREFIX_THRESHOLD)
                    && !always)
@@ -3212,13 +3287,7 @@ void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
                        if (CHECK_FLAG(dest->flags, BGP_NODE_SELECT_DEFER)) {
                                UNSET_FLAG(dest->flags, BGP_NODE_SELECT_DEFER);
                                bgp = pi->peer->bgp;
-                               if ((dest->rt_node)
-                                   && (bgp->gr_info[afi][safi].route_list)) {
-                                       list_delete_node(bgp->gr_info[afi][safi]
-                                                                .route_list,
-                                                        dest->rt_node);
-                                       dest->rt_node = NULL;
-                               }
+                               bgp->gr_info[afi][safi].gr_deferred--;
                        }
                }
        }
@@ -3430,6 +3499,14 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
        uint8_t pi_type = 0;
        uint8_t pi_sub_type = 0;
 
+       if (frrtrace_enabled(frr_bgp, process_update)) {
+               char pfxprint[PREFIX2STR_BUFFER];
+
+               prefix2str(p, pfxprint, sizeof(pfxprint));
+               frrtrace(6, frr_bgp, process_update, peer, pfxprint, addpath_id,
+                        afi, safi, attr);
+       }
+
 #ifdef ENABLE_BGP_VNC
        int vnc_implicit_withdraw = 0;
 #endif
@@ -4287,7 +4364,7 @@ void bgp_stop_announce_route_timer(struct peer_af *paf)
        if (!paf->t_announce_route)
                return;
 
-       THREAD_TIMER_OFF(paf->t_announce_route);
+       thread_cancel(&paf->t_announce_route);
 }
 
 /*
@@ -4311,6 +4388,10 @@ static int bgp_announce_route_timer_expired(struct thread *t)
                return 0;
 
        peer_af_announce_route(paf, 1);
+
+       /* Notify BGP conditional advertisement scanner percess */
+       peer->advmap_config_change[paf->afi][paf->safi] = true;
+
        return 0;
 }
 
@@ -4546,7 +4627,7 @@ static void bgp_clear_route_table(struct peer *peer, afi_t afi, safi_t safi,
                                  struct bgp_table *table)
 {
        struct bgp_dest *dest;
-       int force = bm->process_main_queue ? 0 : 1;
+       int force = peer->bgp->process_queue ? 0 : 1;
 
        if (!table)
                table = peer->bgp->rib[afi][safi];
@@ -4983,8 +5064,8 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                 */
                                flog_err(
                                        EC_BGP_UPDATE_RCV,
-                                       "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
-                                       peer->host, inet_ntoa(p.u.prefix4));
+                                       "%s: IPv4 unicast NLRI is multicast address %pI4, ignoring",
+                                       peer->host, &p.u.prefix4);
                                continue;
                        }
                }
@@ -5538,28 +5619,16 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
 
 /* Configure static BGP network.  When user don't run zebra, static
    route should be installed as valid.  */
-static int bgp_static_set(struct vty *vty, const char *negate,
-                         const char *ip_str, afi_t afi, safi_t safi,
-                         const char *rmap, int backdoor, uint32_t label_index)
+int bgp_static_set(struct bgp *bgp, const char *negate, struct prefix *pfx,
+                  afi_t afi, safi_t safi, const char *rmap, int backdoor,
+                  uint32_t label_index, char *errmsg, size_t errmsg_len)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int ret;
        struct prefix p;
        struct bgp_static *bgp_static;
        struct bgp_dest *dest;
        uint8_t need_update = 0;
 
-       /* Convert IP prefix string to struct prefix. */
-       ret = str2prefix(ip_str, &p);
-       if (!ret) {
-               vty_out(vty, "%% Malformed prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       if (afi == AFI_IP6 && IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6)) {
-               vty_out(vty, "%% Malformed prefix (link-local address)\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
+       prefix_copy(&p, pfx);
        apply_mask(&p);
 
        if (negate) {
@@ -5568,24 +5637,25 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                dest = bgp_node_lookup(bgp->route[afi][safi], &p);
 
                if (!dest) {
-                       vty_out(vty, "%% Can't find static route specified\n");
-                       return CMD_WARNING_CONFIG_FAILED;
+                       snprintf(errmsg, errmsg_len,
+                                "Can't find static route specified\n");
+                       return -1;
                }
 
                bgp_static = bgp_dest_get_bgp_static_info(dest);
 
                if ((label_index != BGP_INVALID_LABEL_INDEX)
                    && (label_index != bgp_static->label_index)) {
-                       vty_out(vty,
-                               "%% label-index doesn't match static route\n");
-                       return CMD_WARNING_CONFIG_FAILED;
+                       snprintf(errmsg, errmsg_len,
+                                "label-index doesn't match static route\n");
+                       return -1;
                }
 
                if ((rmap && bgp_static->rmap.name)
                    && strcmp(rmap, bgp_static->rmap.name)) {
-                       vty_out(vty,
-                               "%% route-map name doesn't match static route\n");
-                       return CMD_WARNING_CONFIG_FAILED;
+                       snprintf(errmsg, errmsg_len,
+                                "route-map name doesn't match static route\n");
+                       return -1;
                }
 
                /* Update BGP RIB. */
@@ -5606,8 +5676,9 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                        /* Configuration change. */
                        /* Label index cannot be changed. */
                        if (bgp_static->label_index != label_index) {
-                               vty_out(vty, "%% cannot change label-index\n");
-                               return CMD_WARNING_CONFIG_FAILED;
+                               snprintf(errmsg, errmsg_len,
+                                        "cannot change label-index\n");
+                               return -1;
                        }
 
                        /* Check previous routes are installed into BGP.  */
@@ -5669,7 +5740,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                        bgp_static_update(bgp, &p, bgp_static, afi, safi);
        }
 
-       return CMD_SUCCESS;
+       return 0;
 }
 
 void bgp_static_add(struct bgp *bgp)
@@ -5745,9 +5816,9 @@ void bgp_static_delete(struct bgp *bgp)
                                                        bgp_dest_get_prefix(
                                                                dest));
                                        bgp_static_free(bgp_static);
-                                       bgp_dest_set_bgp_static_info(dest,
+                                       bgp_dest_set_bgp_static_info(rm,
                                                                     NULL);
-                                       bgp_dest_unlock_node(dest);
+                                       bgp_dest_unlock_node(rm);
                                }
                        } else {
                                bgp_static = bgp_dest_get_bgp_static_info(dest);
@@ -6119,25 +6190,27 @@ DEFUN (no_bgp_table_map,
                                   argv[idx_word]->arg);
 }
 
-DEFPY(bgp_network,
-       bgp_network_cmd,
-       "[no] network \
-       <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
-       [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
-       backdoor$backdoor}]",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "IPv4 prefix\n"
-       "Network number\n"
-       "Network mask\n"
-       "Network mask\n"
-       "Route-map to modify the attributes\n"
-       "Name of the route map\n"
-       "Label index to associate with the prefix\n"
-       "Label index value\n"
-       "Specify a BGP backdoor route\n")
-{
-       char addr_prefix_str[BUFSIZ];
+DEFPY_YANG (bgp_network, bgp_network_cmd,
+           "[no] network \
+           <A.B.C.D/M$prefix|A.B.C.D$address [mask A.B.C.D$netmask]> \
+           [{route-map WORD$map_name|label-index (0-1048560)$label_index| \
+           backdoor$backdoor}]",
+           NO_STR
+           "Specify a network to announce via BGP\n"
+           "IPv4 prefix\n"
+           "Network number\n"
+           "Network mask\n"
+           "Network mask\n"
+           "Route-map to modify the attributes\n"
+           "Name of the route map\n"
+           "Label index to associate with the prefix\n"
+           "Label index value\n"
+           "Specify a BGP backdoor route\n")
+{
+       char addr_prefix_str[PREFIX_STRLEN];
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
 
        if (address_str) {
                int ret;
@@ -6150,27 +6223,102 @@ DEFPY(bgp_network,
                }
        }
 
-       return bgp_static_set(
-               vty, no, address_str ? addr_prefix_str : prefix_str, AFI_IP,
-               bgp_node_safi(vty), map_name, backdoor ? 1 : 0,
-               label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       if (no) {
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       } else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+               if (map_name)
+                       nb_cli_enqueue_change(vty, "./rmap-policy-export",
+                                             NB_OP_CREATE, map_name);
+               else
+                       nb_cli_enqueue_change(vty, "./rmap-policy-export",
+                                             NB_OP_DESTROY, NULL);
+
+               if (label_index_str)
+                       nb_cli_enqueue_change(vty, "./label-index",
+                                             NB_OP_MODIFY, label_index_str);
+
+               nb_cli_enqueue_change(vty, "./backdoor", NB_OP_MODIFY,
+                                     backdoor ? "true" : "false");
+       }
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi),
+               address_str ? addr_prefix_str : prefix_str);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFPY(ipv6_bgp_network,
-       ipv6_bgp_network_cmd,
-       "[no] network X:X::X:X/M$prefix \
-       [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
-       NO_STR
-       "Specify a network to announce via BGP\n"
-       "IPv6 prefix\n"
-       "Route-map to modify the attributes\n"
-       "Name of the route map\n"
-       "Label index to associate with the prefix\n"
-       "Label index value\n")
+DEFPY_YANG (ipv6_bgp_network,
+           ipv6_bgp_network_cmd,
+           "[no] network X:X::X:X/M$prefix \
+           [{route-map WORD$map_name|label-index (0-1048560)$label_index}]",
+           NO_STR
+           "Specify a network to announce via BGP\n"
+           "IPv6 prefix\n"
+           "Route-map to modify the attributes\n"
+           "Name of the route map\n"
+           "Label index to associate with the prefix\n"
+           "Label index value\n")
 {
-       return bgp_static_set(
-               vty, no, prefix_str, AFI_IP6, bgp_node_safi(vty), map_name, 0,
-               label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       if (no) {
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       } else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+               if (map_name)
+                       nb_cli_enqueue_change(vty, "./rmap-policy-export",
+                                             NB_OP_MODIFY, map_name);
+               else
+                       nb_cli_enqueue_change(vty, "./rmap-policy-export",
+                                             NB_OP_DESTROY, NULL);
+
+               if (label_index_str)
+                       nb_cli_enqueue_change(vty, "./label-index",
+                                             NB_OP_MODIFY, label_index_str);
+       }
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/network-config[prefix='%s']",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi), prefix_str);
+
+       return nb_cli_apply_changes(vty, base_xpath);
+}
+
+void cli_show_bgp_global_afi_safi_network_config(struct vty *vty,
+                                                struct lyd_node *dnode,
+                                                bool show_defaults)
+{
+       vty_out(vty, "  network %s", yang_dnode_get_string(dnode, "./prefix"));
+
+       if (yang_dnode_exists(dnode, "./label-index"))
+               vty_out(vty, " label-index %s",
+                       yang_dnode_get_string(dnode, "./label-index"));
+
+       if (yang_dnode_exists(dnode, "./rmap-policy-export"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./rmap-policy-export"));
+
+       if (yang_dnode_get_bool(dnode, "./backdoor"))
+               vty_out(vty, " backdoor");
+
+       vty_out(vty, "\n");
 }
 
 static struct bgp_aggregate *bgp_aggregate_new(void)
@@ -6180,11 +6328,119 @@ static struct bgp_aggregate *bgp_aggregate_new(void)
 
 static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
 {
+       XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
+       route_map_counter_decrement(aggregate->suppress_map);
        XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->rmap.name);
        route_map_counter_decrement(aggregate->rmap.map);
        XFREE(MTYPE_BGP_AGGREGATE, aggregate);
 }
 
+/**
+ * Helper function to avoid repeated code: prepare variables for a
+ * `route_map_apply` call.
+ *
+ * \returns `true` on route map match, otherwise `false`.
+ */
+static bool aggr_suppress_map_test(struct bgp *bgp,
+                                  struct bgp_aggregate *aggregate,
+                                  struct bgp_path_info *pi)
+{
+       const struct prefix *p = bgp_dest_get_prefix(pi->net);
+       route_map_result_t rmr = RMAP_DENYMATCH;
+       struct bgp_path_info rmap_path = {};
+       struct attr attr = {};
+
+       /* No route map entries created, just don't match. */
+       if (aggregate->suppress_map == NULL)
+               return false;
+
+       /* Call route map matching and return result. */
+       attr.aspath = aspath_empty();
+       rmap_path.peer = bgp->peer_self;
+       rmap_path.attr = &attr;
+
+       SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
+       rmr = route_map_apply(aggregate->suppress_map, p, RMAP_BGP, &rmap_path);
+       bgp->peer_self->rmap_type = 0;
+
+       bgp_attr_flush(&attr);
+
+       return rmr == RMAP_PERMITMATCH;
+}
+
+/** Test whether the aggregation has suppressed this path or not. */
+static bool aggr_suppress_exists(struct bgp_aggregate *aggregate,
+                                struct bgp_path_info *pi)
+{
+       if (pi->extra == NULL || pi->extra->aggr_suppressors == NULL)
+               return false;
+
+       return listnode_lookup(pi->extra->aggr_suppressors, aggregate) != NULL;
+}
+
+/**
+ * Suppress this path and keep the reference.
+ *
+ * \returns `true` if needs processing otherwise `false`.
+ */
+static bool aggr_suppress_path(struct bgp_aggregate *aggregate,
+                              struct bgp_path_info *pi)
+{
+       struct bgp_path_info_extra *pie;
+
+       /* Path is already suppressed by this aggregation. */
+       if (aggr_suppress_exists(aggregate, pi))
+               return false;
+
+       pie = bgp_path_info_extra_get(pi);
+
+       /* This is the first suppression, allocate memory and list it. */
+       if (pie->aggr_suppressors == NULL)
+               pie->aggr_suppressors = list_new();
+
+       listnode_add(pie->aggr_suppressors, aggregate);
+
+       /* Only mark for processing if suppressed. */
+       if (listcount(pie->aggr_suppressors) == 1) {
+               if (BGP_DEBUG(update, UPDATE_OUT))
+                       zlog_debug("aggregate-address suppressing: %pFX",
+                                  bgp_dest_get_prefix(pi->net));
+
+               bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
+               return true;
+       }
+
+       return false;
+}
+
+/**
+ * Unsuppress this path and remove the reference.
+ *
+ * \returns `true` if needs processing otherwise `false`.
+ */
+static bool aggr_unsuppress_path(struct bgp_aggregate *aggregate,
+                                struct bgp_path_info *pi)
+{
+       /* Path wasn't suppressed. */
+       if (!aggr_suppress_exists(aggregate, pi))
+               return false;
+
+       listnode_delete(pi->extra->aggr_suppressors, aggregate);
+
+       /* Unsuppress and free extra memory if last item. */
+       if (listcount(pi->extra->aggr_suppressors) == 0) {
+               if (BGP_DEBUG(update, UPDATE_OUT))
+                       zlog_debug("aggregate-address unsuppressing: %pFX",
+                                  bgp_dest_get_prefix(pi->net));
+
+               list_delete(&pi->extra->aggr_suppressors);
+               bgp_path_info_set_flag(pi->net, pi, BGP_PATH_ATTR_CHANGED);
+               return true;
+       }
+
+       return false;
+}
+
 static bool bgp_aggregate_info_same(struct bgp_path_info *pi, uint8_t origin,
                                    struct aspath *aspath,
                                    struct community *comm,
@@ -6240,6 +6496,13 @@ static void bgp_aggregate_install(
                    && pi->sub_type == BGP_ROUTE_AGGREGATE)
                        break;
 
+       /*
+        * If we have paths with different MEDs, then don't install
+        * (or uninstall) the aggregate route.
+        */
+       if (aggregate->match_med && aggregate->med_mismatched)
+               goto uninstall_aggregate_route;
+
        if (aggregate->count > 0) {
                /*
                 * If the aggregate information has not changed
@@ -6284,6 +6547,7 @@ static void bgp_aggregate_install(
                bgp_path_info_add(dest, new);
                bgp_process(bgp, dest, afi, safi);
        } else {
+       uninstall_aggregate_route:
                for (pi = orig; pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self
                            && pi->type == ZEBRA_ROUTE_BGP
@@ -6300,6 +6564,172 @@ static void bgp_aggregate_install(
        bgp_dest_unlock_node(dest);
 }
 
+/**
+ * Check if the current path has different MED than other known paths.
+ *
+ * \returns `true` if the MED matched the others else `false`.
+ */
+static bool bgp_aggregate_med_match(struct bgp_aggregate *aggregate,
+                                   struct bgp *bgp, struct bgp_path_info *pi)
+{
+       uint32_t cur_med = bgp_med_value(pi->attr, bgp);
+
+       /* This is the first route being analyzed. */
+       if (!aggregate->med_initialized) {
+               aggregate->med_initialized = true;
+               aggregate->med_mismatched = false;
+               aggregate->med_matched_value = cur_med;
+       } else {
+               /* Check if routes with different MED showed up. */
+               if (cur_med != aggregate->med_matched_value)
+                       aggregate->med_mismatched = true;
+       }
+
+       return !aggregate->med_mismatched;
+}
+
+/**
+ * Initializes and tests all routes in the aggregate address path for MED
+ * values.
+ *
+ * \returns `true` if all MEDs are the same otherwise `false`.
+ */
+static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
+                                      struct bgp *bgp, const struct prefix *p,
+                                      afi_t afi, safi_t safi)
+{
+       struct bgp_table *table = bgp->rib[afi][safi];
+       const struct prefix *dest_p;
+       struct bgp_dest *dest, *top;
+       struct bgp_path_info *pi;
+       bool med_matched = true;
+
+       aggregate->med_initialized = false;
+
+       top = bgp_node_get(table, p);
+       for (dest = bgp_node_get(table, p); dest;
+            dest = bgp_route_next_until(dest, top)) {
+               dest_p = bgp_dest_get_prefix(dest);
+               if (dest_p->prefixlen <= p->prefixlen)
+                       continue;
+
+               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+                       if (BGP_PATH_HOLDDOWN(pi))
+                               continue;
+                       if (pi->sub_type == BGP_ROUTE_AGGREGATE)
+                               continue;
+                       if (!bgp_aggregate_med_match(aggregate, bgp, pi)) {
+                               med_matched = false;
+                               break;
+                       }
+               }
+               if (!med_matched)
+                       break;
+       }
+       bgp_dest_unlock_node(top);
+
+       return med_matched;
+}
+
+/**
+ * Toggles the route suppression status for this aggregate address
+ * configuration.
+ */
+void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
+                                    struct bgp *bgp, const struct prefix *p,
+                                    afi_t afi, safi_t safi, bool suppress)
+{
+       struct bgp_table *table = bgp->rib[afi][safi];
+       const struct prefix *dest_p;
+       struct bgp_dest *dest, *top;
+       struct bgp_path_info *pi;
+       bool toggle_suppression;
+
+       /* We've found a different MED we must revert any suppressed routes. */
+       top = bgp_node_get(table, p);
+       for (dest = bgp_node_get(table, p); dest;
+            dest = bgp_route_next_until(dest, top)) {
+               dest_p = bgp_dest_get_prefix(dest);
+               if (dest_p->prefixlen <= p->prefixlen)
+                       continue;
+
+               toggle_suppression = false;
+               for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
+                       if (BGP_PATH_HOLDDOWN(pi))
+                               continue;
+                       if (pi->sub_type == BGP_ROUTE_AGGREGATE)
+                               continue;
+
+                       /* We are toggling suppression back. */
+                       if (suppress) {
+                               /* Suppress route if not suppressed already. */
+                               if (aggr_suppress_path(aggregate, pi))
+                                       toggle_suppression = true;
+                               continue;
+                       }
+
+                       /* Install route if there is no more suppression. */
+                       if (aggr_unsuppress_path(aggregate, pi))
+                               toggle_suppression = true;
+               }
+
+               if (toggle_suppression)
+                       bgp_process(bgp, dest, afi, safi);
+       }
+       bgp_dest_unlock_node(top);
+}
+
+/**
+ * Aggregate address MED matching incremental test: this function is called
+ * when the initial aggregation occurred and we are only testing a single
+ * new path.
+ *
+ * In addition to testing and setting the MED validity it also installs back
+ * suppressed routes (if summary is configured).
+ *
+ * Must not be called in `bgp_aggregate_route`.
+ */
+static void bgp_aggregate_med_update(struct bgp_aggregate *aggregate,
+                                    struct bgp *bgp, const struct prefix *p,
+                                    afi_t afi, safi_t safi,
+                                    struct bgp_path_info *pi, bool is_adding)
+{
+       /* MED matching disabled. */
+       if (!aggregate->match_med)
+               return;
+
+       /* Aggregation with different MED, nothing to do. */
+       if (aggregate->med_mismatched)
+               return;
+
+       /*
+        * Test the current entry:
+        *
+        * is_adding == true: if the new entry doesn't match then we must
+        * install all suppressed routes.
+        *
+        * is_adding == false: if the entry being removed was the last
+        * unmatching entry then we can suppress all routes.
+        */
+       if (!is_adding) {
+               if (bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi)
+                   && aggregate->summary_only)
+                       bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi,
+                                                       safi, true);
+       } else
+               bgp_aggregate_med_match(aggregate, bgp, pi);
+
+       /* No mismatches, just quit. */
+       if (!aggregate->med_mismatched)
+               return;
+
+       /* Route summarization is disabled. */
+       if (!aggregate->summary_only)
+               return;
+
+       bgp_aggregate_toggle_suppressed(aggregate, bgp, p, afi, safi, false);
+}
+
 /* Update an aggregate as routes are added/removed from the BGP table */
 void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
                         safi_t safi, struct bgp_aggregate *aggregate)
@@ -6323,6 +6753,21 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
            || (bgp->peer_self == NULL))
                return;
 
+       /* Initialize and test routes for MED difference. */
+       if (aggregate->match_med)
+               bgp_aggregate_test_all_med(aggregate, bgp, p, afi, safi);
+
+       /*
+        * Reset aggregate count: we might've been called from route map
+        * update so in that case we must retest all more specific routes.
+        *
+        * \see `bgp_route_map_process_update`.
+        */
+       aggregate->count = 0;
+       aggregate->incomplete_origin_count = 0;
+       aggregate->incomplete_origin_count = 0;
+       aggregate->egp_origin_count = 0;
+
        /* ORIGIN attribute: If at least one route among routes that are
           aggregated has ORIGIN with the value INCOMPLETE, then the
           aggregated route must have the ORIGIN attribute with the value
@@ -6359,12 +6804,32 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
                        /*
                         * summary-only aggregate route suppress
                         * aggregated route announcements.
+                        *
+                        * MED matching:
+                        * Don't create summaries if MED didn't match
+                        * otherwise neither the specific routes and the
+                        * aggregation will be announced.
                         */
-                       if (aggregate->summary_only) {
-                               (bgp_path_info_extra_get(pi))->suppress++;
-                               bgp_path_info_set_flag(dest, pi,
-                                                      BGP_PATH_ATTR_CHANGED);
-                               match++;
+                       if (aggregate->summary_only
+                           && AGGREGATE_MED_VALID(aggregate)) {
+                               if (aggr_suppress_path(aggregate, pi))
+                                       match++;
+                       }
+
+                       /*
+                        * Suppress more specific routes that match the route
+                        * map results.
+                        *
+                        * MED matching:
+                        * Don't suppress routes if MED matching is enabled and
+                        * it mismatched otherwise we might end up with no
+                        * routes for this path.
+                        */
+                       if (aggregate->suppress_map_name
+                           && AGGREGATE_MED_VALID(aggregate)
+                           && aggr_suppress_map_test(bgp, aggregate, pi)) {
+                               if (aggr_suppress_path(aggregate, pi))
+                                       match++;
                        }
 
                        aggregate->count++;
@@ -6502,16 +6967,19 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
                        if (pi->sub_type == BGP_ROUTE_AGGREGATE)
                                continue;
 
-                       if (aggregate->summary_only && pi->extra) {
-                               pi->extra->suppress--;
+                       if (aggregate->summary_only && pi->extra
+                           && AGGREGATE_MED_VALID(aggregate)) {
+                               if (aggr_unsuppress_path(aggregate, pi))
+                                       match++;
+                       }
 
-                               if (pi->extra->suppress == 0) {
-                                       bgp_path_info_set_flag(
-                                               dest, pi,
-                                               BGP_PATH_ATTR_CHANGED);
+                       if (aggregate->suppress_map_name
+                           && AGGREGATE_MED_VALID(aggregate)
+                           && aggr_suppress_map_test(bgp, aggregate, pi)) {
+                               if (aggr_unsuppress_path(aggregate, pi))
                                        match++;
-                               }
                        }
+
                        aggregate->count--;
 
                        if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
@@ -6593,8 +7061,20 @@ static void bgp_add_route_to_aggregate(struct bgp *bgp,
 
        aggregate->count++;
 
-       if (aggregate->summary_only)
-               (bgp_path_info_extra_get(pinew))->suppress++;
+       /*
+        * This must be called before `summary` check to avoid
+        * "suppressing" twice.
+        */
+       if (aggregate->match_med)
+               bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi,
+                                        pinew, true);
+
+       if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
+               aggr_suppress_path(aggregate, pinew);
+
+       if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
+           && aggr_suppress_map_test(bgp, aggregate, pinew))
+               aggr_suppress_path(aggregate, pinew);
 
        switch (pinew->attr->origin) {
        case BGP_ORIGIN_INCOMPLETE:
@@ -6690,17 +7170,22 @@ static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
        if (pi->sub_type == BGP_ROUTE_AGGREGATE)
                return;
 
-       if (aggregate->summary_only
-               && pi->extra
-               && pi->extra->suppress > 0) {
-               pi->extra->suppress--;
+       if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
+               if (aggr_unsuppress_path(aggregate, pi))
+                       match++;
 
-               if (pi->extra->suppress == 0) {
-                       bgp_path_info_set_flag(pi->net, pi,
-                                              BGP_PATH_ATTR_CHANGED);
+       if (aggregate->suppress_map_name && AGGREGATE_MED_VALID(aggregate)
+           && aggr_suppress_map_test(bgp, aggregate, pi))
+               if (aggr_unsuppress_path(aggregate, pi))
                        match++;
-               }
-       }
+
+       /*
+        * This must be called after `summary`, `suppress-map` check to avoid
+        * "unsuppressing" twice.
+        */
+       if (aggregate->match_med)
+               bgp_aggregate_med_update(aggregate, bgp, aggr_p, afi, safi, pi,
+                                        true);
 
        if (aggregate->count > 0)
                aggregate->count--;
@@ -6863,35 +7348,25 @@ static const char *bgp_origin2str(uint8_t origin)
        return "n/a";
 }
 
-static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
-                              afi_t afi, safi_t safi)
+int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix, afi_t afi,
+                       safi_t safi, char *errmsg, size_t errmsg_len)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int ret;
-       struct prefix p;
        struct bgp_dest *dest;
        struct bgp_aggregate *aggregate;
 
-       /* Convert string to prefix structure. */
-       ret = str2prefix(prefix_str, &p);
-       if (!ret) {
-               vty_out(vty, "Malformed prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       apply_mask(&p);
-
+       apply_mask(prefix);
        /* Old configuration check. */
-       dest = bgp_node_lookup(bgp->aggregate[afi][safi], &p);
+       dest = bgp_node_lookup(bgp->aggregate[afi][safi], prefix);
        if (!dest) {
-               vty_out(vty,
-                       "%% There is no aggregate-address configuration.\n");
-               return CMD_WARNING_CONFIG_FAILED;
+               snprintf(errmsg, errmsg_len,
+                        "There is no aggregate-address configuration.\n");
+               return -1;
        }
 
        aggregate = bgp_dest_get_bgp_aggregate_info(dest);
-       bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
-       bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL,
-                             NULL, NULL,  0, aggregate);
+       bgp_aggregate_delete(bgp, prefix, afi, safi, aggregate);
+       bgp_aggregate_install(bgp, afi, safi, prefix, 0, NULL, NULL, NULL, NULL,
+                             0, aggregate);
 
        /* Unlock aggregate address configuration. */
        bgp_dest_set_bgp_aggregate_info(dest, NULL);
@@ -6952,54 +7427,60 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
        bgp_dest_unlock_node(dest);
        bgp_dest_unlock_node(dest);
 
-       return CMD_SUCCESS;
+       return 0;
 }
 
-static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
-                            safi_t safi, const char *rmap,
-                            uint8_t summary_only, uint8_t as_set,
-                            uint8_t origin)
+int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
+                     safi_t safi, const char *rmap, uint8_t summary_only,
+                     uint8_t as_set, uint8_t origin, bool match_med,
+                     const char *suppress_map,
+                     char *errmsg, size_t errmsg_len)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int ret;
-       struct prefix p;
        struct bgp_dest *dest;
        struct bgp_aggregate *aggregate;
        uint8_t as_set_new = as_set;
+       char buf[PREFIX2STR_BUFFER];
 
-       /* Convert string to prefix structure. */
-       ret = str2prefix(prefix_str, &p);
-       if (!ret) {
-               vty_out(vty, "Malformed prefix\n");
-               return CMD_WARNING_CONFIG_FAILED;
+       if (suppress_map && summary_only) {
+               snprintf(errmsg, errmsg_len,
+                       "'summary-only' and 'suppress-map' can't be used at the same time\n");
+               return -1;
        }
-       apply_mask(&p);
 
-       if ((afi == AFI_IP && p.prefixlen == IPV4_MAX_BITLEN) ||
-           (afi == AFI_IP6 && p.prefixlen == IPV6_MAX_BITLEN)) {
-               vty_out(vty, "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
-                       prefix_str);
-               return CMD_WARNING_CONFIG_FAILED;
+       apply_mask(prefix);
+
+       if ((afi == AFI_IP && prefix->prefixlen == IPV4_MAX_BITLEN)
+           || (afi == AFI_IP6 && prefix->prefixlen == IPV6_MAX_BITLEN)) {
+               snprintf(
+                       errmsg, errmsg_len,
+                       "Specified prefix: %s will not result in any useful aggregation, disallowing\n",
+                       prefix2str(prefix, buf, PREFIX_STRLEN));
+               return -1;
        }
 
        /* Old configuration check. */
-       dest = bgp_node_get(bgp->aggregate[afi][safi], &p);
+       dest = bgp_node_get(bgp->aggregate[afi][safi], prefix);
        aggregate = bgp_dest_get_bgp_aggregate_info(dest);
 
        if (aggregate) {
-               vty_out(vty, "There is already same aggregate network.\n");
+               snprintf(errmsg, errmsg_len,
+                        "There is already same aggregate network.\n");
                /* try to remove the old entry */
-               ret = bgp_aggregate_unset(vty, prefix_str, afi, safi);
+               ret = bgp_aggregate_unset(bgp, prefix, afi, safi, errmsg,
+                                         errmsg_len);
                if (ret) {
-                       vty_out(vty, "Error deleting aggregate.\n");
+                       snprintf(errmsg, errmsg_len,
+                                "Error deleting aggregate.\n");
                        bgp_dest_unlock_node(dest);
-                       return CMD_WARNING_CONFIG_FAILED;
+                       return -1;
                }
        }
 
        /* Make aggregate address structure. */
        aggregate = bgp_aggregate_new();
        aggregate->summary_only = summary_only;
+       aggregate->match_med = match_med;
 
        /* Network operators MUST NOT locally generate any new
         * announcements containing AS_SET or AS_CONFED_SET. If they have
@@ -7015,7 +7496,8 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
                        zlog_warn(
                                "%s: Ignoring as-set because `bgp reject-as-sets` is enabled.",
                                __func__);
-                       vty_out(vty,
+                       snprintf(
+                               errmsg, errmsg_len,
                                "Ignoring as-set because `bgp reject-as-sets` is enabled.\n");
                }
        }
@@ -7037,244 +7519,215 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
                aggregate->rmap.map = route_map_lookup_by_name(rmap);
                route_map_counter_increment(aggregate->rmap.map);
        }
+
+       if (suppress_map) {
+               XFREE(MTYPE_ROUTE_MAP_NAME, aggregate->suppress_map_name);
+               route_map_counter_decrement(aggregate->suppress_map);
+
+               aggregate->suppress_map_name =
+                       XSTRDUP(MTYPE_ROUTE_MAP_NAME, suppress_map);
+               aggregate->suppress_map =
+                       route_map_lookup_by_name(aggregate->suppress_map_name);
+               route_map_counter_increment(aggregate->suppress_map);
+       }
+
        bgp_dest_set_bgp_aggregate_info(dest, aggregate);
 
        /* Aggregate address insert into BGP routing table. */
-       bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
+       bgp_aggregate_route(bgp, prefix, afi, safi, aggregate);
 
-       return CMD_SUCCESS;
+       return 0;
 }
 
-DEFUN (aggregate_address,
-       aggregate_address_cmd,
-       "aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
-       "Configure BGP aggregate entries\n"
-       "Aggregate prefix\n"
-       "Generate AS set path information\n"
-       "Filter more specific routes from updates\n"
-       "Filter more specific routes from updates\n"
-       "Generate AS set path information\n"
-       "Apply route map to aggregate network\n"
-       "Name of route map\n"
-       "BGP origin code\n"
-       "Remote EGP\n"
-       "Local IGP\n"
-       "Unknown heritage\n")
-{
-       int idx = 0;
-       argv_find(argv, argc, "A.B.C.D/M", &idx);
-       char *prefix = argv[idx]->arg;
-       char *rmap = NULL;
-       uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
-       int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
-                                                          : AGGREGATE_AS_UNSET;
-       idx = 0;
-       int summary_only = argv_find(argv, argc, "summary-only", &idx)
-                                  ? AGGREGATE_SUMMARY_ONLY
-                                  : 0;
-
-       idx = 0;
-       argv_find(argv, argc, "WORD", &idx);
-       if (idx)
-               rmap = argv[idx]->arg;
-
-       idx = 0;
-       if (argv_find(argv, argc, "origin", &idx)) {
-               if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
-                       origin = BGP_ORIGIN_IGP;
-               if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
-                       origin = BGP_ORIGIN_EGP;
-               if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
-                       origin = BGP_ORIGIN_INCOMPLETE;
-       }
-
-       return bgp_aggregate_set(vty, prefix, AFI_IP, bgp_node_safi(vty), rmap,
-                                summary_only, as_set, origin);
-}
-
-DEFUN (aggregate_address_mask,
-       aggregate_address_mask_cmd,
-       "aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
-       "Configure BGP aggregate entries\n"
-       "Aggregate address\n"
-       "Aggregate mask\n"
-       "Generate AS set path information\n"
-       "Filter more specific routes from updates\n"
-       "Filter more specific routes from updates\n"
-       "Generate AS set path information\n"
-       "Apply route map to aggregate network\n"
-       "Name of route map\n"
-       "BGP origin code\n"
-       "Remote EGP\n"
-       "Local IGP\n"
-       "Unknown heritage\n")
-{
-       int idx = 0;
-       argv_find(argv, argc, "A.B.C.D", &idx);
-       char *prefix = argv[idx]->arg;
-       char *mask = argv[idx + 1]->arg;
-       bool rmap_found;
-       char *rmap = NULL;
-       uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
-       int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
-                                                          : AGGREGATE_AS_UNSET;
-       idx = 0;
-       int summary_only = argv_find(argv, argc, "summary-only", &idx)
-                                  ? AGGREGATE_SUMMARY_ONLY
-                                  : 0;
-
-       rmap_found = argv_find(argv, argc, "WORD", &idx);
-       if (rmap_found)
-               rmap = argv[idx]->arg;
+DEFPY_YANG(
+       aggregate_addressv4, aggregate_addressv4_cmd,
+       "[no] aggregate-address <A.B.C.D/M$prefix|A.B.C.D$addr A.B.C.D$mask> {"
+       "as-set$as_set_s"
+       "|summary-only$summary_only"
+       "|route-map WORD$rmap_name"
+       "|origin <egp|igp|incomplete>$origin_s"
+       "|matching-MED-only$match_med"
+       "|suppress-map WORD$suppress_map"
+       "}",
+       NO_STR
+       "Configure BGP aggregate entries\n"
+       "Aggregate prefix\n"
+       "Aggregate address\n"
+       "Aggregate mask\n"
+       "Generate AS set path information\n"
+       "Filter more specific routes from updates\n"
+       "Apply route map to aggregate network\n"
+       "Route map name\n"
+       "BGP origin code\n"
+       "Remote EGP\n"
+       "Local IGP\n"
+       "Unknown heritage\n"
+       "Only aggregate routes with matching MED\n"
+       "Suppress the selected more specific routes\n"
+       "Route map with the route selectors\n")
+{
+       char base_xpath[XPATH_MAXLEN];
+       safi_t safi = bgp_node_safi(vty);
+       char prefix_buf[PREFIX2STR_BUFFER];
+
+       if (addr_str) {
+               if (netmask_str2prefix_str(addr_str, mask_str, prefix_buf)
+                   == 0) {
+                       vty_out(vty, "%% Inconsistent address and mask\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
+       } else {
+               strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
+       }
 
-       char prefix_str[BUFSIZ];
-       int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
+       if (!no && origin_s)
+               nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
 
-       if (!ret) {
-               vty_out(vty, "%% Inconsistent address and mask\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       if (!no && as_set_s)
+               nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
+       else
+               nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
 
-       idx = 0;
-       if (argv_find(argv, argc, "origin", &idx)) {
-               if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
-                       origin = BGP_ORIGIN_IGP;
-               if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
-                       origin = BGP_ORIGIN_EGP;
-               if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
-                       origin = BGP_ORIGIN_INCOMPLETE;
-       }
+       if (!no && summary_only)
+               nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+                                     "true");
+       else
+               nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+                                     "false");
 
-       return bgp_aggregate_set(vty, prefix_str, AFI_IP, bgp_node_safi(vty),
-                                rmap, summary_only, as_set, origin);
-}
+       if (!no && match_med)
+               nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
+       else
+               nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
+                                     "false");
 
-DEFUN (no_aggregate_address,
-       no_aggregate_address_cmd,
-       "no aggregate-address A.B.C.D/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
-       NO_STR
-       "Configure BGP aggregate entries\n"
-       "Aggregate prefix\n"
-       "Generate AS set path information\n"
-       "Filter more specific routes from updates\n"
-       "Filter more specific routes from updates\n"
-       "Generate AS set path information\n"
-       "Apply route map to aggregate network\n"
-       "Name of route map\n"
-       "BGP origin code\n"
-       "Remote EGP\n"
-       "Local IGP\n"
-       "Unknown heritage\n")
-{
-       int idx = 0;
-       argv_find(argv, argc, "A.B.C.D/M", &idx);
-       char *prefix = argv[idx]->arg;
-       return bgp_aggregate_unset(vty, prefix, AFI_IP, bgp_node_safi(vty));
-}
+       if (rmap_name)
+               nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
+                                     rmap_name);
+       else
+               nb_cli_enqueue_change(vty, "./rmap-policy-export",
+                                     NB_OP_DESTROY, NULL);
 
-DEFUN (no_aggregate_address_mask,
-       no_aggregate_address_mask_cmd,
-       "no aggregate-address A.B.C.D A.B.C.D [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
-       NO_STR
-       "Configure BGP aggregate entries\n"
-       "Aggregate address\n"
-       "Aggregate mask\n"
-       "Generate AS set path information\n"
-       "Filter more specific routes from updates\n"
-       "Filter more specific routes from updates\n"
-       "Generate AS set path information\n"
-       "Apply route map to aggregate network\n"
-       "Name of route map\n"
-       "BGP origin code\n"
-       "Remote EGP\n"
-       "Local IGP\n"
-       "Unknown heritage\n")
-{
-       int idx = 0;
-       argv_find(argv, argc, "A.B.C.D", &idx);
-       char *prefix = argv[idx]->arg;
-       char *mask = argv[idx + 1]->arg;
+       if (suppress_map)
+               nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
+                                     suppress_map);
+       else
+               nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
+                                     NULL);
 
-       char prefix_str[BUFSIZ];
-       int ret = netmask_str2prefix_str(prefix, mask, prefix_str);
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
+               yang_afi_safi_value2identity(AFI_IP, safi),
+               bgp_afi_safi_get_container_str(AFI_IP, safi), prefix_buf);
 
-       if (!ret) {
-               vty_out(vty, "%% Inconsistent address and mask\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       if (no)
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
+}
+
+DEFPY_YANG(aggregate_addressv6, aggregate_addressv6_cmd,
+          "[no] aggregate-address X:X::X:X/M$prefix {"
+          "as-set$as_set_s"
+          "|summary-only$summary_only"
+          "|route-map WORD$rmap_name"
+          "|origin <egp|igp|incomplete>$origin_s"
+          "|matching-MED-only$match_med"
+          "|suppress-map WORD$suppress_map"
+          "}",
+          NO_STR
+          "Configure BGP aggregate entries\n"
+          "Aggregate prefix\n"
+          "Generate AS set path information\n"
+          "Filter more specific routes from updates\n"
+          "Apply route map to aggregate network\n"
+          "Route map name\n"
+          "BGP origin code\n"
+          "Remote EGP\n"
+          "Local IGP\n"
+          "Unknown heritage\n"
+          "Only aggregate routes with matching MED\n"
+          "Suppress the selected more specific routes\n"
+          "Route map with the route selectors\n")
+{
+       char base_xpath[XPATH_MAXLEN];
+       safi_t safi = bgp_node_safi(vty);
+
+       if (!no && origin_s)
+               nb_cli_enqueue_change(vty, "./origin", NB_OP_MODIFY, origin_s);
+
+       if (!no && as_set_s)
+               nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "true");
+       else
+               nb_cli_enqueue_change(vty, "./as-set", NB_OP_MODIFY, "false");
+
+       if (!no && summary_only)
+               nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+                                     "true");
+       else
+               nb_cli_enqueue_change(vty, "./summary-only", NB_OP_MODIFY,
+                                     "false");
+
+       if (!no && match_med)
+               nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY, "true");
+       else
+               nb_cli_enqueue_change(vty, "./match-med", NB_OP_MODIFY,
+                                     "false");
+
+       if (rmap_name)
+               nb_cli_enqueue_change(vty, "./rmap-policy-export", NB_OP_MODIFY,
+                                     rmap_name);
+
+       if (suppress_map)
+               nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_MODIFY,
+                                     suppress_map);
+       else
+               nb_cli_enqueue_change(vty, "./suppress-map", NB_OP_DESTROY,
+                                     NULL);
 
-       return bgp_aggregate_unset(vty, prefix_str, AFI_IP, bgp_node_safi(vty));
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/aggregate-route[prefix='%s']",
+               yang_afi_safi_value2identity(AFI_IP6, safi),
+               bgp_afi_safi_get_container_str(AFI_IP6, safi), prefix_str);
+
+       if (no)
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFUN (ipv6_aggregate_address,
-       ipv6_aggregate_address_cmd,
-       "aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
-       "Configure BGP aggregate entries\n"
-       "Aggregate prefix\n"
-       "Generate AS set path information\n"
-       "Filter more specific routes from updates\n"
-       "Filter more specific routes from updates\n"
-       "Generate AS set path information\n"
-       "Apply route map to aggregate network\n"
-       "Name of route map\n"
-       "BGP origin code\n"
-       "Remote EGP\n"
-       "Local IGP\n"
-       "Unknown heritage\n")
+void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
 {
-       int idx = 0;
-       argv_find(argv, argc, "X:X::X:X/M", &idx);
-       char *prefix = argv[idx]->arg;
-       char *rmap = NULL;
-       bool rmap_found;
-       uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
-       int as_set = argv_find(argv, argc, "as-set", &idx) ? AGGREGATE_AS_SET
-                                                          : AGGREGATE_AS_UNSET;
-
-       idx = 0;
-       int sum_only = argv_find(argv, argc, "summary-only", &idx)
-                              ? AGGREGATE_SUMMARY_ONLY
-                              : 0;
-
-       rmap_found = argv_find(argv, argc, "WORD", &idx);
-       if (rmap_found)
-               rmap = argv[idx]->arg;
-
-       idx = 0;
-       if (argv_find(argv, argc, "origin", &idx)) {
-               if (strncmp(argv[idx + 1]->arg, "igp", 2) == 0)
-                       origin = BGP_ORIGIN_IGP;
-               if (strncmp(argv[idx + 1]->arg, "egp", 1) == 0)
-                       origin = BGP_ORIGIN_EGP;
-               if (strncmp(argv[idx + 1]->arg, "incomplete", 2) == 0)
-                       origin = BGP_ORIGIN_INCOMPLETE;
-       }
-
-       return bgp_aggregate_set(vty, prefix, AFI_IP6, SAFI_UNICAST, rmap,
-                                sum_only, as_set, origin);
-}
-
-DEFUN (no_ipv6_aggregate_address,
-       no_ipv6_aggregate_address_cmd,
-       "no aggregate-address X:X::X:X/M [<as-set [summary-only]|summary-only [as-set]>] [route-map WORD] [origin <egp|igp|incomplete>]",
-       NO_STR
-       "Configure BGP aggregate entries\n"
-       "Aggregate prefix\n"
-       "Generate AS set path information\n"
-       "Filter more specific routes from updates\n"
-       "Filter more specific routes from updates\n"
-       "Generate AS set path information\n"
-       "Apply route map to aggregate network\n"
-       "Name of route map\n"
-       "BGP origin code\n"
-       "Remote EGP\n"
-       "Local IGP\n"
-       "Unknown heritage\n")
-{
-       int idx = 0;
-       argv_find(argv, argc, "X:X::X:X/M", &idx);
-       char *prefix = argv[idx]->arg;
-       return bgp_aggregate_unset(vty, prefix, AFI_IP6, SAFI_UNICAST);
+       uint8_t origin;
+
+       vty_out(vty, "  aggregate-address %s",
+               yang_dnode_get_string(dnode, "./prefix"));
+
+       if (yang_dnode_get_bool(dnode, "./as-set"))
+               vty_out(vty, " as-set");
+
+       if (yang_dnode_get_bool(dnode, "./summary-only"))
+               vty_out(vty, " summary-only");
+
+       if (yang_dnode_exists(dnode, "./rmap-policy-export"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./rmap-policy-export"));
+
+       origin = yang_dnode_get_enum(dnode, "./origin");
+       if (origin != BGP_ORIGIN_UNSPECIFIED)
+               vty_out(vty, " origin %s", bgp_origin2str(origin));
+
+       if (yang_dnode_get_bool(dnode, "./match-med"))
+               vty_out(vty, " matching-MED-only");
+
+       vty_out(vty, "\n");
 }
 
 /* Redistribute route treatment. */
@@ -7519,10 +7972,7 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty,
 
        if (p->family == AF_INET) {
                if (!json) {
-                       len = vty_out(
-                               vty, "%s/%d",
-                               inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
-                               p->prefixlen);
+                       len = vty_out(vty, "%pFX", p);
                } else {
                        json_object_string_add(json, "prefix",
                                               inet_ntop(p->family,
@@ -7533,14 +7983,10 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty,
                        json_object_string_add(json, "network", buf2);
                }
        } else if (p->family == AF_ETHERNET) {
-               prefix2str(p, buf, PREFIX_STRLEN);
-               len = vty_out(vty, "%s", buf);
+               len = vty_out(vty, "%pFX", p);
        } else if (p->family == AF_EVPN) {
                if (!json)
-                       len = vty_out(
-                               vty, "%s",
-                               bgp_evpn_route2str((struct prefix_evpn *)p, buf,
-                                                  BUFSIZ));
+                       len = vty_out(vty, "%pFX", (struct prefix_evpn *)p);
                else
                        bgp_evpn_route2json((struct prefix_evpn *)p, json);
        } else if (p->family == AF_FLOWSPEC) {
@@ -7550,10 +7996,7 @@ static void route_vty_out_route(const struct prefix *p, struct vty *vty,
                               NLRI_STRING_FORMAT_MIN, json);
        } else {
                if (!json)
-                       len = vty_out(
-                               vty, "%s/%d",
-                               inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ),
-                               p->prefixlen);
+                       len = vty_out(vty, "%pFX", p);
                else {
                        json_object_string_add(json, "prefix",
                                                inet_ntop(p->family,
@@ -7592,7 +8035,7 @@ static void route_vty_short_status_out(struct vty *vty,
                if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
                        json_object_boolean_true_add(json_path, "stale");
 
-               if (path->extra && path->extra->suppress)
+               if (path->extra && bgp_path_suppressed(path))
                        json_object_boolean_true_add(json_path, "suppressed");
 
                if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
@@ -7629,7 +8072,7 @@ static void route_vty_short_status_out(struct vty *vty,
                vty_out(vty, "R");
        else if (CHECK_FLAG(path->flags, BGP_PATH_STALE))
                vty_out(vty, "S");
-       else if (path->extra && path->extra->suppress)
+       else if (bgp_path_suppressed(path))
                vty_out(vty, "s");
        else if (CHECK_FLAG(path->flags, BGP_PATH_VALID)
                 && !CHECK_FLAG(path->flags, BGP_PATH_HISTORY))
@@ -7799,10 +8242,14 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                }
        } else if (safi == SAFI_EVPN) {
                if (json_paths) {
+                       char buf[BUFSIZ] = {0};
+
                        json_nexthop_global = json_object_new_object();
 
                        json_object_string_add(json_nexthop_global, "ip",
-                                              inet_ntoa(attr->nexthop));
+                                              inet_ntop(AF_INET,
+                                                        &attr->nexthop, buf,
+                                                        sizeof(buf)));
 
                        if (path->peer->hostname)
                                json_object_string_add(json_nexthop_global,
@@ -7830,13 +8277,16 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
        } else if (safi == SAFI_FLOWSPEC) {
                if (attr->nexthop.s_addr != INADDR_ANY) {
                        if (json_paths) {
+                               char buf[BUFSIZ] = {0};
+
                                json_nexthop_global = json_object_new_object();
 
                                json_object_string_add(json_nexthop_global,
                                                       "afi", "ipv4");
                                json_object_string_add(
                                        json_nexthop_global, "ip",
-                                       inet_ntoa(attr->nexthop));
+                                       inet_ntop(AF_INET, &attr->nexthop, buf,
+                                                 sizeof(buf)));
 
                                if (path->peer->hostname)
                                        json_object_string_add(
@@ -7866,10 +8316,14 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
                }
        } else if (p->family == AF_INET && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
                if (json_paths) {
+                       char buf[BUFSIZ] = {0};
+
                        json_nexthop_global = json_object_new_object();
 
                        json_object_string_add(json_nexthop_global, "ip",
-                                              inet_ntoa(attr->nexthop));
+                                              inet_ntop(AF_INET,
+                                                        &attr->nexthop, buf,
+                                                        sizeof(buf)));
 
                        if (path->peer->hostname)
                                json_object_string_add(json_nexthop_global,
@@ -8177,18 +8631,24 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
        /* Print attribute */
        if (attr) {
                if (use_json) {
+                       char buf[BUFSIZ] = {0};
+
                        if (p->family == AF_INET
                            && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                                || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
                                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
                                        json_object_string_add(
                                                json_net, "nextHop",
-                                               inet_ntoa(
-                                                       attr->mp_nexthop_global_in));
+                                               inet_ntop(
+                                                       AF_INET,
+                                                       &attr->mp_nexthop_global_in,
+                                                       buf, sizeof(buf)));
                                else
                                        json_object_string_add(
                                                json_net, "nextHop",
-                                               inet_ntoa(attr->nexthop));
+                                               inet_ntop(AF_INET,
+                                                         &attr->nexthop, buf,
+                                                         sizeof(buf)));
                        } else if (p->family == AF_INET6
                                   || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
                                char buf[BUFSIZ];
@@ -8198,11 +8658,16 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
                                        inet_ntop(AF_INET6,
                                                  &attr->mp_nexthop_global, buf,
                                                  BUFSIZ));
-                       } else if (p->family == AF_EVPN &&
-                                  !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
-                               json_object_string_add(json_net,
-                                       "nextHop", inet_ntoa(
-                                       attr->mp_nexthop_global_in));
+                       } else if (p->family == AF_EVPN
+                                  && !BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
+                               char buf[BUFSIZ] = {0};
+
+                               json_object_string_add(
+                                       json_net, "nextHop",
+                                       inet_ntop(AF_INET,
+                                                 &attr->mp_nexthop_global_in,
+                                                 buf, sizeof(buf)));
+                       }
 
                        if (attr->flag
                            & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC))
@@ -8230,15 +8695,12 @@ void route_vty_out_tmp(struct vty *vty, const struct prefix *p,
                                || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
                                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                                    || safi == SAFI_EVPN)
-                                       vty_out(vty, "%-16s",
-                                               inet_ntoa(
-                                                       attr->mp_nexthop_global_in));
+                                       vty_out(vty, "%-16pI4",
+                                               &attr->mp_nexthop_global_in);
                                else if (wide)
-                                       vty_out(vty, "%-41s",
-                                               inet_ntoa(attr->nexthop));
+                                       vty_out(vty, "%-41pI4", &attr->nexthop);
                                else
-                                       vty_out(vty, "%-16s",
-                                               inet_ntoa(attr->nexthop));
+                                       vty_out(vty, "%-16pI4", &attr->nexthop);
                        } else if (p->family == AF_INET6
                                   || BGP_ATTR_NEXTHOP_AFI_IP6(attr)) {
                                char buf[BUFSIZ];
@@ -8323,22 +8785,27 @@ void route_vty_out_tag(struct vty *vty, const struct prefix *p,
             && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
            || (safi == SAFI_EVPN && !BGP_ATTR_NEXTHOP_AFI_IP6(attr))
            || (!BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+               char buf[BUFSIZ] = {0};
+
                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                    || safi == SAFI_EVPN) {
                        if (json)
                                json_object_string_add(
                                        json_out, "mpNexthopGlobalIn",
-                                       inet_ntoa(attr->mp_nexthop_global_in));
+                                       inet_ntop(AF_INET,
+                                                 &attr->mp_nexthop_global_in,
+                                                 buf, sizeof(buf)));
                        else
-                               vty_out(vty, "%-16s",
-                                       inet_ntoa(attr->mp_nexthop_global_in));
+                               vty_out(vty, "%-16pI4",
+                                       &attr->mp_nexthop_global_in);
                } else {
                        if (json)
                                json_object_string_add(
                                        json_out, "nexthop",
-                                       inet_ntoa(attr->nexthop));
+                                       inet_ntop(AF_INET, &attr->nexthop, buf,
+                                                 sizeof(buf)));
                        else
-                               vty_out(vty, "%-16s", inet_ntoa(attr->nexthop));
+                               vty_out(vty, "%-16pI4", &attr->nexthop);
                }
        } else if (((p->family == AF_INET6)
                    && ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)))
@@ -8847,7 +9314,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
 {
        char buf[INET6_ADDRSTRLEN];
        char buf1[BUFSIZ];
-       char buf2[EVPN_ROUTE_STRLEN];
        struct attr *attr = path->attr;
        int sockunion_vty_out(struct vty *, union sockunion *);
        time_t tbuf;
@@ -8885,7 +9351,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
        if (path->extra) {
                char tag_buf[30];
 
-               buf2[0] = '\0';
                tag_buf[0] = '\0';
                if (path->extra && path->extra->num_labels) {
                        bgp_evpn_label2str(path->extra->label,
@@ -8894,11 +9359,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                }
                if (safi == SAFI_EVPN) {
                        if (!json_paths) {
-                               bgp_evpn_route2str(
+                               vty_out(vty, "  Route %pFX",
                                        (struct prefix_evpn *)
-                                               bgp_dest_get_prefix(bn),
-                                       buf2, sizeof(buf2));
-                               vty_out(vty, "  Route %s", buf2);
+                                               bgp_dest_get_prefix(bn));
                                if (tag_buf[0] != '\0')
                                        vty_out(vty, " VNI %s", tag_buf);
                                vty_out(vty, "\n");
@@ -8922,14 +9385,20 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                                                pdest),
                                        buf1, sizeof(buf1));
                                if (is_pi_family_evpn(parent_ri)) {
-                                       bgp_evpn_route2str(
+                                       vty_out(vty,
+                                               "  Imported from %s:%pFX, VNI %s\n",
+                                               buf1,
                                                (struct prefix_evpn *)
                                                        bgp_dest_get_prefix(
                                                                dest),
-                                               buf2, sizeof(buf2));
-                                       vty_out(vty, "  Imported from %s:%s, VNI %s\n", buf1, buf2, tag_buf);
+                                               tag_buf);
                                } else
-                                       vty_out(vty, "  Imported from %s:%s\n", buf1, buf2);
+                                       vty_out(vty,
+                                               "  Imported from %s:%pFX\n",
+                                               buf1,
+                                               (struct prefix_evpn *)
+                                                       bgp_dest_get_prefix(
+                                                               dest));
                        }
                }
        }
@@ -8966,11 +9435,14 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
 
        if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR))) {
                if (json_paths) {
+                       char buf[BUFSIZ] = {0};
+
                        json_object_int_add(json_path, "aggregatorAs",
                                            attr->aggregator_as);
-                       json_object_string_add(
-                               json_path, "aggregatorId",
-                               inet_ntoa(attr->aggregator_addr));
+                       json_object_string_add(json_path, "aggregatorId",
+                                              inet_ntop(AF_INET,
+                                                        &attr->aggregator_addr,
+                                                        buf, sizeof(buf)));
                        if (attr->aggregator_as == BGP_AS_ZERO)
                                json_object_boolean_true_add(
                                        json_path, "aggregatorAsMalformed");
@@ -8980,13 +9452,13 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                } else {
                        if (attr->aggregator_as == BGP_AS_ZERO)
                                vty_out(vty,
-                                       ", (aggregated by %u(malformed) %s)",
+                                       ", (aggregated by %u(malformed) %pI4)",
                                        attr->aggregator_as,
-                                       inet_ntoa(attr->aggregator_addr));
+                                       &attr->aggregator_addr);
                        else
-                               vty_out(vty, ", (aggregated by %u %s)",
+                               vty_out(vty, ", (aggregated by %u %pI4)",
                                        attr->aggregator_as,
-                                       inet_ntoa(attr->aggregator_addr));
+                                       &attr->aggregator_addr);
                }
        }
 
@@ -9033,12 +9505,16 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
             || bn_p->family == AF_EVPN)
            && (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP || safi == SAFI_EVPN
                || !BGP_ATTR_NEXTHOP_AFI_IP6(attr))) {
+               char buf[BUFSIZ] = {0};
+
                if (safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP
                    || safi == SAFI_EVPN) {
                        if (json_paths) {
                                json_object_string_add(
                                        json_nexthop_global, "ip",
-                                       inet_ntoa(attr->mp_nexthop_global_in));
+                                       inet_ntop(AF_INET,
+                                                 &attr->mp_nexthop_global_in,
+                                                 buf, sizeof(buf)));
 
                                if (path->peer->hostname)
                                        json_object_string_add(
@@ -9057,7 +9533,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                        if (json_paths) {
                                json_object_string_add(
                                        json_nexthop_global, "ip",
-                                       inet_ntoa(attr->nexthop));
+                                       inet_ntop(AF_INET, &attr->nexthop, buf,
+                                                 sizeof(buf)));
 
                                if (path->peer->hostname)
                                        json_object_string_add(
@@ -9154,11 +9631,16 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                                vty_out(vty, " from :: ");
                }
 
-               if (json_paths)
+               if (json_paths) {
+                       char buf[BUFSIZ] = {0};
+
                        json_object_string_add(json_peer, "routerId",
-                                              inet_ntoa(bgp->router_id));
-               else
-                       vty_out(vty, "(%s)", inet_ntoa(bgp->router_id));
+                                              inet_ntop(AF_INET,
+                                                        &bgp->router_id, buf,
+                                                        sizeof(buf)));
+               } else {
+                       vty_out(vty, "(%pI4)", &bgp->router_id);
+               }
        }
 
        /* We RXed this path from one of our peers */
@@ -9211,8 +9693,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                        }
 
                        if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
-                               vty_out(vty, " (%s)",
-                                       inet_ntoa(attr->originator_id));
+                               vty_out(vty, " (%pI4)", &attr->originator_id);
                        else
                                vty_out(vty, " (%s)",
                                        inet_ntop(AF_INET,
@@ -9522,14 +10003,17 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
        /* Line 7 display Originator, Cluster-id */
        if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))
            || (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
+               char buf[BUFSIZ] = {0};
+
                if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) {
                        if (json_paths)
                                json_object_string_add(
                                        json_path, "originatorId",
-                                       inet_ntoa(attr->originator_id));
+                                       inet_ntop(AF_INET, &attr->originator_id,
+                                                 buf, sizeof(buf)));
                        else
-                               vty_out(vty, "      Originator: %s",
-                                       inet_ntoa(attr->originator_id));
+                               vty_out(vty, "      Originator: %pI4",
+                                       &attr->originator_id);
                }
 
                if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
@@ -9543,8 +10027,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                                for (i = 0; i < attr->cluster->length / 4;
                                     i++) {
                                        json_string = json_object_new_string(
-                                               inet_ntoa(attr->cluster
-                                                                 ->list[i]));
+                                               inet_ntop(
+                                                       AF_INET,
+                                                       &attr->cluster->list[i],
+                                                       buf, sizeof(buf)));
                                        json_object_array_add(
                                                json_cluster_list_list,
                                                json_string);
@@ -9568,9 +10054,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
 
                                for (i = 0; i < attr->cluster->length / 4;
                                     i++) {
-                                       vty_out(vty, "%s ",
-                                               inet_ntoa(attr->cluster
-                                                                 ->list[i]));
+                                       vty_out(vty, "%pI4 ",
+                                               &attr->cluster->list[i]);
                                }
                        }
                }
@@ -9794,13 +10279,14 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                }
 
                vty_out(vty,
-                       " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64",\n \"routerId\": \"%s\",\n \"defaultLocPrf\": %u,\n"
+                       " \"vrfId\": %d,\n \"vrfName\": \"%s\",\n \"tableVersion\": %" PRId64
+                       ",\n \"routerId\": \"%pI4\",\n \"defaultLocPrf\": %u,\n"
                        " \"localAS\": %u,\n \"routes\": { ",
                        bgp->vrf_id == VRF_UNKNOWN ? -1 : (int)bgp->vrf_id,
                        bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT
-                                               ? VRF_DEFAULT_NAME
-                                               : bgp->name,
-                       table->version, inet_ntoa(bgp->router_id),
+                               ? VRF_DEFAULT_NAME
+                               : bgp->name,
+                       table->version, &bgp->router_id,
                        bgp->default_local_pref, bgp->as);
                if (rd) {
                        vty_out(vty, " \"routeDistinguishers\" : {");
@@ -9978,9 +10464,10 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                        }
 
                        if (!use_json && header) {
-                               vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
-                                       table->version,
-                                       inet_ntoa(bgp->router_id));
+                               vty_out(vty,
+                                       "BGP table version is %" PRIu64
+                                       ", local router ID is %pI4, vrf id ",
+                                       table->version, &bgp->router_id);
                                if (bgp->vrf_id == VRF_UNKNOWN)
                                        vty_out(vty, "%s", VRFID_NONE_STR);
                                else
@@ -10243,8 +10730,6 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
        struct peer *peer;
        struct listnode *node, *nnode;
        char buf1[RD_ADDRSTRLEN];
-       char buf2[INET6_ADDRSTRLEN];
-       char buf3[EVPN_ROUTE_STRLEN];
        char prefix_str[BUFSIZ];
        int count = 0;
        int best = 0;
@@ -10276,11 +10761,10 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
        if (safi == SAFI_EVPN) {
 
                if (!json) {
-                       vty_out(vty, "BGP routing table entry for %s%s%s\n",
+                       vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
                                prd ? prefix_rd2str(prd, buf1, sizeof(buf1))
-                               : "", prd ? ":" : "",
-                               bgp_evpn_route2str((struct prefix_evpn *)p,
-                               buf3, sizeof(buf3)));
+                                   : "",
+                               prd ? ":" : "", (struct prefix_evpn *)p);
                } else {
                        json_object_string_add(json, "rd",
                                prd ? prefix_rd2str(prd, buf1, sizeof(buf1)) :
@@ -10289,15 +10773,12 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
                }
        } else {
                if (!json) {
-                       vty_out(vty, "BGP routing table entry for %s%s%s/%d\n",
+                       vty_out(vty, "BGP routing table entry for %s%s%pFX\n",
                                ((safi == SAFI_MPLS_VPN || safi == SAFI_ENCAP)
-                                ? prefix_rd2str(prd, buf1,
-                                        sizeof(buf1))
-                                : ""),
-                               safi == SAFI_MPLS_VPN ? ":" : "",
-                               inet_ntop(p->family, &p->u.prefix, buf2,
-                                       INET6_ADDRSTRLEN),
-                               p->prefixlen);
+                                        ? prefix_rd2str(prd, buf1,
+                                                        sizeof(buf1))
+                                        : ""),
+                               safi == SAFI_MPLS_VPN ? ":" : "", p);
 
                } else
                        json_object_string_add(json, "prefix",
@@ -10319,7 +10800,7 @@ void route_vty_out_detail_header(struct vty *vty, struct bgp *bgp,
                count++;
                if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)) {
                        best = count;
-                       if (pi->extra && pi->extra->suppress)
+                       if (bgp_path_suppressed(pi))
                                suppress = 1;
 
                        if (pi->attr->community == NULL)
@@ -11623,9 +12104,6 @@ static void bgp_table_stats_rn(struct bgp_dest *dest, struct bgp_dest *top,
        struct bgp_path_info *pi;
        const struct prefix *rn_p;
 
-       if (dest == top)
-               return;
-
        if (!bgp_dest_has_bgp_path_info_data(dest))
                return;
 
@@ -12315,12 +12793,15 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
                                  json_object *json_ocode, bool wide)
 {
        uint64_t version = table ? table->version : 0;
+       char buf[BUFSIZ] = {0};
 
        if (*header1) {
                if (json) {
                        json_object_int_add(json, "bgpTableVersion", version);
                        json_object_string_add(json, "bgpLocalRouterId",
-                                              inet_ntoa(bgp->router_id));
+                                              inet_ntop(AF_INET,
+                                                        &bgp->router_id, buf,
+                                                        sizeof(buf)));
                        json_object_int_add(json, "defaultLocPrf",
                                            bgp->default_local_pref);
                        json_object_int_add(json, "localAS", bgp->as);
@@ -12330,8 +12811,9 @@ static void show_adj_route_header(struct vty *vty, struct bgp *bgp,
                                               json_ocode);
                } else {
                        vty_out(vty,
-                               "BGP table version is %" PRIu64 ", local router ID is %s, vrf id ",
-                               version, inet_ntoa(bgp->router_id));
+                               "BGP table version is %" PRIu64
+                               ", local router ID is %pI4, vrf id ",
+                               version, &bgp->router_id);
                        if (bgp->vrf_id == VRF_UNKNOWN)
                                vty_out(vty, "%s", VRFID_NONE_STR);
                        else
@@ -12423,11 +12905,15 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
 
        if (type == bgp_show_adj_route_advertised && subgrp
            && CHECK_FLAG(subgrp->sflags, SUBGRP_STATUS_DEFAULT_ORIGINATE)) {
+               char buf[BUFSIZ] = {0};
+
                if (use_json) {
                        json_object_int_add(json, "bgpTableVersion",
                                            table->version);
                        json_object_string_add(json, "bgpLocalRouterId",
-                                              inet_ntoa(bgp->router_id));
+                                              inet_ntop(AF_INET,
+                                                        &bgp->router_id, buf,
+                                                        sizeof(buf)));
                        json_object_int_add(json, "defaultLocPrf",
                                                bgp->default_local_pref);
                        json_object_int_add(json, "localAS", bgp->as);
@@ -12439,8 +12925,10 @@ static void show_adj_route(struct vty *vty, struct peer *peer, afi_t afi,
                                json, "bgpOriginatingDefaultNetwork",
                                (afi == AFI_IP) ? "0.0.0.0/0" : "::/0");
                } else {
-                       vty_out(vty, "BGP table version is %" PRIu64", local router ID is %s, vrf id ",
-                               table->version, inet_ntoa(bgp->router_id));
+                       vty_out(vty,
+                               "BGP table version is %" PRIu64
+                               ", local router ID is %pI4, vrf id ",
+                               table->version, &bgp->router_id);
                        if (bgp->vrf_id == VRF_UNKNOWN)
                                vty_out(vty, "%s", VRFID_NONE_STR);
                        else
@@ -12905,10 +13393,6 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
        if (use_json)
                SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
 
-       /* labeled-unicast routes live in the unicast table */
-       if (safi == SAFI_LABELED_UNICAST)
-               safi = SAFI_UNICAST;
-
        if (!peer || !peer->afc[afi][safi]) {
                if (use_json) {
                        json_object *json_no = NULL;
@@ -12924,6 +13408,10 @@ static int bgp_show_neighbor_route(struct vty *vty, struct peer *peer,
                return CMD_WARNING;
        }
 
+       /* labeled-unicast routes live in the unicast table */
+       if (safi == SAFI_LABELED_UNICAST)
+               safi = SAFI_UNICAST;
+
        return bgp_show(vty, peer->bgp, afi, safi, type, &peer->su, show_flags);
 }
 
@@ -13066,28 +13554,21 @@ static void bgp_distance_free(struct bgp_distance *bdistance)
        XFREE(MTYPE_BGP_DISTANCE, bdistance);
 }
 
-static int bgp_distance_set(struct vty *vty, const char *distance_str,
-                           const char *ip_str, const char *access_list_str)
+int bgp_distance_set(uint8_t distance, const char *ip_str,
+                    const char *access_list_str, afi_t afi, safi_t safi,
+                    char *errmsg, size_t errmsg_len)
 {
        int ret;
-       afi_t afi;
-       safi_t safi;
        struct prefix p;
-       uint8_t distance;
        struct bgp_dest *dest;
        struct bgp_distance *bdistance;
 
-       afi = bgp_node_afi(vty);
-       safi = bgp_node_safi(vty);
-
        ret = str2prefix(ip_str, &p);
        if (ret == 0) {
-               vty_out(vty, "Malformed prefix\n");
+               snprintf(errmsg, errmsg_len, "Malformed prefix\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       distance = atoi(distance_str);
-
        /* Get BGP distance node. */
        dest = bgp_node_get(bgp_distance_table[afi][safi], &p);
        bdistance = bgp_dest_get_bgp_distance_info(dest);
@@ -13110,37 +13591,32 @@ static int bgp_distance_set(struct vty *vty, const char *distance_str,
        return CMD_SUCCESS;
 }
 
-static int bgp_distance_unset(struct vty *vty, const char *distance_str,
-                             const char *ip_str, const char *access_list_str)
+int bgp_distance_unset(uint8_t distance, const char *ip_str,
+                      const char *access_list_str, afi_t afi, safi_t safi,
+                      char *errmsg, size_t errmsg_len)
 {
        int ret;
-       afi_t afi;
-       safi_t safi;
        struct prefix p;
-       int distance;
        struct bgp_dest *dest;
        struct bgp_distance *bdistance;
 
-       afi = bgp_node_afi(vty);
-       safi = bgp_node_safi(vty);
-
        ret = str2prefix(ip_str, &p);
        if (ret == 0) {
-               vty_out(vty, "Malformed prefix\n");
+               snprintf(errmsg, errmsg_len, "Malformed prefix\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
        dest = bgp_node_lookup(bgp_distance_table[afi][safi], &p);
        if (!dest) {
-               vty_out(vty, "Can't find specified prefix\n");
+               snprintf(errmsg, errmsg_len, "Can't find specified prefix\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
        bdistance = bgp_dest_get_bgp_distance_info(dest);
-       distance = atoi(distance_str);
 
        if (bdistance->distance != distance) {
-               vty_out(vty, "Distance does not match configured\n");
+               snprintf(errmsg, errmsg_len,
+                        "Distance does not match configured\n");
                return CMD_WARNING_CONFIG_FAILED;
        }
 
@@ -13218,9 +13694,8 @@ uint8_t bgp_distance_apply(const struct prefix *p, struct bgp_path_info *pinfo,
  * we should tell ZEBRA update the routes for a specific
  * AFI/SAFI to reflect changes in RIB.
  */
-static void bgp_announce_routes_distance_update(struct bgp *bgp,
-                                               afi_t update_afi,
-                                               safi_t update_safi)
+void bgp_announce_routes_distance_update(struct bgp *bgp, afi_t update_afi,
+                                        safi_t update_safi)
 {
        afi_t afi;
        safi_t safi;
@@ -13240,237 +13715,228 @@ static void bgp_announce_routes_distance_update(struct bgp *bgp,
        }
 }
 
-DEFUN (bgp_distance,
-       bgp_distance_cmd,
-       "distance bgp (1-255) (1-255) (1-255)",
-       "Define an administrative distance\n"
-       "BGP distance\n"
-       "Distance for routes external to the AS\n"
-       "Distance for routes internal to the AS\n"
-       "Distance for local routes\n")
+DEFUN_YANG(bgp_distance, bgp_distance_cmd,
+          "distance bgp (1-255) (1-255) (1-255)",
+          "Define an administrative distance\n"
+          "BGP distance\n"
+          "Distance for routes external to the AS\n"
+          "Distance for routes internal to the AS\n"
+          "Distance for local routes\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 2;
        int idx_number_2 = 3;
        int idx_number_3 = 4;
-       int distance_ebgp = atoi(argv[idx_number]->arg);
-       int distance_ibgp = atoi(argv[idx_number_2]->arg);
-       int distance_local = atoi(argv[idx_number_3]->arg);
        afi_t afi;
        safi_t safi;
+       char xpath[XPATH_MAXLEN];
 
        afi = bgp_node_afi(vty);
        safi = bgp_node_safi(vty);
 
-       if (bgp->distance_ebgp[afi][safi] != distance_ebgp
-           || bgp->distance_ibgp[afi][safi] != distance_ibgp
-           || bgp->distance_local[afi][safi] != distance_local) {
-               bgp->distance_ebgp[afi][safi] = distance_ebgp;
-               bgp->distance_ibgp[afi][safi] = distance_ibgp;
-               bgp->distance_local[afi][safi] = distance_local;
-               bgp_announce_routes_distance_update(bgp, afi, safi);
-       }
-       return CMD_SUCCESS;
-}
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, argv[idx_number]->arg);
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+                             argv[idx_number_2]->arg);
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+                             argv[idx_number_3]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG(no_bgp_distance, no_bgp_distance_cmd,
+          "no distance bgp [(1-255) (1-255) (1-255)]",
+          NO_STR
+          "Define an administrative distance\n"
+          "BGP distance\n"
+          "Distance for routes external to the AS\n"
+          "Distance for routes internal to the AS\n"
+          "Distance for local routes\n")
+{
+       afi_t afi;
+       safi_t safi;
+       char xpath[XPATH_MAXLEN];
 
-DEFUN (no_bgp_distance,
-       no_bgp_distance_cmd,
-       "no distance bgp [(1-255) (1-255) (1-255)]",
-       NO_STR
-       "Define an administrative distance\n"
-       "BGP distance\n"
-       "Distance for routes external to the AS\n"
-       "Distance for routes internal to the AS\n"
-       "Distance for local routes\n")
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/external",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/internal",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance/local",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_bgp_global_afi_safi_admin_distance_config(struct vty *vty,
+                                                       struct lyd_node *dnode,
+                                                       bool show_defaults)
+{
+       uint8_t distance_ebgp, distance_ibgp, distance_local;
+
+       distance_ebgp = yang_dnode_get_uint8(dnode, "./external");
+       distance_ibgp = yang_dnode_get_uint8(dnode, "./internal");
+       distance_local = yang_dnode_get_uint8(dnode, "./local");
+
+       vty_out(vty, "  distance bgp %d %d %d\n", distance_ebgp, distance_ibgp,
+               distance_local);
+}
+
+DEFPY_YANG(bgp_distance_source,
+          bgp_distance_source_cmd,
+          "[no] distance (1-255) <A.B.C.D/M | X:X::X:X/M>$prefix [WORD$acl]",
+          NO_STR
+          "Define an administrative distance\n"
+          "Distance value\n"
+          "IPv4 source prefix\n"
+          "IPv6 source prefix\n"
+          "Access list name\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        afi_t afi;
        safi_t safi;
+       char xpath[XPATH_MAXLEN];
 
        afi = bgp_node_afi(vty);
        safi = bgp_node_safi(vty);
 
-       if (bgp->distance_ebgp[afi][safi] != 0
-           || bgp->distance_ibgp[afi][safi] != 0
-           || bgp->distance_local[afi][safi] != 0) {
-               bgp->distance_ebgp[afi][safi] = 0;
-               bgp->distance_ibgp[afi][safi] = 0;
-               bgp->distance_local[afi][safi] = 0;
-               bgp_announce_routes_distance_update(bgp, afi, safi);
+       if (!no) {
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./distance", NB_OP_MODIFY,
+                                     distance_str);
+               if (acl)
+                       nb_cli_enqueue_change(vty,
+                                             "./access-list-policy-export",
+                                             NB_OP_CREATE, acl);
+               else
+                       nb_cli_enqueue_change(vty,
+                                             "./access-list-policy-export",
+                                             NB_OP_DESTROY, NULL);
+       } else {
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
        }
-       return CMD_SUCCESS;
-}
 
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/admin-distance-route[prefix='%s']",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi), prefix_str);
 
-DEFUN (bgp_distance_source,
-       bgp_distance_source_cmd,
-       "distance (1-255) A.B.C.D/M",
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n")
-{
-       int idx_number = 1;
-       int idx_ipv4_prefixlen = 2;
-       bgp_distance_set(vty, argv[idx_number]->arg,
-                        argv[idx_ipv4_prefixlen]->arg, NULL);
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, xpath);
 }
 
-DEFUN (no_bgp_distance_source,
-       no_bgp_distance_source_cmd,
-       "no distance (1-255) A.B.C.D/M",
-       NO_STR
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n")
+void cli_show_bgp_global_afi_safi_unicast_admin_distance_route(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
 {
-       int idx_number = 2;
-       int idx_ipv4_prefixlen = 3;
-       bgp_distance_unset(vty, argv[idx_number]->arg,
-                          argv[idx_ipv4_prefixlen]->arg, NULL);
-       return CMD_SUCCESS;
+       vty_out(vty, "  distance %d %s %s\n",
+               yang_dnode_get_uint8(dnode, "./distance"),
+               yang_dnode_get_string(dnode, "./prefix"),
+               (yang_dnode_exists(dnode, "./access-list-policy-export"))
+                       ? yang_dnode_get_string(dnode,
+                                               "./access-list-policy-export")
+                       : "");
 }
 
-DEFUN (bgp_distance_source_access_list,
-       bgp_distance_source_access_list_cmd,
-       "distance (1-255) A.B.C.D/M WORD",
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n"
-       "Access list name\n")
+DEFPY_YANG(bgp_dampening,
+          bgp_dampening_cmd,
+          "[no] bgp dampening [(1-45)$halflife [(1-20000)$reuse (1-20000)$suppress (1-255)$max_supress]]",
+          NO_STR
+          "BGP Specific commands\n"
+          "Enable route-flap dampening\n"
+          "Half-life time for the penalty\n"
+          "Value to start reusing a route\n"
+          "Value to start suppressing a route\n"
+          "Maximum duration to suppress a stable route\n")
 {
-       int idx_number = 1;
-       int idx_ipv4_prefixlen = 2;
-       int idx_word = 3;
-       bgp_distance_set(vty, argv[idx_number]->arg,
-                        argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
-       return CMD_SUCCESS;
-}
+       afi_t afi;
+       safi_t safi;
+       char xpath[XPATH_MAXLEN];
 
-DEFUN (no_bgp_distance_source_access_list,
-       no_bgp_distance_source_access_list_cmd,
-       "no distance (1-255) A.B.C.D/M WORD",
-       NO_STR
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n"
-       "Access list name\n")
-{
-       int idx_number = 2;
-       int idx_ipv4_prefixlen = 3;
-       int idx_word = 4;
-       bgp_distance_unset(vty, argv[idx_number]->arg,
-                          argv[idx_ipv4_prefixlen]->arg, argv[idx_word]->arg);
-       return CMD_SUCCESS;
-}
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
 
-DEFUN (ipv6_bgp_distance_source,
-       ipv6_bgp_distance_source_cmd,
-       "distance (1-255) X:X::X:X/M",
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n")
-{
-       bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, NULL);
-       return CMD_SUCCESS;
-}
+       if (!no) {
+               nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "true");
+               if (argc == 6) {
+                       nb_cli_enqueue_change(vty, "./reach-decay",
+                                             NB_OP_MODIFY, halflife_str);
+                       nb_cli_enqueue_change(vty, "./reuse-above",
+                                             NB_OP_MODIFY, reuse_str);
+                       nb_cli_enqueue_change(vty, "./suppress-above",
+                                             NB_OP_MODIFY, suppress_str);
+                       nb_cli_enqueue_change(vty, "./unreach-decay",
+                                             NB_OP_MODIFY, max_supress_str);
+               } if (argc == 3) {
+                       nb_cli_enqueue_change(vty, "./reach-decay",
+                                             NB_OP_MODIFY, halflife_str);
+               }
+       } else {
+               nb_cli_enqueue_change(vty, "./enable", NB_OP_MODIFY, "false");
+       }
 
-DEFUN (no_ipv6_bgp_distance_source,
-       no_ipv6_bgp_distance_source_cmd,
-       "no distance (1-255) X:X::X:X/M",
-       NO_STR
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n")
-{
-       bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, NULL);
-       return CMD_SUCCESS;
-}
+       snprintf(
+               xpath, sizeof(xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/route-flap-dampening",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
 
-DEFUN (ipv6_bgp_distance_source_access_list,
-       ipv6_bgp_distance_source_access_list_cmd,
-       "distance (1-255) X:X::X:X/M WORD",
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n"
-       "Access list name\n")
-{
-       bgp_distance_set(vty, argv[1]->arg, argv[2]->arg, argv[3]->arg);
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, xpath);
 }
 
-DEFUN (no_ipv6_bgp_distance_source_access_list,
-       no_ipv6_bgp_distance_source_access_list_cmd,
-       "no distance (1-255) X:X::X:X/M WORD",
-       NO_STR
-       "Define an administrative distance\n"
-       "Administrative distance\n"
-       "IP source prefix\n"
-       "Access list name\n")
+void cli_show_bgp_global_afi_safi_route_flap_dampening(struct vty *vty,
+                                                      struct lyd_node *dnode,
+                                                      bool show_defaults)
 {
-       bgp_distance_unset(vty, argv[2]->arg, argv[3]->arg, argv[4]->arg);
-       return CMD_SUCCESS;
-}
+       if (!yang_dnode_get_bool(dnode, "./enable"))
+               return;
 
-DEFUN (bgp_damp_set,
-       bgp_damp_set_cmd,
-       "bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
-       "BGP Specific commands\n"
-       "Enable route-flap dampening\n"
-       "Half-life time for the penalty\n"
-       "Value to start reusing a route\n"
-       "Value to start suppressing a route\n"
-       "Maximum duration to suppress a stable route\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_half_life = 2;
-       int idx_reuse = 3;
-       int idx_suppress = 4;
-       int idx_max_suppress = 5;
        int half = DEFAULT_HALF_LIFE * 60;
        int reuse = DEFAULT_REUSE;
        int suppress = DEFAULT_SUPPRESS;
-       int max = 4 * half;
-
-       if (argc == 6) {
-               half = atoi(argv[idx_half_life]->arg) * 60;
-               reuse = atoi(argv[idx_reuse]->arg);
-               suppress = atoi(argv[idx_suppress]->arg);
-               max = atoi(argv[idx_max_suppress]->arg) * 60;
-       } else if (argc == 3) {
-               half = atoi(argv[idx_half_life]->arg) * 60;
-               max = 4 * half;
-       }
-
-       /*
-        * These can't be 0 but our SA doesn't understand the
-        * way our cli is constructed
-        */
-       assert(reuse);
-       assert(half);
-       if (suppress < reuse) {
-               vty_out(vty,
-                       "Suppress value cannot be less than reuse value \n");
-               return 0;
-       }
-
-       return bgp_damp_enable(bgp, bgp_node_afi(vty), bgp_node_safi(vty), half,
-                              reuse, suppress, max);
-}
-
-DEFUN (bgp_damp_unset,
-       bgp_damp_unset_cmd,
-       "no bgp dampening [(1-45) [(1-20000) (1-20000) (1-255)]]",
-       NO_STR
-       "BGP Specific commands\n"
-       "Enable route-flap dampening\n"
-       "Half-life time for the penalty\n"
-       "Value to start reusing a route\n"
-       "Value to start suppressing a route\n"
-       "Maximum duration to suppress a stable route\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       return bgp_damp_disable(bgp, bgp_node_afi(vty), bgp_node_safi(vty));
+       int max;
+
+       half = yang_dnode_get_uint8(dnode, "../reach-decay");
+       reuse = yang_dnode_get_uint16(dnode, "../reuse-above");
+       suppress = yang_dnode_get_uint16(dnode, "../suppress-above");
+       max = yang_dnode_get_uint8(dnode, "../unreach-decay");
+
+       if (half == DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
+           && suppress == DEFAULT_SUPPRESS && max == half * 4)
+               vty_out(vty, "  bgp dampening\n");
+       else if (half != DEFAULT_HALF_LIFE * 60 && reuse == DEFAULT_REUSE
+                && suppress == DEFAULT_SUPPRESS && max == half * 4)
+               vty_out(vty, "  bgp dampening %u\n", half);
+       else
+               vty_out(vty, "  bgp dampening %u %d %d %d\n", half, reuse,
+                       suppress, max);
 }
 
 /* Display specified route of BGP table. */
@@ -13691,7 +14157,6 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
        const struct prefix_rd *prd;
        struct bgp_static *bgp_static;
        mpls_label_t label;
-       char buf[SU_ADDRSTRLEN];
        char rdbuf[RD_ADDRSTRLEN];
 
        /* Network configuration. */
@@ -13715,10 +14180,7 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
                        prefix_rd2str(prd, rdbuf, sizeof(rdbuf));
                        label = decode_label(&bgp_static->label);
 
-                       vty_out(vty, "  network %s/%d rd %s",
-                               inet_ntop(p->family, &p->u.prefix, buf,
-                                         SU_ADDRSTRLEN),
-                               p->prefixlen, rdbuf);
+                       vty_out(vty, "  network %pFX rd %s", p, rdbuf);
                        if (safi == SAFI_MPLS_VPN)
                                vty_out(vty, " label %u", label);
 
@@ -13816,7 +14278,6 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        const struct prefix *p;
        struct bgp_static *bgp_static;
        struct bgp_aggregate *bgp_aggregate;
-       char buf[SU_ADDRSTRLEN];
 
        if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)) {
                bgp_config_write_network_vpn(vty, bgp, afi, safi);
@@ -13837,9 +14298,7 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
 
                p = bgp_dest_get_prefix(dest);
 
-               vty_out(vty, "  network %s/%d",
-                       inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
-                       p->prefixlen);
+               vty_out(vty, "  network %pFX", p);
 
                if (bgp_static->label_index != BGP_INVALID_LABEL_INDEX)
                        vty_out(vty, " label-index %u",
@@ -13863,9 +14322,7 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
 
                p = bgp_dest_get_prefix(dest);
 
-               vty_out(vty, "  aggregate-address %s/%d",
-                       inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN),
-                       p->prefixlen);
+               vty_out(vty, "  aggregate-address %pFX", p);
 
                if (bgp_aggregate->as_set)
                        vty_out(vty, " as-set");
@@ -13880,6 +14337,13 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
                        vty_out(vty, " origin %s",
                                bgp_origin2str(bgp_aggregate->origin));
 
+               if (bgp_aggregate->match_med)
+                       vty_out(vty, " matching-MED-only");
+
+               if (bgp_aggregate->suppress_map_name)
+                       vty_out(vty, " suppress-map %s",
+                               bgp_aggregate->suppress_map_name);
+
                vty_out(vty, "\n");
        }
 }
@@ -13907,7 +14371,7 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
             dest = bgp_route_next(dest)) {
                bdistance = bgp_dest_get_bgp_distance_info(dest);
                if (bdistance != NULL)
-                       vty_out(vty, "  distance %d %pRN %s\n",
+                       vty_out(vty, "  distance %d %pBD %s\n",
                                bdistance->distance, dest,
                                bdistance->access_list ? bdistance->access_list
                                                       : "");
@@ -13929,36 +14393,24 @@ void bgp_route_init(void)
        install_element(BGP_NODE, &bgp_network_cmd);
        install_element(BGP_NODE, &no_bgp_table_map_cmd);
 
-       install_element(BGP_NODE, &aggregate_address_cmd);
-       install_element(BGP_NODE, &aggregate_address_mask_cmd);
-       install_element(BGP_NODE, &no_aggregate_address_cmd);
-       install_element(BGP_NODE, &no_aggregate_address_mask_cmd);
+       install_element(BGP_NODE, &aggregate_addressv4_cmd);
 
        /* IPv4 unicast configuration.  */
        install_element(BGP_IPV4_NODE, &bgp_table_map_cmd);
        install_element(BGP_IPV4_NODE, &bgp_network_cmd);
        install_element(BGP_IPV4_NODE, &no_bgp_table_map_cmd);
 
-       install_element(BGP_IPV4_NODE, &aggregate_address_cmd);
-       install_element(BGP_IPV4_NODE, &aggregate_address_mask_cmd);
-       install_element(BGP_IPV4_NODE, &no_aggregate_address_cmd);
-       install_element(BGP_IPV4_NODE, &no_aggregate_address_mask_cmd);
+       install_element(BGP_IPV4_NODE, &aggregate_addressv4_cmd);
 
        /* IPv4 multicast configuration.  */
        install_element(BGP_IPV4M_NODE, &bgp_table_map_cmd);
        install_element(BGP_IPV4M_NODE, &bgp_network_cmd);
        install_element(BGP_IPV4M_NODE, &no_bgp_table_map_cmd);
-       install_element(BGP_IPV4M_NODE, &aggregate_address_cmd);
-       install_element(BGP_IPV4M_NODE, &aggregate_address_mask_cmd);
-       install_element(BGP_IPV4M_NODE, &no_aggregate_address_cmd);
-       install_element(BGP_IPV4M_NODE, &no_aggregate_address_mask_cmd);
+       install_element(BGP_IPV4M_NODE, &aggregate_addressv4_cmd);
 
        /* IPv4 labeled-unicast configuration.  */
        install_element(BGP_IPV4L_NODE, &bgp_network_cmd);
-       install_element(BGP_IPV4L_NODE, &aggregate_address_cmd);
-       install_element(BGP_IPV4L_NODE, &aggregate_address_mask_cmd);
-       install_element(BGP_IPV4L_NODE, &no_aggregate_address_cmd);
-       install_element(BGP_IPV4L_NODE, &no_aggregate_address_mask_cmd);
+       install_element(BGP_IPV4L_NODE, &aggregate_addressv4_cmd);
 
        install_element(VIEW_NODE, &show_ip_bgp_instance_all_cmd);
        install_element(VIEW_NODE, &show_ip_bgp_cmd);
@@ -14003,67 +14455,38 @@ void bgp_route_init(void)
        install_element(BGP_IPV6_NODE, &ipv6_bgp_network_cmd);
        install_element(BGP_IPV6_NODE, &no_bgp_table_map_cmd);
 
-       install_element(BGP_IPV6_NODE, &ipv6_aggregate_address_cmd);
-       install_element(BGP_IPV6_NODE, &no_ipv6_aggregate_address_cmd);
+       install_element(BGP_IPV6_NODE, &aggregate_addressv6_cmd);
 
        install_element(BGP_IPV6M_NODE, &ipv6_bgp_network_cmd);
 
        /* IPv6 labeled unicast address family. */
        install_element(BGP_IPV6L_NODE, &ipv6_bgp_network_cmd);
-       install_element(BGP_IPV6L_NODE, &ipv6_aggregate_address_cmd);
-       install_element(BGP_IPV6L_NODE, &no_ipv6_aggregate_address_cmd);
+       install_element(BGP_IPV6L_NODE, &aggregate_addressv6_cmd);
 
        install_element(BGP_NODE, &bgp_distance_cmd);
        install_element(BGP_NODE, &no_bgp_distance_cmd);
        install_element(BGP_NODE, &bgp_distance_source_cmd);
-       install_element(BGP_NODE, &no_bgp_distance_source_cmd);
-       install_element(BGP_NODE, &bgp_distance_source_access_list_cmd);
-       install_element(BGP_NODE, &no_bgp_distance_source_access_list_cmd);
        install_element(BGP_IPV4_NODE, &bgp_distance_cmd);
        install_element(BGP_IPV4_NODE, &no_bgp_distance_cmd);
        install_element(BGP_IPV4_NODE, &bgp_distance_source_cmd);
-       install_element(BGP_IPV4_NODE, &no_bgp_distance_source_cmd);
-       install_element(BGP_IPV4_NODE, &bgp_distance_source_access_list_cmd);
-       install_element(BGP_IPV4_NODE, &no_bgp_distance_source_access_list_cmd);
        install_element(BGP_IPV4M_NODE, &bgp_distance_cmd);
        install_element(BGP_IPV4M_NODE, &no_bgp_distance_cmd);
        install_element(BGP_IPV4M_NODE, &bgp_distance_source_cmd);
-       install_element(BGP_IPV4M_NODE, &no_bgp_distance_source_cmd);
-       install_element(BGP_IPV4M_NODE, &bgp_distance_source_access_list_cmd);
-       install_element(BGP_IPV4M_NODE,
-                       &no_bgp_distance_source_access_list_cmd);
        install_element(BGP_IPV6_NODE, &bgp_distance_cmd);
        install_element(BGP_IPV6_NODE, &no_bgp_distance_cmd);
-       install_element(BGP_IPV6_NODE, &ipv6_bgp_distance_source_cmd);
-       install_element(BGP_IPV6_NODE, &no_ipv6_bgp_distance_source_cmd);
-       install_element(BGP_IPV6_NODE,
-                       &ipv6_bgp_distance_source_access_list_cmd);
-       install_element(BGP_IPV6_NODE,
-                       &no_ipv6_bgp_distance_source_access_list_cmd);
+       install_element(BGP_IPV6_NODE, &bgp_distance_source_cmd);
        install_element(BGP_IPV6M_NODE, &bgp_distance_cmd);
        install_element(BGP_IPV6M_NODE, &no_bgp_distance_cmd);
-       install_element(BGP_IPV6M_NODE, &ipv6_bgp_distance_source_cmd);
-       install_element(BGP_IPV6M_NODE, &no_ipv6_bgp_distance_source_cmd);
-       install_element(BGP_IPV6M_NODE,
-                       &ipv6_bgp_distance_source_access_list_cmd);
-       install_element(BGP_IPV6M_NODE,
-                       &no_ipv6_bgp_distance_source_access_list_cmd);
+       install_element(BGP_IPV6M_NODE, &bgp_distance_source_cmd);
 
        /* BGP dampening */
-       install_element(BGP_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_NODE, &bgp_damp_unset_cmd);
-       install_element(BGP_IPV4_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_IPV4_NODE, &bgp_damp_unset_cmd);
-       install_element(BGP_IPV4M_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_IPV4M_NODE, &bgp_damp_unset_cmd);
-       install_element(BGP_IPV4L_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_IPV4L_NODE, &bgp_damp_unset_cmd);
-       install_element(BGP_IPV6_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_IPV6_NODE, &bgp_damp_unset_cmd);
-       install_element(BGP_IPV6M_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_IPV6M_NODE, &bgp_damp_unset_cmd);
-       install_element(BGP_IPV6L_NODE, &bgp_damp_set_cmd);
-       install_element(BGP_IPV6L_NODE, &bgp_damp_unset_cmd);
+       install_element(BGP_NODE, &bgp_dampening_cmd);
+       install_element(BGP_IPV4_NODE, &bgp_dampening_cmd);
+       install_element(BGP_IPV4M_NODE, &bgp_dampening_cmd);
+       install_element(BGP_IPV4L_NODE, &bgp_dampening_cmd);
+       install_element(BGP_IPV6_NODE, &bgp_dampening_cmd);
+       install_element(BGP_IPV6M_NODE, &bgp_dampening_cmd);
+       install_element(BGP_IPV6L_NODE, &bgp_dampening_cmd);
 
        /* Large Communities */
        install_element(VIEW_NODE, &show_ip_bgp_large_community_list_cmd);
index 3407884897ad73dd18454eff66dd6f8445b2ba60..e4c6f9a0e2f356c022755c625037ea1c465e18bf 100644 (file)
@@ -110,8 +110,8 @@ struct bgp_path_info_extra {
        /* Pointer to dampening structure.  */
        struct bgp_damp_info *damp_info;
 
-       /* This route is suppressed with aggregation.  */
-       int suppress;
+       /** List of aggregations that suppress this path. */
+       struct list *aggr_suppressors;
 
        /* Nexthop reachability check.  */
        uint32_t igpmetric;
@@ -379,6 +379,30 @@ struct bgp_aggregate {
 
        /* SAFI configuration. */
        safi_t safi;
+
+       /** Match only equal MED. */
+       bool match_med;
+       /* MED matching state. */
+       /** Did we get the first MED value? */
+       bool med_initialized;
+       /** Are there MED mismatches? */
+       bool med_mismatched;
+       /** MED value found in current group. */
+       uint32_t med_matched_value;
+
+       /**
+        * Test if aggregated address MED of all route match, otherwise
+        * returns `false`. This macro will also return `true` if MED
+        * matching is disabled.
+        */
+#define AGGREGATE_MED_VALID(aggregate)                                         \
+       (((aggregate)->match_med && !(aggregate)->med_mismatched)              \
+        || !(aggregate)->match_med)
+
+       /** Suppress map route map name (`NULL` when disabled). */
+       char *suppress_map_name;
+       /** Suppress map route map pointer. */
+       struct route_map *suppress_map;
 };
 
 #define BGP_NEXTHOP_AFI_FROM_NHLEN(nhlen)                                      \
@@ -430,6 +454,14 @@ struct bgp_aggregate {
 #define UNSUPPRESS_MAP_NAME(F)  ((F)->usmap.name)
 #define UNSUPPRESS_MAP(F)       ((F)->usmap.map)
 
+#define ADVERTISE_MAP_NAME(F)  ((F)->advmap.aname)
+#define ADVERTISE_MAP(F)       ((F)->advmap.amap)
+
+#define ADVERTISE_CONDITION(F) ((F)->advmap.condition)
+
+#define CONDITION_MAP_NAME(F)  ((F)->advmap.cname)
+#define CONDITION_MAP(F)       ((F)->advmap.cmap)
+
 /* path PREFIX (addpath rxid NUMBER) */
 #define PATH_ADDPATH_STR_BUFFER PREFIX2STR_BUFFER + 32
 
@@ -508,7 +540,7 @@ DECLARE_HOOK(bgp_process,
 /* Prototypes. */
 extern void bgp_rib_remove(struct bgp_dest *dest, struct bgp_path_info *pi,
                           struct peer *peer, afi_t afi, safi_t safi);
-extern void bgp_process_queue_init(void);
+extern void bgp_process_queue_init(struct bgp *bgp);
 extern void bgp_route_init(void);
 extern void bgp_route_finish(void);
 extern void bgp_cleanup_routes(struct bgp *);
@@ -639,6 +671,8 @@ extern void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
                                  struct bgp_path_info *path, int display,
                                  json_object *json);
 
+extern void bgp_notify_conditional_adv_scanner(struct update_subgroup *subgrp);
+
 extern void subgroup_process_announce_selected(struct update_subgroup *subgrp,
                                               struct bgp_path_info *selected,
                                               struct bgp_dest *dest,
@@ -647,7 +681,8 @@ extern void subgroup_process_announce_selected(struct update_subgroup *subgrp,
 extern bool subgroup_announce_check(struct bgp_dest *dest,
                                    struct bgp_path_info *pi,
                                    struct update_subgroup *subgrp,
-                                   const struct prefix *p, struct attr *attr);
+                                   const struct prefix *p, struct attr *attr,
+                                   bool skip_rmap_check);
 
 extern void bgp_peer_clear_node_queue_drain_immediate(struct peer *peer);
 extern void bgp_process_queues_drain_immediate(void);
@@ -691,4 +726,36 @@ extern bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
                                       struct attr *attr, struct bgp_dest *dest);
 extern int bgp_evpn_path_info_cmp(struct bgp *bgp, struct bgp_path_info *new,
                             struct bgp_path_info *exist, int *paths_eq);
+extern void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
+                                           struct bgp *bgp,
+                                           const struct prefix *p, afi_t afi,
+                                           safi_t safi, bool suppress);
+extern int bgp_static_set(struct bgp *bgp, const char *negate,
+                         struct prefix *pfx, afi_t afi, safi_t safi,
+                         const char *rmap, int backdoor, uint32_t label_index,
+                         char *errmsg, size_t errmsg_len);
+
+extern int bgp_aggregate_set(struct bgp *bgp, struct prefix *prefix, afi_t afi,
+                            safi_t safi, const char *rmap,
+                            uint8_t summary_only, uint8_t as_set,
+                            uint8_t origin, bool match_med,
+                            const char *suppress_map, char *errmsg,
+                            size_t errmsg_len);
+
+extern int bgp_aggregate_unset(struct bgp *bgp, struct prefix *prefix,
+                              afi_t afi, safi_t safi, char *errmsg,
+                              size_t errmsg_len);
+
+extern void bgp_announce_routes_distance_update(struct bgp *bgp,
+                                               afi_t update_afi,
+                                               safi_t update_safi);
+
+extern int bgp_distance_set(uint8_t distance, const char *ip_str,
+                           const char *access_list_str, afi_t afi, safi_t safi,
+                           char *errmsg, size_t errmsg_len);
+
+extern int bgp_distance_unset(uint8_t distance, const char *ip_str,
+                             const char *access_list_str, afi_t afi,
+                             safi_t safi, char *errmsg, size_t errmsg_len);
+extern void subgroup_announce_reset_nhop(uint8_t family, struct attr *attr);
 #endif /* _QUAGGA_BGP_ROUTE_H */
index 09cc775d479550aa4120babb731fc0b7fc79297e..e4a9c29000675b40e5c6ec8c9f7c50f1728cf72e 100644 (file)
@@ -3695,9 +3695,22 @@ static void bgp_route_map_process_peer(const char *rmap_name,
        if (filter->usmap.name && (strcmp(rmap_name, filter->usmap.name) == 0))
                filter->usmap.map = map;
 
+       if (filter->advmap.aname
+           && (strcmp(rmap_name, filter->advmap.aname) == 0)) {
+               filter->advmap.amap = map;
+       }
+
+       if (filter->advmap.cname
+           && (strcmp(rmap_name, filter->advmap.cname) == 0)) {
+               filter->advmap.cmap = map;
+       }
+
        if (peer->default_rmap[afi][safi].name
            && (strcmp(rmap_name, peer->default_rmap[afi][safi].name) == 0))
                peer->default_rmap[afi][safi].map = map;
+
+       /* Notify BGP conditional advertisement scanner percess */
+       peer->advmap_config_change[afi][safi] = true;
 }
 
 static void bgp_route_map_update_peer_group(const char *rmap_name,
@@ -3746,6 +3759,7 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                                         int route_update)
 {
        int i;
+       bool matched;
        afi_t afi;
        safi_t safi;
        struct peer *peer;
@@ -3845,16 +3859,35 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                        if (!aggregate)
                                continue;
 
-                       if (!aggregate->rmap.name
-                           || (strcmp(rmap_name, aggregate->rmap.name) != 0))
-                               continue;
+                       matched = false;
 
-                       if (!aggregate->rmap.map)
-                               route_map_counter_increment(map);
+                       /* Update suppress map pointer. */
+                       if (aggregate->suppress_map_name
+                           && strmatch(aggregate->suppress_map_name,
+                                       rmap_name)) {
+                               if (aggregate->rmap.map == NULL)
+                                       route_map_counter_increment(map);
+
+                               aggregate->suppress_map = map;
+
+                               bgp_aggregate_toggle_suppressed(
+                                       aggregate, bgp, bgp_dest_get_prefix(bn),
+                                       afi, safi, false);
+
+                               matched = true;
+                       }
+
+                       if (aggregate->rmap.name
+                           && strmatch(rmap_name, aggregate->rmap.name)) {
+                               if (aggregate->rmap.map == NULL)
+                                       route_map_counter_increment(map);
+
+                               aggregate->rmap.map = map;
 
-                       aggregate->rmap.map = map;
+                               matched = true;
+                       }
 
-                       if (route_update) {
+                       if (matched && route_update) {
                                const struct prefix *bn_p =
                                        bgp_dest_get_prefix(bn);
 
@@ -3960,8 +3993,7 @@ static void bgp_route_map_mark_update(const char *rmap_name)
        /* If new update is received before the current timer timed out,
         * turn it off and start a new timer.
         */
-       if (bm->t_rmap_update != NULL)
-               THREAD_OFF(bm->t_rmap_update);
+       THREAD_OFF(bm->t_rmap_update);
 
        /* rmap_update_timer of 0 means don't do route updates */
        if (bm->rmap_update_timer) {
@@ -4034,32 +4066,64 @@ DEFUN (no_match_mac_address,
                                      RMAP_EVENT_FILTER_DELETED);
 }
 
+/*
+ * Helper to handle the case of the user passing in a number or type string
+ */
+static const char *parse_evpn_rt_type(const char *num_rt_type)
+{
+       switch (num_rt_type[0]) {
+       case '1':
+               return "ead";
+       case '2':
+               return "macip";
+       case '3':
+               return "multicast";
+       case '4':
+               return "es";
+       case '5':
+               return "prefix";
+       default:
+               break;
+       }
+
+       /* Was already full type string */
+       return num_rt_type;
+}
+
 DEFUN (match_evpn_route_type,
        match_evpn_route_type_cmd,
-       "match evpn route-type <macip | multicast | prefix>",
+       "match evpn route-type <macip|2|multicast|3|prefix|5>",
        MATCH_STR
        EVPN_HELP_STR
-       "Match route-type\n"
-       "mac-ip route\n"
-       "IMET route\n"
-       "prefix route\n")
-{
-       return bgp_route_match_add(vty, "evpn route-type", argv[3]->arg,
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_5_HELP_STR
+       EVPN_TYPE_5_HELP_STR)
+{
+       return bgp_route_match_add(vty, "evpn route-type",
+                                  parse_evpn_rt_type(argv[3]->arg),
                                   RMAP_EVENT_MATCH_ADDED);
 }
 
 DEFUN (no_match_evpn_route_type,
        no_match_evpn_route_type_cmd,
-       "no match evpn route-type <macip | multicast | prefix>",
+       "no match evpn route-type <macip|2|multicast|3|prefix|5>",
        NO_STR
        MATCH_STR
        EVPN_HELP_STR
-       "Match route-type\n"
-       "mac-ip route\n"
-       "IMET route\n"
-       "prefix route\n")
-{
-       return bgp_route_match_delete(vty, "evpn route-type", argv[4]->arg,
+       EVPN_TYPE_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_2_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_3_HELP_STR
+       EVPN_TYPE_5_HELP_STR
+       EVPN_TYPE_5_HELP_STR)
+{
+       return bgp_route_match_delete(vty, "evpn route-type",
+                                     parse_evpn_rt_type(argv[4]->arg),
                                      RMAP_EVENT_MATCH_DELETED);
 }
 
index ca47fb316a0e9414c6bc992b7f239bb8d39aec53..0f0aff7eaaca537bf459b965f28d8fddb936ee65 100644 (file)
@@ -702,8 +702,6 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
        as_t as_number = 0;
        struct lrtr_ip_addr ip_addr_prefix;
        enum pfxv_state result;
-       char buf[BUFSIZ];
-       const char *prefix_string;
 
        if (!is_synchronized())
                return 0;
@@ -754,27 +752,26 @@ static int rpki_validate_prefix(struct peer *peer, struct attr *attr,
                         prefix->prefixlen, &result);
 
        // Print Debug output
-       prefix_string = prefix2str(prefix, buf, sizeof(buf));
        switch (result) {
        case BGP_PFXV_STATE_VALID:
                RPKI_DEBUG(
-                       "Validating Prefix %s from asn %u    Result: VALID",
-                       prefix_string, as_number);
+                       "Validating Prefix %pFX from asn %u    Result: VALID",
+                       prefix, as_number);
                return RPKI_VALID;
        case BGP_PFXV_STATE_NOT_FOUND:
                RPKI_DEBUG(
-                       "Validating Prefix %s from asn %u    Result: NOT FOUND",
-                       prefix_string, as_number);
+                       "Validating Prefix %pFX from asn %u    Result: NOT FOUND",
+                       prefix, as_number);
                return RPKI_NOTFOUND;
        case BGP_PFXV_STATE_INVALID:
                RPKI_DEBUG(
-                       "Validating Prefix %s from asn %u    Result: INVALID",
-                       prefix_string, as_number);
+                       "Validating Prefix %pFX from asn %u    Result: INVALID",
+                       prefix, as_number);
                return RPKI_INVALID;
        default:
                RPKI_DEBUG(
-                       "Validating Prefix %s from asn %u    Result: CANNOT VALIDATE",
-                       prefix_string, as_number);
+                       "Validating Prefix %pFX from asn %u    Result: CANNOT VALIDATE",
+                       prefix, as_number);
                break;
        }
        return 0;
index 185cb251c7efa4c4379cbc46dce2997f443b76e1..022a6413e2bb2cf2ac5a32a751f10e976a4b161e 100644 (file)
@@ -26,6 +26,7 @@
 #include "queue.h"
 #include "filter.h"
 #include "command.h"
+#include "printfrr.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_table.h"
@@ -153,13 +154,8 @@ void bgp_delete_listnode(struct bgp_node *node)
 
                if (bgp && rn && rn->lock == 1) {
                        /* Delete the route from the selection pending list */
-                       if ((node->rt_node)
-                           && (bgp->gr_info[afi][safi].route_list)) {
-                               list_delete_node(
-                                       bgp->gr_info[afi][safi].route_list,
-                                       node->rt_node);
-                               node->rt_node = NULL;
-                       }
+                       bgp->gr_info[afi][safi].gr_deferred--;
+                       UNSET_FLAG(node->flags, BGP_NODE_SELECT_DEFER);
                }
        }
 }
@@ -203,3 +199,14 @@ struct bgp_node *bgp_table_subtree_lookup(const struct bgp_table *table,
        bgp_dest_lock_node(matched);
        return matched;
 }
+
+printfrr_ext_autoreg_p("BD", printfrr_bd)
+static ssize_t printfrr_bd(char *buf, size_t bsz, const char *fmt,
+                          int prec, const void *ptr)
+{
+       const struct bgp_dest *dest = ptr;
+       const struct prefix *p = bgp_dest_get_prefix(dest);
+
+       prefix2str(p, buf, bsz);
+       return 2;
+}
index cf0086b52e91f5bf71ae5f5deba7fc0132d3834a..4e9abf863ddb9d6b6ae3533752d66f0eef064769 100644 (file)
@@ -102,8 +102,7 @@ struct bgp_node {
 #define BGP_NODE_LABEL_CHANGED          (1 << 2)
 #define BGP_NODE_REGISTERED_FOR_LABEL   (1 << 3)
 #define BGP_NODE_SELECT_DEFER           (1 << 4)
-       /* list node pointer */
-       struct listnode *rt_node;
+
        struct bgp_addpath_node_data tx_addpath;
 
        enum bgp_path_selection_reason reason;
@@ -469,8 +468,14 @@ static inline const struct prefix *bgp_dest_get_prefix(const struct bgp_dest *de
        return &dest->p;
 }
 
+static inline unsigned int bgp_dest_get_lock_count(const struct bgp_dest *dest)
+{
+       return dest->lock;
+}
+
 #ifdef _FRR_ATTRIBUTE_PRINTFRR
 #pragma FRR printfrr_ext "%pRN"  (struct bgp_node *)
+#pragma FRR printfrr_ext "%pBD"  (struct bgp_dest *)
 #endif
 
 #endif /* _QUAGGA_BGP_TABLE_H */
diff --git a/bgpd/bgp_trace.c b/bgpd/bgp_trace.c
new file mode 100644 (file)
index 0000000..2ebc63b
--- /dev/null
@@ -0,0 +1,4 @@
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+
+#include "bgp_trace.h"
diff --git a/bgpd/bgp_trace.h b/bgpd/bgp_trace.h
new file mode 100644 (file)
index 0000000..2566ffb
--- /dev/null
@@ -0,0 +1,131 @@
+/* Tracing for BGP
+ *
+ * Copyright (C) 2020  NVIDIA Corporation
+ * Quentin Young
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined(_BGP_TRACE_H) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _BGP_TRACE_H
+
+#include "lib/trace.h"
+
+#ifdef HAVE_LTTNG
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER frr_bgp
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "bgpd/bgp_trace.h"
+
+#include <lttng/tracepoint.h>
+
+#include "bgpd/bgpd.h"
+#include "lib/stream.h"
+
+/* clang-format off */
+
+TRACEPOINT_EVENT_CLASS(
+       frr_bgp,
+       packet_process,
+       TP_ARGS(struct peer *, peer, bgp_size_t, size),
+       TP_FIELDS(
+               ctf_string(peer, peer->host ? peer->host : "(unknown peer)")
+       )
+)
+
+#define PKT_PROCESS_TRACEPOINT_INSTANCE(name)                                  \
+       TRACEPOINT_EVENT_INSTANCE(                                             \
+               frr_bgp, packet_process, name,                                 \
+               TP_ARGS(struct peer *, peer, bgp_size_t, size))                \
+       TRACEPOINT_LOGLEVEL(frr_bgp, name, TRACE_INFO)
+
+PKT_PROCESS_TRACEPOINT_INSTANCE(open_process)
+PKT_PROCESS_TRACEPOINT_INSTANCE(keepalive_process)
+PKT_PROCESS_TRACEPOINT_INSTANCE(update_process)
+PKT_PROCESS_TRACEPOINT_INSTANCE(notification_process)
+PKT_PROCESS_TRACEPOINT_INSTANCE(capability_process)
+PKT_PROCESS_TRACEPOINT_INSTANCE(refresh_process)
+
+TRACEPOINT_EVENT(
+       frr_bgp,
+       packet_read,
+       TP_ARGS(struct peer *, peer, struct stream *, pkt),
+       TP_FIELDS(
+               ctf_string(peer, peer->host ? peer->host : "(unknown peer)")
+               ctf_sequence_hex(uint8_t, packet, pkt->data, size_t,
+                                STREAM_READABLE(pkt))
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_bgp, packet_read, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+       frr_bgp,
+       process_update,
+       TP_ARGS(struct peer *, peer, char *, pfx, uint32_t, addpath_id, afi_t,
+               afi, safi_t, safi, struct attr *, attr),
+       TP_FIELDS(
+               ctf_string(peer, peer->host ? peer->host : "(unknown peer)")
+               ctf_string(prefix, pfx)
+               ctf_integer(uint32_t, addpath_id, addpath_id)
+               ctf_integer(afi_t, afi, afi)
+               ctf_integer(safi_t, safi, safi)
+               ctf_integer_hex(intptr_t, attribute_ptr, attr)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_bgp, process_update, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+       frr_bgp,
+       input_filter,
+       TP_ARGS(struct peer *, peer, char *, pfx, afi_t, afi, safi_t, safi,
+               const char *, result),
+       TP_FIELDS(
+               ctf_string(peer, peer->host ? peer->host : "(unknown peer)")
+               ctf_string(prefix, pfx)
+               ctf_integer(afi_t, afi, afi)
+               ctf_integer(safi_t, safi, safi)
+               ctf_string(action, result)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_bgp, input_filter, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+       frr_bgp,
+       output_filter,
+       TP_ARGS(struct peer *, peer, char *, pfx, afi_t, afi, safi_t, safi,
+               const char *, result),
+       TP_FIELDS(
+               ctf_string(peer, peer->host ? peer->host : "(unknown peer)")
+               ctf_string(prefix, pfx)
+               ctf_integer(afi_t, afi, afi)
+               ctf_integer(safi_t, safi, safi)
+               ctf_string(action, result)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_bgp, output_filter, TRACE_INFO)
+
+/* clang-format on */
+
+#include <lttng/tracepoint-event.h>
+
+#endif /* HAVE_LTTNG */
+
+#endif /* _BGP_TRACE_H */
index d2e563b23700266dd7ff8d19b5d6729bbe7bf580..2788a8ea4ff48583938f819487ef1c12d5e4ba93 100644 (file)
@@ -195,6 +195,19 @@ static void conf_copy(struct peer *dst, struct peer *src, afi_t afi,
                        MTYPE_BGP_FILTER_NAME, UNSUPPRESS_MAP_NAME(srcfilter));
                UNSUPPRESS_MAP(dstfilter) = UNSUPPRESS_MAP(srcfilter);
        }
+
+       if (ADVERTISE_MAP_NAME(srcfilter)) {
+               ADVERTISE_MAP_NAME(dstfilter) = XSTRDUP(
+                       MTYPE_BGP_FILTER_NAME, ADVERTISE_MAP_NAME(srcfilter));
+               ADVERTISE_MAP(dstfilter) = ADVERTISE_MAP(srcfilter);
+               ADVERTISE_CONDITION(dstfilter) = ADVERTISE_CONDITION(srcfilter);
+       }
+
+       if (CONDITION_MAP_NAME(srcfilter)) {
+               CONDITION_MAP_NAME(dstfilter) = XSTRDUP(
+                       MTYPE_BGP_FILTER_NAME, CONDITION_MAP_NAME(srcfilter));
+               CONDITION_MAP(dstfilter) = CONDITION_MAP(srcfilter);
+       }
 }
 
 /**
@@ -218,6 +231,10 @@ static void conf_release(struct peer *src, afi_t afi, safi_t safi)
 
        XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->usmap.name);
 
+       XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.aname);
+
+       XFREE(MTYPE_BGP_FILTER_NAME, srcfilter->advmap.cname);
+
        XFREE(MTYPE_BGP_PEER_HOST, src->host);
 }
 
@@ -353,6 +370,11 @@ static unsigned int updgrp_hash_key_make(const void *p)
                                        strlen(filter->usmap.name), SEED1),
                                  key);
 
+       if (filter->advmap.aname)
+               key = jhash_1word(jhash(filter->advmap.aname,
+                                       strlen(filter->advmap.aname), SEED1),
+                                 key);
+
        if (peer->default_rmap[afi][safi].name)
                key = jhash_1word(
                        jhash(peer->default_rmap[afi][safi].name,
@@ -481,6 +503,12 @@ static bool updgrp_hash_cmp(const void *p1, const void *p2)
                && strcmp(fl1->usmap.name, fl2->usmap.name)))
                return false;
 
+       if ((fl1->advmap.aname && !fl2->advmap.aname)
+           || (!fl1->advmap.aname && fl2->advmap.aname)
+           || (fl1->advmap.aname && fl2->advmap.aname
+               && strcmp(fl1->advmap.aname, fl2->advmap.aname)))
+               return false;
+
        if ((pe1->default_rmap[afi][safi].name
             && !pe2->default_rmap[afi][safi].name)
            || (!pe1->default_rmap[afi][safi].name
@@ -795,17 +823,12 @@ static void update_subgroup_delete(struct update_subgroup *subgrp)
        if (subgrp->update_group)
                UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted);
 
-       if (subgrp->t_merge_check)
-               THREAD_OFF(subgrp->t_merge_check);
-
-       if (subgrp->t_coalesce)
-               THREAD_TIMER_OFF(subgrp->t_coalesce);
+       THREAD_OFF(subgrp->t_merge_check);
+       THREAD_OFF(subgrp->t_coalesce);
 
        bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp));
        subgroup_clear_table(subgrp);
 
-       if (subgrp->t_coalesce)
-               THREAD_TIMER_OFF(subgrp->t_coalesce);
        sync_delete(subgrp);
 
        if (BGP_DEBUG(update_groups, UPDATE_GROUPS) && subgrp->update_group)
@@ -1771,7 +1794,7 @@ int update_group_refresh_default_originate_route_map(struct thread *thread)
        bgp = THREAD_ARG(thread);
        update_group_walk(bgp, update_group_default_originate_route_map_walkcb,
                          reason);
-       THREAD_TIMER_OFF(bgp->t_rmap_def_originate_eval);
+       thread_cancel(&bgp->t_rmap_def_originate_eval);
        bgp_unlock(bgp);
 
        return 0;
index 67fa9a3ea3e2dc69984817f8b8de5150323f2ad4..3cfb73d8a81b15bbc5e5f0fe0d8f8af139e6401d 100644 (file)
@@ -215,6 +215,9 @@ static int group_announce_route_walkcb(struct update_group *updgrp, void *arg)
                                }
                        }
                }
+
+               /* Notify BGP Conditional advertisement */
+               bgp_notify_conditional_adv_scanner(subgrp);
        }
 
        return UPDWALK_CONTINUE;
@@ -246,9 +249,10 @@ static void subgrp_show_adjq_vty(struct update_subgroup *subgrp,
                        if (adj->subgroup == subgrp) {
                                if (header1) {
                                        vty_out(vty,
-                                               "BGP table version is %" PRIu64", local router ID is %s\n",
+                                               "BGP table version is %" PRIu64
+                                               ", local router ID is %pI4\n",
                                                table->version,
-                                               inet_ntoa(bgp->router_id));
+                                               &bgp->router_id);
                                        vty_out(vty, BGP_SHOW_SCODE_HEADER);
                                        vty_out(vty, BGP_SHOW_OCODE_HEADER);
                                        header1 = 0;
@@ -641,7 +645,8 @@ void subgroup_announce_table(struct update_subgroup *subgrp,
                                           peer->addpath_type[afi][safi],
                                           ri))) {
                                if (subgroup_announce_check(dest, ri, subgrp,
-                                                           dest_p, &attr))
+                                                           dest_p, &attr,
+                                                           false))
                                        bgp_adj_out_set_subgroup(dest, subgrp,
                                                                 &attr, ri);
                                else {
@@ -726,7 +731,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
        struct bgp *bgp;
        struct attr attr;
        struct attr *new_attr = &attr;
-       struct aspath *aspath;
        struct prefix p;
        struct peer *from;
        struct bgp_dest *dest;
@@ -751,7 +755,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
        from = bgp->peer_self;
 
        bgp_attr_default_set(&attr, BGP_ORIGIN_IGP);
-       aspath = attr.aspath;
 
        attr.local_pref = bgp->default_local_pref;
 
@@ -767,12 +770,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
        }
 
        if (peer->default_rmap[afi][safi].name) {
-               struct attr attr_tmp = attr;
-               struct bgp_path_info bpi_rmap = {0};
-
-               bpi_rmap.peer = bgp->peer_self;
-               bpi_rmap.attr = &attr_tmp;
-
                SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_DEFAULT);
 
                /* Iterate over the RIB to see if we can announce
@@ -784,20 +781,45 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
                        if (!bgp_dest_has_bgp_path_info_data(dest))
                                continue;
 
-                       ret = route_map_apply(peer->default_rmap[afi][safi].map,
-                                             bgp_dest_get_prefix(dest),
-                                             RMAP_BGP, &bpi_rmap);
+                       for (pi = bgp_dest_get_bgp_path_info(dest); pi;
+                            pi = pi->next) {
+                               struct attr tmp_attr;
+                               struct bgp_path_info tmp_pi;
+                               struct bgp_path_info_extra tmp_pie;
+
+                               tmp_attr = *pi->attr;
+
+                               prep_for_rmap_apply(&tmp_pi, &tmp_pie, dest, pi,
+                                                   pi->peer, &tmp_attr);
+
+                               ret = route_map_apply(
+                                       peer->default_rmap[afi][safi].map,
+                                       bgp_dest_get_prefix(dest), RMAP_BGP,
+                                       &tmp_pi);
 
-                       if (ret != RMAP_DENYMATCH)
+                               if (ret == RMAP_DENYMATCH) {
+                                       bgp_attr_flush(&tmp_attr);
+                                       continue;
+                               } else {
+                                       new_attr = bgp_attr_intern(&tmp_attr);
+                                       new_attr->aspath = attr.aspath;
+
+                                       subgroup_announce_reset_nhop(
+                                               (peer_cap_enhe(peer, afi, safi)
+                                                        ? AF_INET6
+                                                        : AF_INET),
+                                               new_attr);
+
+                                       break;
+                               }
+                       }
+                       if (ret == RMAP_PERMITMATCH)
                                break;
                }
                bgp->peer_self->rmap_type = 0;
-               new_attr = bgp_attr_intern(&attr_tmp);
 
-               if (ret == RMAP_DENYMATCH) {
-                       bgp_attr_flush(&attr_tmp);
+               if (ret == RMAP_DENYMATCH)
                        withdraw = 1;
-               }
        }
 
        /* Check if the default route is in local BGP RIB which is
@@ -826,7 +848,7 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
                                        if (subgroup_announce_check(
                                                    dest, pi, subgrp,
                                                    bgp_dest_get_prefix(dest),
-                                                   &attr))
+                                                   &attr, false))
                                                bgp_adj_out_set_subgroup(
                                                        dest, subgrp, &attr,
                                                        pi);
@@ -876,8 +898,6 @@ void subgroup_default_originate(struct update_subgroup *subgrp, int withdraw)
                        subgroup_default_update_packet(subgrp, new_attr, from);
                }
        }
-
-       aspath_unintern(&aspath);
 }
 
 /*
index f706b834fed23a22bc2ff4b78fe34518a3a0f94b..c3edb9e9a4a8cd5798db6e96a7ff85a85918ce6b 100644 (file)
@@ -488,10 +488,10 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
                        stream_put_in_addr_at(s, offset_nh, mod_v4nh);
 
                if (bgp_debug_update(peer, NULL, NULL, 0))
-                       zlog_debug("u%" PRIu64 ":s%" PRIu64" %s send UPDATE w/ nexthop %s%s",
+                       zlog_debug("u%" PRIu64 ":s%" PRIu64
+                                  " %s send UPDATE w/ nexthop %pI4%s",
                                   PAF_SUBGRP(paf)->update_group->id,
-                                  PAF_SUBGRP(paf)->id, peer->host,
-                                  inet_ntoa(*mod_v4nh),
+                                  PAF_SUBGRP(paf)->id, peer->host, mod_v4nh,
                                   (nhlen == BGP_ATTR_NHLEN_VPNV4 ? " and RD"
                                                                  : ""));
        } else if (nhafi == AFI_IP6) {
@@ -642,10 +642,10 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
                        stream_put_in_addr_at(s, vec->offset + 1, mod_v4nh);
 
                if (bgp_debug_update(peer, NULL, NULL, 0))
-                       zlog_debug("u%" PRIu64 ":s%" PRIu64" %s send UPDATE w/ nexthop %s",
+                       zlog_debug("u%" PRIu64 ":s%" PRIu64
+                                  " %s send UPDATE w/ nexthop %pI4",
                                   PAF_SUBGRP(paf)->update_group->id,
-                                  PAF_SUBGRP(paf)->id, peer->host,
-                                  inet_ntoa(*mod_v4nh));
+                                  PAF_SUBGRP(paf)->id, peer->host, mod_v4nh);
        }
 
        return s;
@@ -1137,7 +1137,6 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
        /* Logging the attribute. */
        if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
                char attrstr[BUFSIZ];
-               char buf[PREFIX_STRLEN];
                /* ' with addpath ID '          17
                 * max strlen of uint32       + 10
                 * +/- (just in case)         +  1
@@ -1156,10 +1155,9 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
                else
                        tx_id_buf[0] = '\0';
 
-               zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s%s %s",
-                          (SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
-                          prefix2str(&p, buf, sizeof(buf)), tx_id_buf,
-                          attrstr);
+               zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %pFX%s %s",
+                          (SUBGRP_UPDGRP(subgrp))->id, subgrp->id, &p,
+                          tx_id_buf, attrstr);
        }
 
        s = stream_new(BGP_MAX_PACKET_SIZE);
@@ -1222,7 +1220,6 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
        p.prefixlen = 0;
 
        if (bgp_debug_update(NULL, &p, subgrp->update_group, 0)) {
-               char buf[PREFIX_STRLEN];
                /* ' with addpath ID '          17
                 * max strlen of uint32       + 10
                 * +/- (just in case)         +  1
@@ -1235,9 +1232,10 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
                                 " with addpath ID %u",
                                 BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
 
-               zlog_debug("u%" PRIu64 ":s%" PRIu64" send UPDATE %s%s -- unreachable",
-                          (SUBGRP_UPDGRP(subgrp))->id, subgrp->id,
-                          prefix2str(&p, buf, sizeof(buf)), tx_id_buf);
+               zlog_debug("u%" PRIu64 ":s%" PRIu64
+                          " send UPDATE %pFX%s -- unreachable",
+                          (SUBGRP_UPDGRP(subgrp))->id, subgrp->id, &p,
+                          tx_id_buf);
        }
 
        s = stream_new(BGP_MAX_PACKET_SIZE);
index 0b5d156e6d49f36dba1bfc593f2acaf9005a1fa2..cb459ae13cca3a0825eaf745e9cd0da89cd831c9 100644 (file)
@@ -22,6 +22,7 @@
 #include "command.h"
 #include "prefix.h"
 #include "lib/json.h"
+#include "lib/printfrr.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_route.h"
@@ -117,11 +118,15 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
 
                        if (header) {
                                if (use_json) {
+                                       char buf[BUFSIZ] = {0};
+
                                        json_object_int_add(
                                                json, "bgpTableVersion", 0);
                                        json_object_string_add(
                                                json, "bgpLocalRouterId",
-                                               inet_ntoa(bgp->router_id));
+                                               inet_ntop(AF_INET,
+                                                         &bgp->router_id, buf,
+                                                         sizeof(buf)));
                                        json_object_int_add(
                                                json,
                                                "defaultLocPrf",
@@ -137,8 +142,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
                                                               json_ocode);
                                } else {
                                        vty_out(vty,
-                                               "BGP table version is 0, local router ID is %s\n",
-                                               inet_ntoa(bgp->router_id));
+                                               "BGP table version is 0, local router ID is %pI4\n",
+                                               &bgp->router_id);
                                        vty_out(vty, "Default local pref %u, ",
                                                bgp->default_local_pref);
                                        vty_out(vty, "local AS %u\n", bgp->as);
@@ -184,10 +189,10 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
                                                         "%u:%d", rd_as.as,
                                                         rd_as.val);
                                        else if (type == RD_TYPE_IP)
-                                               snprintf(rd_str, sizeof(rd_str),
-                                                        "%s:%d",
-                                                        inet_ntoa(rd_ip.ip),
-                                                        rd_ip.val);
+                                               snprintfrr(rd_str,
+                                                          sizeof(rd_str),
+                                                          "%pI4:%d", &rd_ip.ip,
+                                                          rd_ip.val);
                                        json_object_string_add(
                                                json_routes,
                                                "rd", rd_str);
@@ -199,9 +204,8 @@ int show_adj_route_vpn(struct vty *vty, struct peer *peer,
                                                vty_out(vty, "%u:%d", rd_as.as,
                                                        rd_as.val);
                                        else if (type == RD_TYPE_IP)
-                                               vty_out(vty, "%s:%d",
-                                                       inet_ntoa(rd_ip.ip),
-                                                       rd_ip.val);
+                                               vty_out(vty, "%pI4:%d",
+                                                       &rd_ip.ip, rd_ip.val);
 #ifdef ENABLE_BGP_VNC
                                        else if (type == RD_TYPE_VNC_ETH)
                                                vty_out(vty,
index 795a4adfc7f5185d19264899d2a782dbcf9047f8..00e781d804cb2304c4a68ca7ee63d1abe33b8683 100644 (file)
 #include "bgpd/rfapi/bgp_rfapi_cfg.h"
 #endif
 
+#include "northbound.h"
+#include "northbound_cli.h"
+#include "bgpd/bgp_nb.h"
+
+
 FRR_CFG_DEFAULT_BOOL(BGP_IMPORT_CHECK,
        {
                .val_bool = false,
@@ -268,6 +273,37 @@ static const char *get_afi_safi_json_str(afi_t afi, safi_t safi)
                return "Unknown";
 }
 
+/* return string maps to afi-safi specific container names
+ * defined in bgp yang file.
+ */
+const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi)
+{
+       if (afi == AFI_IP && safi == SAFI_UNICAST)
+               return "ipv4-unicast";
+       else if (afi == AFI_IP && safi == SAFI_MULTICAST)
+               return "ipv4-multicast";
+       else if (afi == AFI_IP && safi == SAFI_LABELED_UNICAST)
+               return "ipv4-labeled-unicast";
+       else if (afi == AFI_IP && safi == SAFI_MPLS_VPN)
+               return "l3vpn-ipv4-unicast";
+       else if (afi == AFI_IP && safi == SAFI_FLOWSPEC)
+               return "ipv4-flowspec";
+       else if (afi == AFI_IP6 && safi == SAFI_UNICAST)
+               return "ipv6-unicast";
+       else if (afi == AFI_IP6 && safi == SAFI_MULTICAST)
+               return "ipv6-multicast";
+       else if (afi == AFI_IP6 && safi == SAFI_LABELED_UNICAST)
+               return "ipv6-labeled-unicast";
+       else if (afi == AFI_IP6 && safi == SAFI_MPLS_VPN)
+               return "l3vpn-ipv6-unicast";
+       else if (afi == AFI_IP6 && safi == SAFI_FLOWSPEC)
+               return "ipv6-flowspec";
+       else if (afi == AFI_L2VPN && safi == SAFI_EVPN)
+               return "l2vpn-evpn";
+       else
+               return "Unknown";
+}
+
 /* Utility function to get address family from current node.  */
 afi_t bgp_node_afi(struct vty *vty)
 {
@@ -751,18 +787,19 @@ enum clear_sort {
        clear_as
 };
 
-static void bgp_clear_vty_error(struct vty *vty, struct peer *peer, afi_t afi,
-                               safi_t safi, int error)
+static void bgp_clear_vty_error(struct peer *peer, afi_t afi, safi_t safi,
+                               int error, char *errmsg, size_t errmsg_len)
 {
        switch (error) {
        case BGP_ERR_AF_UNCONFIGURED:
-               vty_out(vty,
-                       "%%BGP: Enable %s address family for the neighbor %s\n",
-                       get_afi_safi_str(afi, safi, false), peer->host);
+               snprintf(errmsg, errmsg_len,
+                        "%%BGP: Enable %s address family for the neighbor %s",
+                        get_afi_safi_str(afi, safi, false), peer->host);
                break;
        case BGP_ERR_SOFT_RECONFIG_UNCONFIGURED:
-               vty_out(vty,
-                       "%%BGP: Inbound soft reconfig for %s not possible as it\n      has neither refresh capability, nor inbound soft reconfig\n",
+               snprintf(
+                       errmsg, errmsg_len,
+                       "%%BGP: Inbound soft reconfig for %s not possible as it\n      has neither refresh capability, nor inbound soft reconfig",
                        peer->host);
                break;
        default:
@@ -820,9 +857,9 @@ static int bgp_peer_clear(struct peer *peer, afi_t afi, safi_t safi,
 }
 
 /* `clear ip bgp' functions. */
-static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
+static int bgp_clear(struct bgp *bgp, afi_t afi, safi_t safi,
                     enum clear_sort sort, enum bgp_clear_type stype,
-                    const char *arg)
+                    const char *arg, char *errmsg, size_t errmsg_len)
 {
        int ret = 0;
        bool found = false;
@@ -848,7 +885,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                                                          stype);
 
                        if (ret < 0)
-                               bgp_clear_vty_error(vty, peer, afi, safi, ret);
+                               bgp_clear_vty_error(peer, afi, safi, ret,
+                                                   errmsg, errmsg_len);
                }
 
                if (gr_router_detected
@@ -877,8 +915,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        if (!peer) {
                                peer = peer_lookup_by_hostname(bgp, arg);
                                if (!peer) {
-                                       vty_out(vty,
-                                               "Malformed address or name: %s\n",
+                                       snprintf(
+                                               errmsg, errmsg_len,
+                                               "Malformed address or name: %s",
                                                arg);
                                        return CMD_WARNING;
                                }
@@ -886,9 +925,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                } else {
                        peer = peer_lookup(bgp, &su);
                        if (!peer) {
-                               vty_out(vty,
-                                       "%%BGP: Unknown neighbor - \"%s\"\n",
-                                       arg);
+                               snprintf(errmsg, errmsg_len,
+                                        "%%BGP: Unknown neighbor - \"%s\"",
+                                        arg);
                                return CMD_WARNING;
                        }
                }
@@ -903,7 +942,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        ret = BGP_ERR_AF_UNCONFIGURED;
 
                if (ret < 0)
-                       bgp_clear_vty_error(vty, peer, afi, safi, ret);
+                       bgp_clear_vty_error(peer, afi, safi, ret, errmsg,
+                                           errmsg_len);
 
                return CMD_SUCCESS;
        }
@@ -914,7 +954,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
 
                group = peer_group_lookup(bgp, arg);
                if (!group) {
-                       vty_out(vty, "%%BGP: No such peer-group %s\n", arg);
+                       snprintf(errmsg, errmsg_len,
+                                "%%BGP: No such peer-group %s", arg);
                        return CMD_WARNING;
                }
 
@@ -922,14 +963,16 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        ret = bgp_peer_clear(peer, afi, safi, &nnode, stype);
 
                        if (ret < 0)
-                               bgp_clear_vty_error(vty, peer, afi, safi, ret);
+                               bgp_clear_vty_error(peer, afi, safi, ret,
+                                                   errmsg, errmsg_len);
                        else
                                found = true;
                }
 
                if (!found)
-                       vty_out(vty,
-                               "%%BGP: No %s peer belonging to peer-group %s is configured\n",
+                       snprintf(
+                               errmsg, errmsg_len,
+                               "%%BGP: No %s peer belonging to peer-group %s is configured",
                                get_afi_safi_str(afi, safi, false), arg);
 
                return CMD_SUCCESS;
@@ -949,7 +992,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        ret = bgp_peer_clear(peer, afi, safi, &nnode, stype);
 
                        if (ret < 0)
-                               bgp_clear_vty_error(vty, peer, afi, safi, ret);
+                               bgp_clear_vty_error(peer, afi, safi, ret,
+                                                   errmsg, errmsg_len);
                        else
                                found = true;
                }
@@ -963,9 +1007,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                }
 
                if (!found)
-                       vty_out(vty,
-                               "%%BGP: No external %s peer is configured\n",
-                               get_afi_safi_str(afi, safi, false));
+                       snprintf(errmsg, errmsg_len,
+                                "%%BGP: No external %s peer is configured",
+                                get_afi_safi_str(afi, safi, false));
 
                return CMD_SUCCESS;
        }
@@ -986,7 +1030,8 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                        ret = bgp_peer_clear(peer, afi, safi, &nnode, stype);
 
                        if (ret < 0)
-                               bgp_clear_vty_error(vty, peer, afi, safi, ret);
+                               bgp_clear_vty_error(peer, afi, safi, ret,
+                                                   errmsg, errmsg_len);
                        else
                                found = true;
                }
@@ -1000,9 +1045,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
                }
 
                if (!found)
-                       vty_out(vty,
-                               "%%BGP: No %s peer is configured with AS %s\n",
-                               get_afi_safi_str(afi, safi, false), arg);
+                       snprintf(errmsg, errmsg_len,
+                                "%%BGP: No %s peer is configured with AS %s",
+                                get_afi_safi_str(afi, safi, false), arg);
 
                return CMD_SUCCESS;
        }
@@ -1010,9 +1055,9 @@ static int bgp_clear(struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi,
        return CMD_SUCCESS;
 }
 
-static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi,
-                        safi_t safi, enum clear_sort sort,
-                        enum bgp_clear_type stype, const char *arg)
+static int bgp_clear_vty(const char *name, afi_t afi, safi_t safi,
+                        enum clear_sort sort, enum bgp_clear_type stype,
+                        const char *arg, char *errmsg, size_t errmsg_len)
 {
        struct bgp *bgp;
 
@@ -1020,40 +1065,56 @@ static int bgp_clear_vty(struct vty *vty, const char *name, afi_t afi,
        if (name) {
                bgp = bgp_lookup_by_name(name);
                if (bgp == NULL) {
-                       vty_out(vty, "Can't find BGP instance %s\n", name);
+                       snprintf(errmsg, errmsg_len,
+                                "Can't find BGP instance %s", name);
                        return CMD_WARNING;
                }
        } else {
                bgp = bgp_get_default();
                if (bgp == NULL) {
-                       vty_out(vty, "No BGP process is configured\n");
+                       snprintf(errmsg, errmsg_len,
+                                "No BGP process is configured");
                        return CMD_WARNING;
                }
        }
 
-       return bgp_clear(vty, bgp, afi, safi, sort, stype, arg);
+       return bgp_clear(bgp, afi, safi, sort, stype, arg, errmsg, errmsg_len);
 }
 
 /* clear soft inbound */
-static void bgp_clear_star_soft_in(struct vty *vty, const char *name)
+int bgp_clear_star_soft_in(const char *name, char *errmsg, size_t errmsg_len)
 {
        afi_t afi;
        safi_t safi;
+       int ret;
 
-       FOREACH_AFI_SAFI (afi, safi)
-               bgp_clear_vty(vty, name, afi, safi, clear_all,
-                             BGP_CLEAR_SOFT_IN, NULL);
+       FOREACH_AFI_SAFI (afi, safi) {
+               ret = bgp_clear_vty(name, afi, safi, clear_all,
+                                   BGP_CLEAR_SOFT_IN, NULL, errmsg,
+                                   errmsg_len);
+               if (ret != CMD_SUCCESS)
+                       return -1;
+       }
+
+       return 0;
 }
 
 /* clear soft outbound */
-static void bgp_clear_star_soft_out(struct vty *vty, const char *name)
+int bgp_clear_star_soft_out(const char *name, char *errmsg, size_t errmsg_len)
 {
        afi_t afi;
        safi_t safi;
+       int ret;
 
-       FOREACH_AFI_SAFI (afi, safi)
-               bgp_clear_vty(vty, name, afi, safi, clear_all,
-                             BGP_CLEAR_SOFT_OUT, NULL);
+       FOREACH_AFI_SAFI (afi, safi) {
+               ret = bgp_clear_vty(name, afi, safi, clear_all,
+                                   BGP_CLEAR_SOFT_OUT, NULL, errmsg,
+                                   errmsg_len);
+               if (ret != CMD_SUCCESS)
+                       return -1;
+       }
+
+       return 0;
 }
 
 
@@ -1162,23 +1223,21 @@ DEFUN (no_auto_summary,
 }
 
 /* "router bgp" commands. */
-DEFUN_NOSH (router_bgp,
-       router_bgp_cmd,
-       "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]",
-       ROUTER_STR
-       BGP_STR
-       AS_STR
-       BGP_INSTANCE_HELP_STR)
+DEFUN_YANG_NOSH(router_bgp,
+               router_bgp_cmd,
+               "router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]",
+               ROUTER_STR BGP_STR AS_STR BGP_INSTANCE_HELP_STR)
 {
        int idx_asn = 2;
        int idx_view_vrf = 3;
        int idx_vrf = 4;
-       int is_new_bgp = 0;
-       int ret;
+       int ret = CMD_SUCCESS;
        as_t as;
        struct bgp *bgp;
        const char *name = NULL;
+       char as_str[12] = {'\0'};
        enum bgp_instance_type inst_type;
+       char base_xpath[XPATH_MAXLEN];
 
        // "router bgp" without an ASN
        if (argc == 2) {
@@ -1194,12 +1253,38 @@ DEFUN_NOSH (router_bgp,
                        vty_out(vty, "%% Please specify ASN and VRF\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
+
+               snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH,
+                        "frr-bgp:bgp", "bgp", VRF_DEFAULT_NAME);
+
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               snprintf(as_str, 12, "%d", bgp->as);
+               nb_cli_enqueue_change(vty, "./global/local-as", NB_OP_MODIFY,
+                                     as_str);
+               if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW) {
+                       nb_cli_enqueue_change(vty,
+                                             "./global/instance-type-view",
+                                             NB_OP_MODIFY, "true");
+               }
+
+               nb_cli_pending_commit_check(vty);
+               ret = nb_cli_apply_changes(vty, base_xpath);
+               if (ret == CMD_SUCCESS) {
+                       VTY_PUSH_XPATH(BGP_NODE, base_xpath);
+
+                       /*
+                        * For backward compatibility with old commands we still
+                        * need to use the qobj infrastructure.
+                        */
+                       VTY_PUSH_CONTEXT(BGP_NODE, bgp);
+               }
+               return ret;
        }
 
        // "router bgp X"
        else {
-               as = strtoul(argv[idx_asn]->arg, NULL, 10);
 
+               as = strtoul(argv[idx_asn]->arg, NULL, 10);
                inst_type = BGP_INSTANCE_TYPE_DEFAULT;
                if (argc > 3) {
                        name = argv[idx_vrf]->arg;
@@ -1209,70 +1294,63 @@ DEFUN_NOSH (router_bgp,
                                        name = NULL;
                                else
                                        inst_type = BGP_INSTANCE_TYPE_VRF;
-                       } else if (!strcmp(argv[idx_view_vrf]->text, "view"))
+                       } else if (!strcmp(argv[idx_view_vrf]->text, "view")) {
                                inst_type = BGP_INSTANCE_TYPE_VIEW;
+                       }
                }
-
-               if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
-                       is_new_bgp = (bgp_lookup(as, name) == NULL);
-
-               ret = bgp_get_vty(&bgp, &as, name, inst_type);
-               switch (ret) {
-               case BGP_ERR_AS_MISMATCH:
-                       vty_out(vty, "BGP is already running; AS is %u\n", as);
-                       return CMD_WARNING_CONFIG_FAILED;
-               case BGP_ERR_INSTANCE_MISMATCH:
-                       vty_out(vty,
-                               "BGP instance name and AS number mismatch\n");
-                       vty_out(vty,
-                               "BGP instance is already running; AS is %u\n",
-                               as);
-                       return CMD_WARNING_CONFIG_FAILED;
+               snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH,
+                        "frr-bgp:bgp", "bgp", name ? name : VRF_DEFAULT_NAME);
+
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+               nb_cli_enqueue_change(vty, "./global/local-as", NB_OP_MODIFY,
+                                     argv[idx_asn]->arg);
+               if (inst_type == BGP_INSTANCE_TYPE_VIEW) {
+                       nb_cli_enqueue_change(vty,
+                                             "./global/instance-type-view",
+                                             NB_OP_MODIFY, "true");
                }
 
-               /*
-                * If we just instantiated the default instance, complete
-                * any pending VRF-VPN leaking that was configured via
-                * earlier "router bgp X vrf FOO" blocks.
-                */
-               if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
-                       vpn_leak_postchange_all();
+               nb_cli_pending_commit_check(vty);
+               ret = nb_cli_apply_changes(vty, base_xpath);
+               if (ret == CMD_SUCCESS) {
+                       VTY_PUSH_XPATH(BGP_NODE, base_xpath);
 
-               if (inst_type == BGP_INSTANCE_TYPE_VRF)
-                       bgp_vpn_leak_export(bgp);
-               /* Pending: handle when user tries to change a view to vrf n vv.
-                */
+                       /*
+                        * For backward compatibility with old commands we still
+                        * need to use the qobj infrastructure.
+                        */
+                       bgp = bgp_lookup(as, name);
+                       if (bgp)
+                               VTY_PUSH_CONTEXT(BGP_NODE, bgp);
+               }
        }
 
-       /* unset the auto created flag as the user config is now present */
-       UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO);
-       VTY_PUSH_CONTEXT(BGP_NODE, bgp);
-
-       return CMD_SUCCESS;
+       return ret;
 }
 
 /* "no router bgp" commands. */
-DEFUN (no_router_bgp,
-       no_router_bgp_cmd,
-       "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]",
-       NO_STR
-       ROUTER_STR
-       BGP_STR
-       AS_STR
-       BGP_INSTANCE_HELP_STR)
+DEFUN_YANG(no_router_bgp,
+          no_router_bgp_cmd,
+          "no router bgp [(1-4294967295)$instasn [<view|vrf> VIEWVRFNAME]]",
+          NO_STR ROUTER_STR BGP_STR AS_STR BGP_INSTANCE_HELP_STR)
 {
        int idx_asn = 3;
        int idx_vrf = 5;
-       as_t as;
+       as_t as = 0;
        struct bgp *bgp;
        const char *name = NULL;
+       char base_xpath[XPATH_MAXLEN];
+       const struct lyd_node *bgp_glb_dnode;
 
        // "no router bgp" without an ASN
        if (argc == 3) {
                // Pending: Make VRF option available for ASN less config
-               bgp = bgp_get_default();
+               snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH,
+                        "frr-bgp:bgp", "bgp", VRF_DEFAULT_NAME);
 
-               if (bgp == NULL) {
+               bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode,
+                                              base_xpath);
+               if (!bgp_glb_dnode) {
                        vty_out(vty, "%% No BGP process is configured\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
@@ -1282,6 +1360,11 @@ DEFUN (no_router_bgp,
                        return CMD_WARNING_CONFIG_FAILED;
                }
 
+               /* tcli mode bgp would not be set until apply stage. */
+               bgp = nb_running_get_entry(bgp_glb_dnode, NULL, false);
+               if (!bgp)
+                       return CMD_SUCCESS;
+
                if (bgp->l3vni) {
                        vty_out(vty, "%% Please unconfigure l3vni %u",
                                bgp->l3vni);
@@ -1321,94 +1404,94 @@ DEFUN (no_router_bgp,
                        }
                }
        }
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_GLOBAL_XPATH,
+                "frr-bgp:bgp", "bgp",
+                bgp->name ? bgp->name : VRF_DEFAULT_NAME);
 
-       if (bgp_vpn_leak_unimport(bgp, vty))
-               return CMD_WARNING_CONFIG_FAILED;
-
-       bgp_delete(bgp);
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
+void cli_show_router_bgp(struct vty *vty, struct lyd_node *dnode,
+                        bool show_defaults)
+{
+       const struct lyd_node *vrf_dnode;
+       const char *vrf_name;
+       as_t as;
 
-/* BGP router-id.  */
+       vrf_dnode = yang_dnode_get_parent(dnode, "control-plane-protocol");
+       vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf");
+       as = yang_dnode_get_uint32(dnode, "./global/local-as");
 
-DEFPY (bgp_router_id,
-       bgp_router_id_cmd,
-       "bgp router-id A.B.C.D",
-       BGP_STR
-       "Override configured router identifier\n"
-       "Manually configured router identifier\n")
-{
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_router_id_static_set(bgp, router_id);
-       return CMD_SUCCESS;
+       vty_out(vty, "!\n");
+       vty_out(vty, "router bgp %u", as);
+       if (!strmatch(vrf_name, VRF_DEFAULT_NAME))
+               vty_out(vty, " vrf %s", vrf_name);
+       vty_out(vty, "\n");
 }
 
-DEFPY (no_bgp_router_id,
-       no_bgp_router_id_cmd,
-       "no bgp router-id [A.B.C.D]",
-       NO_STR
-       BGP_STR
-       "Override configured router identifier\n"
-       "Manually configured router identifier\n")
+/* BGP router-id.  */
+
+DEFPY_YANG(bgp_router_id, bgp_router_id_cmd, "bgp router-id A.B.C.D",
+          BGP_STR
+          "Override configured router identifier\n"
+          "Manually configured router identifier\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       nb_cli_enqueue_change(vty, "./global/router-id", NB_OP_MODIFY,
+                             router_id_str);
 
-       if (router_id_str) {
-               if (!IPV4_ADDR_SAME(&bgp->router_id_static, &router_id)) {
-                       vty_out(vty, "%% BGP router-id doesn't match\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       router_id.s_addr = 0;
-       bgp_router_id_static_set(bgp, router_id);
+DEFPY_YANG(no_bgp_router_id, no_bgp_router_id_cmd, "no bgp router-id [A.B.C.D]",
+          NO_STR BGP_STR
+          "Override configured router identifier\n"
+          "Manually configured router identifier\n")
+{
+       nb_cli_enqueue_change(vty, "./global/router-id", NB_OP_DESTROY,
+                             router_id_str ? router_id_str : NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
+void cli_show_router_bgp_router_id(struct vty *vty, struct lyd_node *dnode,
+                                  bool show_defaults)
+{
+       vty_out(vty, " bgp router-id %s\n", yang_dnode_get_string(dnode, NULL));
+}
 
 /* BGP Cluster ID.  */
-DEFUN (bgp_cluster_id,
-       bgp_cluster_id_cmd,
-       "bgp cluster-id <A.B.C.D|(1-4294967295)>",
-       BGP_STR
-       "Configure Route-Reflector Cluster-id\n"
-       "Route-Reflector Cluster-id in IP address format\n"
-       "Route-Reflector Cluster-id as 32 bit quantity\n")
+DEFUN_YANG(bgp_cluster_id,
+          bgp_cluster_id_cmd,
+          "bgp cluster-id <A.B.C.D|(1-4294967295)>",
+          BGP_STR
+          "Configure Route-Reflector Cluster-id\n"
+          "Route-Reflector Cluster-id in IP address format\n"
+          "Route-Reflector Cluster-id as 32 bit quantity\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_ipv4 = 2;
-       int ret;
-       struct in_addr cluster;
-
-       ret = inet_aton(argv[idx_ipv4]->arg, &cluster);
-       if (!ret) {
-               vty_out(vty, "%% Malformed bgp cluster identifier\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
 
-       bgp_cluster_id_set(bgp, &cluster);
-       bgp_clear_star_soft_out(vty, bgp->name);
+       nb_cli_enqueue_change(
+               vty, "./global/route-reflector/route-reflector-cluster-id",
+               NB_OP_MODIFY, argv[idx_ipv4]->arg);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_cluster_id,
-       no_bgp_cluster_id_cmd,
-       "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]",
-       NO_STR
-       BGP_STR
-       "Configure Route-Reflector Cluster-id\n"
-       "Route-Reflector Cluster-id in IP address format\n"
-       "Route-Reflector Cluster-id as 32 bit quantity\n")
+DEFUN_YANG(no_bgp_cluster_id,
+          no_bgp_cluster_id_cmd,
+          "no bgp cluster-id [<A.B.C.D|(1-4294967295)>]",
+          NO_STR BGP_STR
+          "Configure Route-Reflector Cluster-id\n"
+          "Route-Reflector Cluster-id in IP address format\n"
+          "Route-Reflector Cluster-id as 32 bit quantity\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_cluster_id_unset(bgp);
-       bgp_clear_star_soft_out(vty, bgp->name);
+       nb_cli_enqueue_change(
+               vty, "./global/route-reflector/route-reflector-cluster-id",
+               NB_OP_DESTROY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 DEFPY (bgp_norib,
@@ -1446,87 +1529,86 @@ DEFPY (no_bgp_norib,
        return CMD_SUCCESS;
 }
 
-DEFUN (bgp_confederation_identifier,
-       bgp_confederation_identifier_cmd,
-       "bgp confederation identifier (1-4294967295)",
-       "BGP specific commands\n"
-       "AS confederation parameters\n"
-       "AS number\n"
-       "Set routing domain confederation AS\n")
+DEFUN_YANG(bgp_confederation_identifier,
+          bgp_confederation_identifier_cmd,
+          "bgp confederation identifier (1-4294967295)",
+          "BGP specific commands\n"
+          "AS confederation parameters\n"
+          "AS number\n"
+          "Set routing domain confederation AS\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 3;
-       as_t as;
 
-       as = strtoul(argv[idx_number]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty, "./global/confederation/identifier",
+                             NB_OP_MODIFY, argv[idx_number]->arg);
 
-       bgp_confederation_id_set(bgp, as);
-
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_confederation_identifier,
-       no_bgp_confederation_identifier_cmd,
-       "no bgp confederation identifier [(1-4294967295)]",
-       NO_STR
-       "BGP specific commands\n"
-       "AS confederation parameters\n"
-       "AS number\n"
-       "Set routing domain confederation AS\n")
+DEFUN_YANG(no_bgp_confederation_identifier,
+          no_bgp_confederation_identifier_cmd,
+          "no bgp confederation identifier [(1-4294967295)]",
+          NO_STR
+          "BGP specific commands\n"
+          "AS confederation parameters\n"
+          "AS number\n"
+          "Set routing domain confederation AS\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_confederation_id_unset(bgp);
+       nb_cli_enqueue_change(vty, "./global/confederation/identifier",
+                             NB_OP_DESTROY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (bgp_confederation_peers,
-       bgp_confederation_peers_cmd,
-       "bgp confederation peers (1-4294967295)...",
-       "BGP specific commands\n"
-       "AS confederation parameters\n"
-       "Peer ASs in BGP confederation\n"
-       AS_STR)
+void cli_show_router_bgp_confederation_identifier(struct vty *vty,
+                                                 struct lyd_node *dnode,
+                                                 bool show_defaults)
+{
+       vty_out(vty, " bgp confederation identifier %u\n",
+               yang_dnode_get_uint32(dnode, NULL));
+}
+
+DEFUN_YANG(bgp_confederation_peers,
+          bgp_confederation_peers_cmd,
+          "bgp confederation peers (1-4294967295)...",
+          "BGP specific commands\n"
+          "AS confederation parameters\n"
+          "Peer ASs in BGP confederation\n" AS_STR)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_asn = 3;
-       as_t as;
        int i;
 
-       for (i = idx_asn; i < argc; i++) {
-               as = strtoul(argv[i]->arg, NULL, 10);
-
-               if (bgp->as == as) {
-                       vty_out(vty,
-                               "%% Local member-AS not allowed in confed peer list\n");
-                       continue;
-               }
+       for (i = idx_asn; i < argc; i++)
+               nb_cli_enqueue_change(vty, "./global/confederation/member-as",
+                                     NB_OP_CREATE, argv[i]->arg);
 
-               bgp_confederation_peers_add(bgp, as);
-       }
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_confederation_peers,
-       no_bgp_confederation_peers_cmd,
-       "no bgp confederation peers (1-4294967295)...",
-       NO_STR
-       "BGP specific commands\n"
-       "AS confederation parameters\n"
-       "Peer ASs in BGP confederation\n"
-       AS_STR)
+DEFUN_YANG(no_bgp_confederation_peers,
+          no_bgp_confederation_peers_cmd,
+          "no bgp confederation peers (1-4294967295)...",
+          NO_STR
+          "BGP specific commands\n"
+          "AS confederation parameters\n"
+          "Peer ASs in BGP confederation\n" AS_STR)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_asn = 4;
-       as_t as;
        int i;
 
-       for (i = idx_asn; i < argc; i++) {
-               as = strtoul(argv[i]->arg, NULL, 10);
+       for (i = idx_asn; i < argc; i++)
+               nb_cli_enqueue_change(vty, "./global/confederation/member-as",
+                                     NB_OP_DESTROY, argv[i]->arg);
 
-               bgp_confederation_peers_remove(bgp, as);
-       }
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_bgp_confederation_member_as(struct vty *vty,
+                                                struct lyd_node *dnode,
+                                                bool show_defaults)
+{
+       vty_out(vty, " bgp confederation peers %u \n",
+               yang_dnode_get_uint32(dnode, NULL));
 }
 
 /**
@@ -1534,23 +1616,16 @@ DEFUN (no_bgp_confederation_peers,
  * @peer_type: BGP_PEER_EBGP or BGP_PEER_IBGP
  * @set: 1 for setting values, 0 for removing the max-paths config.
  */
-static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type,
-                                  const char *mpaths, uint16_t options,
-                                  int set)
+int bgp_maxpaths_config_vty(struct bgp *bgp, afi_t afi, safi_t safi,
+                           int peer_type, uint16_t maxpaths, uint16_t options,
+                           int set, char *errmsg, size_t errmsg_len)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       uint16_t maxpaths = 0;
        int ret;
-       afi_t afi;
-       safi_t safi;
-
-       afi = bgp_node_afi(vty);
-       safi = bgp_node_safi(vty);
 
        if (set) {
-               maxpaths = strtol(mpaths, NULL, 10);
                if (maxpaths > multipath_num) {
-                       vty_out(vty,
+                       snprintf(
+                               errmsg, errmsg_len,
                                "%% Maxpaths Specified: %d is > than multipath num specified on bgp command line %d",
                                maxpaths, multipath_num);
                        return CMD_WARNING_CONFIG_FAILED;
@@ -1561,7 +1636,8 @@ static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type,
                ret = bgp_maximum_paths_unset(bgp, afi, safi, peer_type);
 
        if (ret < 0) {
-               vty_out(vty,
+               snprintf(
+                       errmsg, errmsg_len,
                        "%% Failed to %sset maximum-paths %s %u for afi %u, safi %u\n",
                        (set == 1) ? "" : "un",
                        (peer_type == BGP_PEER_EBGP) ? "ebgp" : "ibgp",
@@ -1574,107 +1650,130 @@ static int bgp_maxpaths_config_vty(struct vty *vty, int peer_type,
        return CMD_SUCCESS;
 }
 
-DEFUN (bgp_maxmed_admin,
-       bgp_maxmed_admin_cmd,
-       "bgp max-med administrative ",
-       BGP_STR
-       "Advertise routes with max-med\n"
-       "Administratively applied, for an indefinite period\n")
+void cli_show_router_bgp_med_config(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       if (yang_dnode_get_bool(dnode, "./enable-med-admin")) {
+               uint32_t med_admin_val;
 
-       bgp->v_maxmed_admin = 1;
-       bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT;
+               vty_out(vty, " bgp max-med administrative");
+               if ((med_admin_val =
+                            yang_dnode_get_uint32(dnode, "./max-med-admin"))
+                   != BGP_MAXMED_VALUE_DEFAULT)
+                       vty_out(vty, " %u", med_admin_val);
+               vty_out(vty, "\n");
+       }
 
-       bgp_maxmed_update(bgp);
+       if (yang_dnode_exists(dnode, "./max-med-onstart-up-time")) {
+               uint32_t onstartup_val;
 
-       return CMD_SUCCESS;
+               vty_out(vty, " bgp max-med on-startup %u",
+                       yang_dnode_get_uint32(dnode,
+                                             "./max-med-onstart-up-time"));
+               onstartup_val = yang_dnode_get_uint32(
+                       dnode, "./max-med-onstart-up-value");
+               if (onstartup_val != BGP_MAXMED_VALUE_DEFAULT)
+                       vty_out(vty, " %u", onstartup_val);
+
+               vty_out(vty, "\n");
+       }
 }
 
-DEFUN (bgp_maxmed_admin_medv,
-       bgp_maxmed_admin_medv_cmd,
-       "bgp max-med administrative (0-4294967295)",
-       BGP_STR
-       "Advertise routes with max-med\n"
-       "Administratively applied, for an indefinite period\n"
-       "Max MED value to be used\n")
+DEFUN_YANG(bgp_maxmed_admin,
+          bgp_maxmed_admin_cmd,
+          "bgp max-med administrative ",
+          BGP_STR
+          "Advertise routes with max-med\n"
+          "Administratively applied, for an indefinite period\n")
+{
+       nb_cli_enqueue_change(vty, "./global/med-config/enable-med-admin",
+                             NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG(bgp_maxmed_admin_medv,
+          bgp_maxmed_admin_medv_cmd,
+          "bgp max-med administrative (0-4294967295)",
+          BGP_STR
+          "Advertise routes with max-med\n"
+          "Administratively applied, for an indefinite period\n"
+          "Max MED value to be used\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 3;
 
-       bgp->v_maxmed_admin = 1;
-       bgp->maxmed_admin_value = strtoul(argv[idx_number]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty, "./global/med-config/enable-med-admin",
+                             NB_OP_MODIFY, "true");
 
-       bgp_maxmed_update(bgp);
+       nb_cli_enqueue_change(vty, "./global/med-config/max-med-admin",
+                             NB_OP_MODIFY, argv[idx_number]->arg);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_maxmed_admin,
-       no_bgp_maxmed_admin_cmd,
-       "no bgp max-med administrative [(0-4294967295)]",
-       NO_STR
-       BGP_STR
-       "Advertise routes with max-med\n"
-       "Administratively applied, for an indefinite period\n"
-       "Max MED value to be used\n")
+DEFUN_YANG(no_bgp_maxmed_admin,
+          no_bgp_maxmed_admin_cmd,
+          "no bgp max-med administrative [(0-4294967295)]",
+          NO_STR BGP_STR
+          "Advertise routes with max-med\n"
+          "Administratively applied, for an indefinite period\n"
+          "Max MED value to be used\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp->v_maxmed_admin = BGP_MAXMED_ADMIN_UNCONFIGURED;
-       bgp->maxmed_admin_value = BGP_MAXMED_VALUE_DEFAULT;
-       bgp_maxmed_update(bgp);
+       nb_cli_enqueue_change(vty, "./global/med-config/enable-med-admin",
+                             NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/med-config/max-med-admin",
+                             NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (bgp_maxmed_onstartup,
-       bgp_maxmed_onstartup_cmd,
-       "bgp max-med on-startup (5-86400) [(0-4294967295)]",
-       BGP_STR
-       "Advertise routes with max-med\n"
-       "Effective on a startup\n"
-       "Time (seconds) period for max-med\n"
-       "Max MED value to be used\n")
+DEFUN_YANG (bgp_maxmed_onstartup,
+           bgp_maxmed_onstartup_cmd,
+           "bgp max-med on-startup (5-86400) [(0-4294967295)]",
+           BGP_STR
+           "Advertise routes with max-med\n"
+           "Effective on a startup\n"
+           "Time (seconds) period for max-med\n"
+           "Max MED value to be used\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx = 0;
 
        argv_find(argv, argc, "(5-86400)", &idx);
-       bgp->v_maxmed_onstartup = strtoul(argv[idx]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty,
+                             "./global/med-config/max-med-onstart-up-time",
+                             NB_OP_MODIFY, argv[idx]->arg);
+
        if (argv_find(argv, argc, "(0-4294967295)", &idx))
-               bgp->maxmed_onstartup_value = strtoul(argv[idx]->arg, NULL, 10);
+               nb_cli_enqueue_change(
+                       vty, "./global/med-config/max-med-onstart-up-value",
+                       NB_OP_MODIFY, argv[idx]->arg);
        else
-               bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT;
+               nb_cli_enqueue_change(
+                       vty, "./global/med-config/max-med-onstart-up-value",
+                       NB_OP_MODIFY, NULL);
 
-       bgp_maxmed_update(bgp);
-
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_maxmed_onstartup,
-       no_bgp_maxmed_onstartup_cmd,
-       "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]",
-       NO_STR
-       BGP_STR
-       "Advertise routes with max-med\n"
-       "Effective on a startup\n"
-       "Time (seconds) period for max-med\n"
-       "Max MED value to be used\n")
+DEFUN_YANG (no_bgp_maxmed_onstartup,
+           no_bgp_maxmed_onstartup_cmd,
+           "no bgp max-med on-startup [(5-86400) [(0-4294967295)]]",
+           NO_STR BGP_STR
+           "Advertise routes with max-med\n"
+           "Effective on a startup\n"
+           "Time (seconds) period for max-med\n"
+           "Max MED value to be used\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       nb_cli_enqueue_change(vty,
+                             "./global/med-config/max-med-onstart-up-time",
+                             NB_OP_DESTROY, NULL);
 
-       /* Cancel max-med onstartup if its on */
-       if (bgp->t_maxmed_onstartup) {
-               THREAD_TIMER_OFF(bgp->t_maxmed_onstartup);
-               bgp->maxmed_onstartup_over = 1;
-       }
-
-       bgp->v_maxmed_onstartup = BGP_MAXMED_ONSTARTUP_UNCONFIGURED;
-       bgp->maxmed_onstartup_value = BGP_MAXMED_VALUE_DEFAULT;
+       nb_cli_enqueue_change(vty,
+                             "./global/med-config/max-med-onstart-up-value",
+                             NB_OP_MODIFY, NULL);
 
-       bgp_maxmed_update(bgp);
-
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 static int bgp_global_update_delay_config_vty(struct vty *vty,
@@ -1858,22 +1957,16 @@ DEFPY (no_bgp_update_delay,
 }
 
 
-static int bgp_wpkt_quanta_config_vty(struct vty *vty, uint32_t quanta,
-                                     bool set)
+int bgp_wpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-
        quanta = set ? quanta : BGP_WRITE_PACKET_MAX;
        atomic_store_explicit(&bgp->wpkt_quanta, quanta, memory_order_relaxed);
 
        return CMD_SUCCESS;
 }
 
-static int bgp_rpkt_quanta_config_vty(struct vty *vty, uint32_t quanta,
-                                     bool set)
+int bgp_rpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-
        quanta = set ? quanta : BGP_READ_PACKET_MAX;
        atomic_store_explicit(&bgp->rpkt_quanta, quanta, memory_order_relaxed);
 
@@ -1904,24 +1997,46 @@ void bgp_config_write_rpkt_quanta(struct vty *vty, struct bgp *bgp)
  * Furthermore, the maximums used here should correspond to
  * BGP_WRITE_PACKET_MAX and BGP_READ_PACKET_MAX.
  */
-DEFPY (bgp_wpkt_quanta,
-       bgp_wpkt_quanta_cmd,
-       "[no] write-quanta (1-64)$quanta",
-       NO_STR
-       "How many packets to write to peer socket per run\n"
-       "Number of packets\n")
-{
-       return bgp_wpkt_quanta_config_vty(vty, quanta, !no);
-}
+DEFPY_YANG (bgp_wpkt_quanta,
+           bgp_wpkt_quanta_cmd,
+           "[no] write-quanta (1-64)$quanta",
+           NO_STR
+           "How many packets to write to peer socket per run\n"
+           "Number of packets\n")
+{
+       if (!no)
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/global-neighbor-config/packet-quanta-config/wpkt-quanta",
+                       NB_OP_MODIFY, quanta_str);
+       else
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/global-neighbor-config/packet-quanta-config/wpkt-quanta",
+                       NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFPY_YANG (bgp_rpkt_quanta,
+           bgp_rpkt_quanta_cmd,
+           "[no] read-quanta (1-10)$quanta",
+           NO_STR
+           "How many packets to read from peer socket per I/O cycle\n"
+           "Number of packets\n")
+{
+       if (!no)
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/global-neighbor-config/packet-quanta-config/rpkt-quanta",
+                       NB_OP_MODIFY, quanta_str);
+       else
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/global-neighbor-config/packet-quanta-config/rpkt-quanta",
+                       NB_OP_MODIFY, NULL);
 
-DEFPY (bgp_rpkt_quanta,
-       bgp_rpkt_quanta_cmd,
-       "[no] read-quanta (1-10)$quanta",
-       NO_STR
-       "How many packets to read from peer socket per I/O cycle\n"
-       "Number of packets\n")
-{
-       return bgp_rpkt_quanta_config_vty(vty, quanta, !no);
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
@@ -1930,46 +2045,75 @@ void bgp_config_write_coalesce_time(struct vty *vty, struct bgp *bgp)
                vty_out(vty, " coalesce-time %u\n", bgp->coalesce_time);
 }
 
-
-DEFUN (bgp_coalesce_time,
-       bgp_coalesce_time_cmd,
-       "coalesce-time (0-4294967295)",
-       "Subgroup coalesce timer\n"
-       "Subgroup coalesce timer value (in ms)\n")
+void cli_show_router_global_update_group_config_coalesce_time(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       vty_out(vty, " coalesce-time %u\n", yang_dnode_get_uint32(dnode, NULL));
+}
 
+
+DEFUN_YANG (bgp_coalesce_time,
+           bgp_coalesce_time_cmd,
+           "coalesce-time (0-4294967295)",
+           "Subgroup coalesce timer\n"
+           "Subgroup coalesce timer value (in ms)\n")
+{
        int idx = 0;
+
        argv_find(argv, argc, "(0-4294967295)", &idx);
-       bgp->heuristic_coalesce = false;
-       bgp->coalesce_time = strtoul(argv[idx]->arg, NULL, 10);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(
+               vty, "./global/global-update-group-config/coalesce-time",
+               NB_OP_MODIFY, argv[idx]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_coalesce_time,
-       no_bgp_coalesce_time_cmd,
-       "no coalesce-time (0-4294967295)",
-       NO_STR
-       "Subgroup coalesce timer\n"
-       "Subgroup coalesce timer value (in ms)\n")
+DEFUN_YANG(no_bgp_coalesce_time,
+          no_bgp_coalesce_time_cmd,
+          "no coalesce-time (0-4294967295)",
+          NO_STR
+          "Subgroup coalesce timer\n"
+          "Subgroup coalesce timer value (in ms)\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/global-update-group-config/coalesce-time",
+               NB_OP_MODIFY, NULL);
 
-       bgp->heuristic_coalesce = true;
-       bgp->coalesce_time = BGP_DEFAULT_SUBGROUP_COALESCE_TIME;
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* Maximum-paths configuration */
-DEFUN (bgp_maxpaths,
-       bgp_maxpaths_cmd,
-       "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
-       "Forward packets over multiple paths\n"
-       "Number of paths\n")
+DEFUN_YANG (bgp_maxpaths,
+           bgp_maxpaths_cmd,
+           "maximum-paths " CMD_RANGE_STR(1, MULTIPATH_NUM),
+           "Forward packets over multiple paths\n"
+           "Number of paths\n")
 {
        int idx_number = 1;
-       return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP,
-                                      argv[idx_number]->arg, 0, 1);
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_bgp_global_afi_safi_unicast_use_multiple_paths_ebgp_maximum_paths(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       vty_out(vty, "  maximum-paths %d\n",
+               yang_dnode_get_uint16(dnode, NULL));
 }
 
 ALIAS_HIDDEN(bgp_maxpaths, bgp_maxpaths_hidden_cmd,
@@ -1977,16 +2121,31 @@ ALIAS_HIDDEN(bgp_maxpaths, bgp_maxpaths_hidden_cmd,
             "Forward packets over multiple paths\n"
             "Number of paths\n")
 
-DEFUN (bgp_maxpaths_ibgp,
-       bgp_maxpaths_ibgp_cmd,
-       "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM),
-       "Forward packets over multiple paths\n"
-       "iBGP-multipath\n"
-       "Number of paths\n")
+DEFUN_YANG (bgp_maxpaths_ibgp,
+           bgp_maxpaths_ibgp_cmd,
+           "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM),
+           "Forward packets over multiple paths\n"
+           "iBGP-multipath\n"
+           "Number of paths\n")
 {
        int idx_number = 2;
-       return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP,
-                                      argv[idx_number]->arg, 0, 1);
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 ALIAS_HIDDEN(bgp_maxpaths_ibgp, bgp_maxpaths_ibgp_hidden_cmd,
@@ -1995,18 +2154,50 @@ ALIAS_HIDDEN(bgp_maxpaths_ibgp, bgp_maxpaths_ibgp_hidden_cmd,
             "iBGP-multipath\n"
             "Number of paths\n")
 
-DEFUN (bgp_maxpaths_ibgp_cluster,
-       bgp_maxpaths_ibgp_cluster_cmd,
-       "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length",
-       "Forward packets over multiple paths\n"
-       "iBGP-multipath\n"
-       "Number of paths\n"
-       "Match the cluster length\n")
+DEFUN_YANG (bgp_maxpaths_ibgp_cluster,
+           bgp_maxpaths_ibgp_cluster_cmd,
+           "maximum-paths ibgp " CMD_RANGE_STR(1, MULTIPATH_NUM) " equal-cluster-length",
+           "Forward packets over multiple paths\n"
+           "iBGP-multipath\n"
+           "Number of paths\n"
+           "Match the cluster length\n")
 {
        int idx_number = 2;
-       return bgp_maxpaths_config_vty(
-               vty, BGP_PEER_IBGP, argv[idx_number]->arg,
-               BGP_FLAG_IBGP_MULTIPATH_SAME_CLUSTERLEN, 1);
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY,
+                             argv[idx_number]->arg);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/cluster-length-list",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       vty_out(vty, "  maximum-paths ibgp %d",
+               yang_dnode_get_uint16(dnode, "./maximum-paths"));
+       if (yang_dnode_get_bool(dnode, "./cluster-length-list"))
+               vty_out(vty, " equal-cluster-length");
+       vty_out(vty, "\n");
 }
 
 ALIAS_HIDDEN(bgp_maxpaths_ibgp_cluster, bgp_maxpaths_ibgp_cluster_hidden_cmd,
@@ -2017,14 +2208,29 @@ ALIAS_HIDDEN(bgp_maxpaths_ibgp_cluster, bgp_maxpaths_ibgp_cluster_hidden_cmd,
             "Number of paths\n"
             "Match the cluster length\n")
 
-DEFUN (no_bgp_maxpaths,
-       no_bgp_maxpaths_cmd,
-       "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]",
-       NO_STR
-       "Forward packets over multiple paths\n"
-       "Number of paths\n")
+DEFUN_YANG (no_bgp_maxpaths,
+           no_bgp_maxpaths_cmd,
+           "no maximum-paths [" CMD_RANGE_STR(1, MULTIPATH_NUM) "]",
+           NO_STR
+           "Forward packets over multiple paths\n"
+           "Number of paths\n")
 {
-       return bgp_maxpaths_config_vty(vty, BGP_PEER_EBGP, NULL, 0, 0);
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ebgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd,
@@ -2032,16 +2238,39 @@ ALIAS_HIDDEN(no_bgp_maxpaths, no_bgp_maxpaths_hidden_cmd,
             "Forward packets over multiple paths\n"
             "Number of paths\n")
 
-DEFUN (no_bgp_maxpaths_ibgp,
-       no_bgp_maxpaths_ibgp_cmd,
-       "no maximum-paths ibgp [" CMD_RANGE_STR(1, MULTIPATH_NUM) " [equal-cluster-length]]",
-       NO_STR
-       "Forward packets over multiple paths\n"
-       "iBGP-multipath\n"
-       "Number of paths\n"
-       "Match the cluster length\n")
+DEFUN_YANG (no_bgp_maxpaths_ibgp,
+           no_bgp_maxpaths_ibgp_cmd,
+           "no maximum-paths ibgp [" CMD_RANGE_STR(1, MULTIPATH_NUM) " [equal-cluster-length]]",
+           NO_STR
+           "Forward packets over multiple paths\n"
+           "iBGP-multipath\n"
+           "Number of paths\n"
+           "Match the cluster length\n")
 {
-       return bgp_maxpaths_config_vty(vty, BGP_PEER_IBGP, NULL, 0, 0);
+       char base_xpath[XPATH_MAXLEN];
+       afi_t afi;
+       safi_t safi;
+
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/maximum-paths",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, NULL);
+
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/use-multiple-paths/ibgp/cluster-length-list",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       nb_cli_enqueue_change(vty, base_xpath, NB_OP_MODIFY, "false");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 ALIAS_HIDDEN(no_bgp_maxpaths_ibgp, no_bgp_maxpaths_ibgp_hidden_cmd,
@@ -2073,129 +2302,181 @@ static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp,
 
 /* BGP timers.  */
 
-DEFUN (bgp_timers,
-       bgp_timers_cmd,
-       "timers bgp (0-65535) (0-65535)",
-       "Adjust routing timers\n"
-       "BGP timers\n"
-       "Keepalive interval\n"
-       "Holdtime\n")
+DEFUN_YANG (bgp_timers,
+           bgp_timers_cmd,
+           "timers bgp (0-65535) (0-65535)",
+           "Adjust routing timers\n"
+           "BGP timers\n"
+           "Keepalive interval\n"
+           "Holdtime\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 2;
        int idx_number_2 = 3;
-       unsigned long keepalive = 0;
-       unsigned long holdtime = 0;
 
-       keepalive = strtoul(argv[idx_number]->arg, NULL, 10);
-       holdtime = strtoul(argv[idx_number_2]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty, "./global/global-config-timers/keepalive",
+                             NB_OP_MODIFY, argv[idx_number]->arg);
+       nb_cli_enqueue_change(vty, "./global/global-config-timers/hold-time",
+                             NB_OP_MODIFY, argv[idx_number_2]->arg);
 
-       /* Holdtime value check. */
-       if (holdtime < 3 && holdtime != 0) {
-               vty_out(vty,
-                       "%% hold time value must be either 0 or greater than 3\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       bgp_timers_set(bgp, keepalive, holdtime, DFLT_BGP_CONNECT_RETRY);
+DEFUN_YANG (no_bgp_timers,
+           no_bgp_timers_cmd,
+           "no timers bgp [(0-65535) (0-65535)]",
+           NO_STR
+           "Adjust routing timers\n"
+           "BGP timers\n"
+           "Keepalive interval\n"
+           "Holdtime\n")
+{
+       nb_cli_enqueue_change(vty, "./global/global-config-timers/keepalive",
+                             NB_OP_DESTROY, NULL);
+       nb_cli_enqueue_change(vty, "./global/global-config-timers/hold-time",
+                             NB_OP_DESTROY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_timers,
-       no_bgp_timers_cmd,
-       "no timers bgp [(0-65535) (0-65535)]",
-       NO_STR
-       "Adjust routing timers\n"
-       "BGP timers\n"
-       "Keepalive interval\n"
-       "Holdtime\n")
+void cli_show_router_bgp_route_reflector(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_timers_set(bgp, DFLT_BGP_KEEPALIVE, DFLT_BGP_HOLDTIME,
-                      DFLT_BGP_CONNECT_RETRY);
+       if (yang_dnode_get_bool(dnode, "./no-client-reflect"))
+               vty_out(vty, " no bgp client-to-client reflection\n");
 
-       return CMD_SUCCESS;
+       if (yang_dnode_get_bool(dnode, "./allow-outbound-policy"))
+               vty_out(vty, " bgp route-reflector allow-outbound-policy\n");
+
+       if (yang_dnode_exists(dnode, "./route-reflector-cluster-id"))
+               vty_out(vty, " bgp cluster-id %s\n",
+                       yang_dnode_get_string(dnode,
+                                             "./route-reflector-cluster-id"));
 }
 
+DEFUN_YANG(bgp_client_to_client_reflection,
+          bgp_client_to_client_reflection_cmd,
+          "bgp client-to-client reflection",
+          "BGP specific commands\n"
+          "Configure client to client route reflection\n"
+          "reflection of routes allowed\n")
+{
+       nb_cli_enqueue_change(vty, "./global/route-reflector/no-client-reflect",
+                             NB_OP_MODIFY, "false");
 
-DEFUN (bgp_client_to_client_reflection,
-       bgp_client_to_client_reflection_cmd,
-       "bgp client-to-client reflection",
-       "BGP specific commands\n"
-       "Configure client to client route reflection\n"
-       "reflection of routes allowed\n")
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+DEFUN_YANG(no_bgp_client_to_client_reflection,
+          no_bgp_client_to_client_reflection_cmd,
+          "no bgp client-to-client reflection",
+          NO_STR
+          "BGP specific commands\n"
+          "Configure client to client route reflection\n"
+          "reflection of routes allowed\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT);
-       bgp_clear_star_soft_out(vty, bgp->name);
+       nb_cli_enqueue_change(vty, "./global/route-reflector/no-client-reflect",
+                             NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_client_to_client_reflection,
-       no_bgp_client_to_client_reflection_cmd,
-       "no bgp client-to-client reflection",
-       NO_STR
-       "BGP specific commands\n"
-       "Configure client to client route reflection\n"
-       "reflection of routes allowed\n")
+void cli_show_router_bgp_route_selection(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_NO_CLIENT_TO_CLIENT);
-       bgp_clear_star_soft_out(vty, bgp->name);
 
-       return CMD_SUCCESS;
+       if (yang_dnode_get_bool(dnode, "./always-compare-med"))
+               vty_out(vty, " bgp always-compare-med\n");
+
+       if (yang_dnode_get_bool(dnode, "./ignore-as-path-length"))
+               vty_out(vty, " bgp bestpath as-path ignore\n");
+
+       if (yang_dnode_get_bool(dnode, "./aspath-confed"))
+               vty_out(vty, " bgp bestpath as-path confed\n");
+
+       if (yang_dnode_get_bool(dnode, "./external-compare-router-id"))
+               vty_out(vty, " bgp bestpath compare-routerid\n");
+
+       if (yang_dnode_get_bool(dnode, "./allow-multiple-as")) {
+               if (yang_dnode_get_bool(dnode, "./multi-path-as-set"))
+                       vty_out(vty,
+                               " bgp bestpath as-path multipath-relax as-set\n");
+               else
+                       vty_out(vty, " bgp bestpath as-path multipath-relax\n");
+       }
+
+       if (yang_dnode_get_bool(dnode, "./deterministic-med"))
+               vty_out(vty, " bgp deterministic-med\n");
+
+       if (yang_dnode_get_bool(dnode, "./confed-med")
+           || yang_dnode_get_bool(dnode, "./missing-as-worst-med")) {
+               vty_out(vty, " bgp bestpath med");
+               if (yang_dnode_get_bool(dnode, "./confed-med"))
+                       vty_out(vty, " confed");
+               if (yang_dnode_get_bool(dnode, "./missing-as-worst-med"))
+                       vty_out(vty, " missing-as-worst");
+               vty_out(vty, "\n");
+       }
 }
 
 /* "bgp always-compare-med" configuration. */
-DEFUN (bgp_always_compare_med,
-       bgp_always_compare_med_cmd,
-       "bgp always-compare-med",
-       "BGP specific commands\n"
-       "Allow comparing MED from different neighbors\n")
+DEFUN_YANG(bgp_always_compare_med,
+          bgp_always_compare_med_cmd,
+          "bgp always-compare-med",
+          "BGP specific commands\n"
+          "Allow comparing MED from different neighbors\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/always-compare-med",
+               NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_always_compare_med,
-       no_bgp_always_compare_med_cmd,
-       "no bgp always-compare-med",
-       NO_STR
-       "BGP specific commands\n"
-       "Allow comparing MED from different neighbors\n")
+DEFUN_YANG(no_bgp_always_compare_med,
+          no_bgp_always_compare_med_cmd,
+          "no bgp always-compare-med",
+          NO_STR
+          "BGP specific commands\n"
+          "Allow comparing MED from different neighbors\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_ALWAYS_COMPARE_MED);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/always-compare-med",
+               NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
+DEFUN_YANG(bgp_ebgp_requires_policy,
+          bgp_ebgp_requires_policy_cmd,
+          "bgp ebgp-requires-policy",
+          "BGP specific commands\n"
+          "Require in and out policy for eBGP peers (RFC8212)\n")
+{
+       nb_cli_enqueue_change(vty, "./global/ebgp-requires-policy",
+                             NB_OP_MODIFY, "true");
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-DEFUN(bgp_ebgp_requires_policy, bgp_ebgp_requires_policy_cmd,
-      "bgp ebgp-requires-policy",
-      "BGP specific commands\n"
-      "Require in and out policy for eBGP peers (RFC8212)\n")
+DEFUN_YANG(no_bgp_ebgp_requires_policy,
+          no_bgp_ebgp_requires_policy_cmd,
+          "no bgp ebgp-requires-policy",
+          NO_STR
+          "BGP specific commands\n"
+          "Require in and out policy for eBGP peers (RFC8212)\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/ebgp-requires-policy",
+                             NB_OP_MODIFY, "false");
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN(no_bgp_ebgp_requires_policy, no_bgp_ebgp_requires_policy_cmd,
-      "no bgp ebgp-requires-policy",
-      NO_STR
-      "BGP specific commands\n"
-      "Require in and out policy for eBGP peers (RFC8212)\n")
+void cli_show_router_bgp_ebgp_requires_policy(struct vty *vty,
+                                             struct lyd_node *dnode,
+                                             bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_EBGP_REQUIRES_POLICY);
-       return CMD_SUCCESS;
+       if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_EBGP_REQUIRES_POLICY)
+               vty_out(vty, " bgp ebgp-requires-policy\n");
 }
 
 DEFUN(bgp_reject_as_sets, bgp_reject_as_sets_cmd,
@@ -2250,62 +2531,31 @@ DEFUN(no_bgp_reject_as_sets, no_bgp_reject_as_sets_cmd,
 }
 
 /* "bgp deterministic-med" configuration. */
-DEFUN (bgp_deterministic_med,
+DEFUN_YANG (bgp_deterministic_med,
        bgp_deterministic_med_cmd,
        "bgp deterministic-med",
        "BGP specific commands\n"
        "Pick the best-MED path among paths advertised from the neighboring AS\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-
-       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
-               SET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED);
-               bgp_recalculate_all_bestpaths(bgp);
-       }
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/deterministic-med",
+               NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_deterministic_med,
+DEFUN_YANG (no_bgp_deterministic_med,
        no_bgp_deterministic_med_cmd,
        "no bgp deterministic-med",
        NO_STR
        "BGP specific commands\n"
        "Pick the best-MED path among paths advertised from the neighboring AS\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int bestpath_per_as_used;
-       afi_t afi;
-       safi_t safi;
-       struct peer *peer;
-       struct listnode *node, *nnode;
-
-       if (CHECK_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED)) {
-               bestpath_per_as_used = 0;
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/deterministic-med",
+               NB_OP_MODIFY, "false");
 
-               for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) {
-                       FOREACH_AFI_SAFI (afi, safi)
-                               if (bgp_addpath_dmed_required(
-                                       peer->addpath_type[afi][safi])) {
-                                       bestpath_per_as_used = 1;
-                                       break;
-                               }
-
-                       if (bestpath_per_as_used)
-                               break;
-               }
-
-               if (bestpath_per_as_used) {
-                       vty_out(vty,
-                               "bgp deterministic-med cannot be disabled while addpath-tx-bestpath-per-AS is in use\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               } else {
-                       UNSET_FLAG(bgp->flags, BGP_FLAG_DETERMINISTIC_MED);
-                       bgp_recalculate_all_bestpaths(bgp);
-               }
-       }
-
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp graceful-restart mode" configuration. */
@@ -2840,13 +3090,18 @@ DEFUN (no_bgp_graceful_restart_rib_stale_time,
        return CMD_SUCCESS;
 }
 
-static inline void bgp_initiate_graceful_shut_unshut(struct vty *vty,
-                                                    struct bgp *bgp)
+static inline int bgp_initiate_graceful_shut_unshut(struct bgp *bgp,
+                                                   char *errmsg,
+                                                   size_t errmsg_len)
 {
        bgp_static_redo_import_check(bgp);
        bgp_redistribute_redo(bgp);
-       bgp_clear_star_soft_out(vty, bgp->name);
-       bgp_clear_star_soft_in(vty, bgp->name);
+       if (bgp_clear_star_soft_out(bgp->name, errmsg, errmsg_len) < 0)
+               return -1;
+       if (bgp_clear_star_soft_in(bgp->name, errmsg, errmsg_len) < 0)
+               return -1;
+
+       return 0;
 }
 
 static int bgp_global_graceful_shutdown_config_vty(struct vty *vty)
@@ -2854,6 +3109,7 @@ static int bgp_global_graceful_shutdown_config_vty(struct vty *vty)
        struct listnode *node, *nnode;
        struct bgp *bgp;
        bool vrf_cfg = false;
+       char errmsg[BUFSIZ] = {'\0'};
 
        if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN))
                return CMD_SUCCESS;
@@ -2879,8 +3135,13 @@ static int bgp_global_graceful_shutdown_config_vty(struct vty *vty)
        SET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN);
 
        /* Initiate processing for all BGP instances. */
-       for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
-               bgp_initiate_graceful_shut_unshut(vty, bgp);
+       for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               if (bgp_initiate_graceful_shut_unshut(bgp, errmsg,
+                                                     sizeof(errmsg))
+                   < 0)
+                       if (strlen(errmsg))
+                               vty_out(vty, "%s\n", errmsg);
+       }
 
        return CMD_SUCCESS;
 }
@@ -2889,6 +3150,7 @@ static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty)
 {
        struct listnode *node, *nnode;
        struct bgp *bgp;
+       char errmsg[BUFSIZ] = {'\0'};
 
        if (!CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN))
                return CMD_SUCCESS;
@@ -2897,8 +3159,13 @@ static int bgp_global_graceful_shutdown_deconfig_vty(struct vty *vty)
        UNSET_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN);
 
        /* Initiate processing for all BGP instances. */
-       for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp))
-               bgp_initiate_graceful_shut_unshut(vty, bgp);
+       for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
+               if (bgp_initiate_graceful_shut_unshut(bgp, errmsg,
+                                                     sizeof(errmsg))
+                   < 0)
+                       if (strlen(errmsg))
+                               vty_out(vty, "%s\n", errmsg);
+       }
 
        return CMD_SUCCESS;
 }
@@ -2913,24 +3180,13 @@ DEFUN (bgp_graceful_shutdown,
        if (vty->node == CONFIG_NODE)
                return bgp_global_graceful_shutdown_config_vty(vty);
 
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-
-       /* if configured globally, per-instance config is not allowed */
-       if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) {
-               vty_out(vty,
-                       "%%Failed: per-vrf graceful-shutdown config not permitted with global graceful-shutdown\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-               SET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
-               bgp_initiate_graceful_shut_unshut(vty, bgp);
-       }
+       nb_cli_enqueue_change(vty, "./global/graceful-shutdown/enable",
+                             NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_graceful_shutdown,
+DEFUN_YANG (no_bgp_graceful_shutdown,
        no_bgp_graceful_shutdown_cmd,
        "no bgp graceful-shutdown",
        NO_STR
@@ -2940,111 +3196,120 @@ DEFUN (no_bgp_graceful_shutdown,
        if (vty->node == CONFIG_NODE)
                return bgp_global_graceful_shutdown_deconfig_vty(vty);
 
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       nb_cli_enqueue_change(vty, "./global/graceful-shutdown/enable",
+                             NB_OP_MODIFY, "false");
 
-       /* If configured globally, cannot remove from one bgp instance */
-       if (CHECK_FLAG(bm->flags, BM_FLAG_GRACEFUL_SHUTDOWN)) {
-               vty_out(vty,
-                       "%%Failed: bgp graceful-shutdown configured globally. Delete per-vrf not permitted\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       if (CHECK_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
-               UNSET_FLAG(bgp->flags, BGP_FLAG_GRACEFUL_SHUTDOWN);
-               bgp_initiate_graceful_shut_unshut(vty, bgp);
-       }
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       return CMD_SUCCESS;
+void cli_show_router_bgp_graceful_shutdown(struct vty *vty,
+                                          struct lyd_node *dnode,
+                                          bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " bgp graceful-shutdown\n");
 }
 
 /* "bgp fast-external-failover" configuration. */
-DEFUN (bgp_fast_external_failover,
+DEFUN_YANG (bgp_fast_external_failover,
        bgp_fast_external_failover_cmd,
        "bgp fast-external-failover",
        BGP_STR
        "Immediately reset session if a link to a directly connected external peer goes down\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/fast-external-failover",
+                             NB_OP_MODIFY, "false");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_fast_external_failover,
+DEFUN_YANG (no_bgp_fast_external_failover,
        no_bgp_fast_external_failover_cmd,
        "no bgp fast-external-failover",
        NO_STR
        BGP_STR
        "Immediately reset session if a link to a directly connected external peer goes down\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_NO_FAST_EXT_FAILOVER);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/fast-external-failover",
+                             NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_bgp_fast_external_failover(struct vty *vty,
+                                               struct lyd_node *dnode,
+                                               bool show_defaults)
+{
+       if (!yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " no bgp fast-external-failover\n");
 }
 
 /* "bgp bestpath compare-routerid" configuration.  */
-DEFUN (bgp_bestpath_compare_router_id,
-       bgp_bestpath_compare_router_id_cmd,
-       "bgp bestpath compare-routerid",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "Compare router-id for identical EBGP paths\n")
+DEFUN_YANG(bgp_bestpath_compare_router_id,
+          bgp_bestpath_compare_router_id_cmd,
+          "bgp bestpath compare-routerid",
+          "BGP specific commands\n"
+          "Change the default bestpath selection\n"
+          "Compare router-id for identical EBGP paths\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty,
+               "./global/route-selection-options/external-compare-router-id",
+               NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_bestpath_compare_router_id,
-       no_bgp_bestpath_compare_router_id_cmd,
-       "no bgp bestpath compare-routerid",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "Compare router-id for identical EBGP paths\n")
+DEFUN_YANG(no_bgp_bestpath_compare_router_id,
+          no_bgp_bestpath_compare_router_id_cmd,
+          "no bgp bestpath compare-routerid",
+          NO_STR
+          "BGP specific commands\n"
+          "Change the default bestpath selection\n"
+          "Compare router-id for identical EBGP paths\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_COMPARE_ROUTER_ID);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty,
+               "./global/route-selection-options/external-compare-router-id",
+               NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp bestpath as-path ignore" configuration.  */
-DEFUN (bgp_bestpath_aspath_ignore,
-       bgp_bestpath_aspath_ignore_cmd,
-       "bgp bestpath as-path ignore",
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Ignore as-path length in selecting a route\n")
+DEFUN_YANG(bgp_bestpath_aspath_ignore,
+          bgp_bestpath_aspath_ignore_cmd,
+          "bgp bestpath as-path ignore",
+          "BGP specific commands\n"
+          "Change the default bestpath selection\n"
+          "AS-path attribute\n"
+          "Ignore as-path length in selecting a route\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/ignore-as-path-length",
+               NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_bestpath_aspath_ignore,
-       no_bgp_bestpath_aspath_ignore_cmd,
-       "no bgp bestpath as-path ignore",
-       NO_STR
-       "BGP specific commands\n"
-       "Change the default bestpath selection\n"
-       "AS-path attribute\n"
-       "Ignore as-path length in selecting a route\n")
+DEFUN_YANG(no_bgp_bestpath_aspath_ignore,
+          no_bgp_bestpath_aspath_ignore_cmd,
+          "no bgp bestpath as-path ignore",
+          NO_STR
+          "BGP specific commands\n"
+          "Change the default bestpath selection\n"
+          "AS-path attribute\n"
+          "Ignore as-path length in selecting a route\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_IGNORE);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/ignore-as-path-length",
+               NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp bestpath as-path confed" configuration.  */
-DEFUN (bgp_bestpath_aspath_confed,
+DEFUN_YANG (bgp_bestpath_aspath_confed,
        bgp_bestpath_aspath_confed_cmd,
        "bgp bestpath as-path confed",
        "BGP specific commands\n"
@@ -3052,14 +3317,14 @@ DEFUN (bgp_bestpath_aspath_confed,
        "AS-path attribute\n"
        "Compare path lengths including confederation sets & sequences in selecting a route\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(vty,
+                             "./global/route-selection-options/aspath-confed",
+                             NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_bestpath_aspath_confed,
+DEFUN_YANG (no_bgp_bestpath_aspath_confed,
        no_bgp_bestpath_aspath_confed_cmd,
        "no bgp bestpath as-path confed",
        NO_STR
@@ -3068,15 +3333,15 @@ DEFUN (no_bgp_bestpath_aspath_confed,
        "AS-path attribute\n"
        "Compare path lengths including confederation sets & sequences in selecting a route\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_CONFED);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(vty,
+                             "./global/route-selection-options/aspath-confed",
+                             NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp bestpath as-path multipath-relax" configuration.  */
-DEFUN (bgp_bestpath_aspath_multipath_relax,
+DEFUN_YANG (bgp_bestpath_aspath_multipath_relax,
        bgp_bestpath_aspath_multipath_relax_cmd,
        "bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
        "BGP specific commands\n"
@@ -3086,23 +3351,26 @@ DEFUN (bgp_bestpath_aspath_multipath_relax,
        "Generate an AS_SET\n"
        "Do not generate an AS_SET\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx = 0;
-       SET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
 
-       /* no-as-set is now the default behavior so we can silently
-        * ignore it */
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/allow-multiple-as",
+               NB_OP_MODIFY, "true");
        if (argv_find(argv, argc, "as-set", &idx))
-               SET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/route-selection-options/multi-path-as-set",
+                       NB_OP_MODIFY, "true");
        else
-               UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
-
-       bgp_recalculate_all_bestpaths(bgp);
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/route-selection-options/multi-path-as-set",
+                       NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_bestpath_aspath_multipath_relax,
+DEFUN_YANG (no_bgp_bestpath_aspath_multipath_relax,
        no_bgp_bestpath_aspath_multipath_relax_cmd,
        "no bgp bestpath as-path multipath-relax [<as-set|no-as-set>]",
        NO_STR
@@ -3113,40 +3381,46 @@ DEFUN (no_bgp_bestpath_aspath_multipath_relax,
        "Generate an AS_SET\n"
        "Do not generate an AS_SET\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_ASPATH_MULTIPATH_RELAX);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_MULTIPATH_RELAX_AS_SET);
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/allow-multiple-as",
+               NB_OP_MODIFY, "false");
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/multi-path-as-set",
+               NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp log-neighbor-changes" configuration.  */
-DEFUN (bgp_log_neighbor_changes,
-       bgp_log_neighbor_changes_cmd,
-       "bgp log-neighbor-changes",
-       "BGP specific commands\n"
-       "Log neighbor up/down and reset reason\n")
+DEFUN_YANG(bgp_log_neighbor_changes,
+          bgp_log_neighbor_changes_cmd,
+          "bgp log-neighbor-changes",
+          "BGP specific commands\n"
+          "Log neighbor up/down and reset reason\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(
+               vty, "./global/global-neighbor-config/log-neighbor-changes",
+               NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_log_neighbor_changes,
-       no_bgp_log_neighbor_changes_cmd,
-       "no bgp log-neighbor-changes",
-       NO_STR
-       "BGP specific commands\n"
-       "Log neighbor up/down and reset reason\n")
+DEFUN_YANG(no_bgp_log_neighbor_changes,
+          no_bgp_log_neighbor_changes_cmd,
+          "no bgp log-neighbor-changes",
+          NO_STR
+          "BGP specific commands\n"
+          "Log neighbor up/down and reset reason\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(
+               vty, "./global/global-neighbor-config/log-neighbor-changes",
+               NB_OP_MODIFY, "false");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp bestpath med" configuration. */
-DEFUN (bgp_bestpath_med,
+DEFUN_YANG (bgp_bestpath_med,
        bgp_bestpath_med_cmd,
        "bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
        "BGP specific commands\n"
@@ -3157,21 +3431,30 @@ DEFUN (bgp_bestpath_med,
        "Treat missing MED as the least preferred one\n"
        "Compare MED among confederation paths\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-
        int idx = 0;
+       bool confed = false;
+       bool worst_med = false;
+
+
        if (argv_find(argv, argc, "confed", &idx))
-               SET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED);
+               confed = true;
+
+       nb_cli_enqueue_change(vty,
+                             "./global/route-selection-options/confed-med",
+                             NB_OP_MODIFY, confed ? "true" : "false");
+
        idx = 0;
        if (argv_find(argv, argc, "missing-as-worst", &idx))
-               SET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST);
+               worst_med = true;
 
-       bgp_recalculate_all_bestpaths(bgp);
+       nb_cli_enqueue_change(
+               vty, "./global/route-selection-options/missing-as-worst-med",
+               NB_OP_MODIFY, worst_med ? "true" : "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_bestpath_med,
+DEFUN_YANG (no_bgp_bestpath_med,
        no_bgp_bestpath_med_cmd,
        "no bgp bestpath med <confed [missing-as-worst]|missing-as-worst [confed]>",
        NO_STR
@@ -3183,18 +3466,21 @@ DEFUN (no_bgp_bestpath_med,
        "Treat missing MED as the least preferred one\n"
        "Compare MED among confederation paths\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-
        int idx = 0;
+
        if (argv_find(argv, argc, "confed", &idx))
-               UNSET_FLAG(bgp->flags, BGP_FLAG_MED_CONFED);
+               nb_cli_enqueue_change(
+                       vty, "./global/route-selection-options/confed-med",
+                       NB_OP_MODIFY, "false");
+
        idx = 0;
        if (argv_find(argv, argc, "missing-as-worst", &idx))
-               UNSET_FLAG(bgp->flags, BGP_FLAG_MED_MISSING_AS_WORST);
-
-       bgp_recalculate_all_bestpaths(bgp);
+               nb_cli_enqueue_change(
+                       vty,
+                       "./global/route-selection-options/missing-as-worst-med",
+                       NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 /* "bgp bestpath bandwidth" configuration. */
@@ -3288,29 +3574,38 @@ DEFUN (bgp_default_ipv4_unicast,
 }
 
 /* Display hostname in certain command outputs */
-DEFUN (bgp_default_show_hostname,
+DEFUN_YANG (bgp_default_show_hostname,
        bgp_default_show_hostname_cmd,
        "bgp default show-hostname",
        "BGP specific commands\n"
        "Configure BGP defaults\n"
        "Show hostname in certain command outputs\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/show-hostname", NB_OP_MODIFY,
+                             "true");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_default_show_hostname,
-       no_bgp_default_show_hostname_cmd,
-       "no bgp default show-hostname",
-       NO_STR
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "Show hostname in certain command outputs\n")
+DEFUN_YANG(no_bgp_default_show_hostname,
+          no_bgp_default_show_hostname_cmd,
+          "no bgp default show-hostname",
+          NO_STR
+          "BGP specific commands\n"
+          "Configure BGP defaults\n"
+          "Show hostname in certain command outputs\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_HOSTNAME);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/show-hostname", NB_OP_MODIFY,
+                             "false");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_bgp_show_hostname(struct vty *vty, struct lyd_node *dnode,
+                                      bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SHOW_HOSTNAME)
+               vty_out(vty, " bgp default show-hostname\n");
 }
 
 /* Display hostname in certain command outputs */
@@ -3321,9 +3616,10 @@ DEFUN (bgp_default_show_nexthop_hostname,
        "Configure BGP defaults\n"
        "Show hostname for nexthop in certain command outputs\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/show-nexthop-hostname",
+                             NB_OP_MODIFY, "true");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 DEFUN (no_bgp_default_show_nexthop_hostname,
@@ -3334,26 +3630,32 @@ DEFUN (no_bgp_default_show_nexthop_hostname,
        "Configure BGP defaults\n"
        "Show hostname for nexthop in certain command outputs\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_SHOW_NEXTHOP_HOSTNAME);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/show-nexthop-hostname",
+                             NB_OP_MODIFY, "false");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_bgp_show_nexthop_hostname(struct vty *vty,
+                                              struct lyd_node *dnode,
+                                              bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_SHOW_HOSTNAME)
+               vty_out(vty, " bgp default show-nexthop-hostname\n");
 }
 
 /* "bgp network import-check" configuration.  */
-DEFUN (bgp_network_import_check,
-       bgp_network_import_check_cmd,
-       "bgp network import-check",
-       "BGP specific commands\n"
-       "BGP network command\n"
-       "Check BGP network route exists in IGP\n")
+DEFUN_YANG(bgp_network_import_check,
+          bgp_network_import_check_cmd,
+          "bgp network import-check",
+          "BGP specific commands\n"
+          "BGP network command\n"
+          "Check BGP network route exists in IGP\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
-               SET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
-               bgp_static_redo_import_check(bgp);
-       }
+       nb_cli_enqueue_change(vty, "./global/import-check", NB_OP_MODIFY,
+                             "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd,
@@ -3363,162 +3665,195 @@ ALIAS_HIDDEN(bgp_network_import_check, bgp_network_import_check_exact_cmd,
             "Check BGP network route exists in IGP\n"
             "Match route precisely\n")
 
-DEFUN (no_bgp_network_import_check,
-       no_bgp_network_import_check_cmd,
-       "no bgp network import-check",
-       NO_STR
-       "BGP specific commands\n"
-       "BGP network command\n"
-       "Check BGP network route exists in IGP\n")
+DEFUN_YANG(no_bgp_network_import_check,
+          no_bgp_network_import_check_cmd,
+          "no bgp network import-check",
+          NO_STR
+          "BGP specific commands\n"
+          "BGP network command\n"
+          "Check BGP network route exists in IGP\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
-               UNSET_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK);
-               bgp_static_redo_import_check(bgp);
-       }
+       nb_cli_enqueue_change(vty, "./global/import-check", NB_OP_MODIFY,
+                             "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (bgp_default_local_preference,
-       bgp_default_local_preference_cmd,
-       "bgp default local-preference (0-4294967295)",
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "local preference (higher=more preferred)\n"
-       "Configure default local preference value\n")
+void cli_show_router_bgp_import_check(struct vty *vty, struct lyd_node *dnode,
+                                     bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_number = 3;
-       uint32_t local_pref;
+       if (yang_dnode_get_bool(dnode, NULL) != SAVE_BGP_IMPORT_CHECK)
+               vty_out(vty, " bgp network import-check\n");
+}
 
-       local_pref = strtoul(argv[idx_number]->arg, NULL, 10);
+DEFUN_YANG(bgp_default_local_preference,
+          bgp_default_local_preference_cmd,
+          "bgp default local-preference (0-4294967295)",
+          "BGP specific commands\n"
+          "Configure BGP defaults\n"
+          "local preference (higher=more preferred)\n"
+          "Configure default local preference value\n")
+{
+       int idx_number = 3;
 
-       bgp_default_local_preference_set(bgp, local_pref);
-       bgp_clear_star_soft_in(vty, bgp->name);
+       nb_cli_enqueue_change(vty, "./global/local-pref", NB_OP_MODIFY,
+                             argv[idx_number]->arg);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_default_local_preference,
-       no_bgp_default_local_preference_cmd,
-       "no bgp default local-preference [(0-4294967295)]",
-       NO_STR
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "local preference (higher=more preferred)\n"
-       "Configure default local preference value\n")
+DEFUN_YANG(no_bgp_default_local_preference,
+          no_bgp_default_local_preference_cmd,
+          "no bgp default local-preference [(0-4294967295)]",
+          NO_STR
+          "BGP specific commands\n"
+          "Configure BGP defaults\n"
+          "local preference (higher=more preferred)\n"
+          "Configure default local preference value\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_default_local_preference_unset(bgp);
-       bgp_clear_star_soft_in(vty, bgp->name);
+       nb_cli_enqueue_change(vty, "./global/local-pref", NB_OP_MODIFY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
+void cli_show_router_bgp_local_pref(struct vty *vty, struct lyd_node *dnode,
+                                   bool show_defaults)
+{
+       vty_out(vty, " bgp default local-preference %u\n",
+               yang_dnode_get_uint32(dnode, NULL));
+}
 
-DEFUN (bgp_default_subgroup_pkt_queue_max,
-       bgp_default_subgroup_pkt_queue_max_cmd,
-       "bgp default subgroup-pkt-queue-max (20-100)",
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "subgroup-pkt-queue-max\n"
-       "Configure subgroup packet queue max\n")
+
+DEFUN_YANG(bgp_default_subgroup_pkt_queue_max,
+          bgp_default_subgroup_pkt_queue_max_cmd,
+          "bgp default subgroup-pkt-queue-max (20-100)",
+          "BGP specific commands\n"
+          "Configure BGP defaults\n"
+          "subgroup-pkt-queue-max\n"
+          "Configure subgroup packet queue max\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 3;
-       uint32_t max_size;
 
-       max_size = strtoul(argv[idx_number]->arg, NULL, 10);
+       nb_cli_enqueue_change(
+               vty,
+               "./global/global-update-group-config/subgroup-pkt-queue-size",
+               NB_OP_MODIFY, argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       bgp_default_subgroup_pkt_queue_max_set(bgp, max_size);
+DEFUN_YANG(no_bgp_default_subgroup_pkt_queue_max,
+          no_bgp_default_subgroup_pkt_queue_max_cmd,
+          "no bgp default subgroup-pkt-queue-max [(20-100)]",
+          NO_STR
+          "BGP specific commands\n"
+          "Configure BGP defaults\n"
+          "subgroup-pkt-queue-max\n"
+          "Configure subgroup packet queue max\n")
+{
+       nb_cli_enqueue_change(
+               vty,
+               "./global/global-update-group-config/subgroup-pkt-queue-size",
+               NB_OP_MODIFY, NULL);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_default_subgroup_pkt_queue_max,
-       no_bgp_default_subgroup_pkt_queue_max_cmd,
-       "no bgp default subgroup-pkt-queue-max [(20-100)]",
-       NO_STR
-       "BGP specific commands\n"
-       "Configure BGP defaults\n"
-       "subgroup-pkt-queue-max\n"
-       "Configure subgroup packet queue max\n")
+void cli_show_router_global_update_group_config_subgroup_pkt_queue_size(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_default_subgroup_pkt_queue_max_unset(bgp);
-       return CMD_SUCCESS;
+       vty_out(vty, " bgp default subgroup-pkt-queue-max %u\n",
+               yang_dnode_get_uint32(dnode, NULL));
 }
 
-
-DEFUN (bgp_rr_allow_outbound_policy,
-       bgp_rr_allow_outbound_policy_cmd,
-       "bgp route-reflector allow-outbound-policy",
-       "BGP specific commands\n"
-       "Allow modifications made by out route-map\n"
-       "on ibgp neighbors\n")
+DEFUN_YANG(bgp_rr_allow_outbound_policy,
+          bgp_rr_allow_outbound_policy_cmd,
+          "bgp route-reflector allow-outbound-policy",
+          "BGP specific commands\n"
+          "Allow modifications made by out route-map\n"
+          "on ibgp neighbors\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       nb_cli_enqueue_change(vty,
+                             "./global/route-reflector/allow-outbound-policy",
+                             NB_OP_MODIFY, "true");
 
-       if (!CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
-               SET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
-               update_group_announce_rrclients(bgp);
-               bgp_clear_star_soft_out(vty, bgp->name);
-       }
+       return nb_cli_apply_changes(vty, NULL);
+}
 
-       return CMD_SUCCESS;
+DEFUN_YANG(no_bgp_rr_allow_outbound_policy,
+          no_bgp_rr_allow_outbound_policy_cmd,
+          "no bgp route-reflector allow-outbound-policy",
+          NO_STR
+          "BGP specific commands\n"
+          "Allow modifications made by out route-map\n"
+          "on ibgp neighbors\n")
+{
+       nb_cli_enqueue_change(vty,
+                             "./global/route-reflector/allow-outbound-policy",
+                             NB_OP_MODIFY, "false");
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_rr_allow_outbound_policy,
-       no_bgp_rr_allow_outbound_policy_cmd,
-       "no bgp route-reflector allow-outbound-policy",
-       NO_STR
-       "BGP specific commands\n"
-       "Allow modifications made by out route-map\n"
-       "on ibgp neighbors\n")
+
+void cli_show_router_global_neighbor_config(struct vty *vty,
+                                           struct lyd_node *dnode,
+                                           bool show_defaults)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       uint32_t write_quanta, read_quanta;
+
+       if (yang_dnode_get_bool(dnode, "./log-neighbor-changes"))
+               vty_out(vty, " bgp log-neighbor-changes\n");
 
-       if (CHECK_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY)) {
-               UNSET_FLAG(bgp->flags, BGP_FLAG_RR_ALLOW_OUTBOUND_POLICY);
-               update_group_announce_rrclients(bgp);
-               bgp_clear_star_soft_out(vty, bgp->name);
+       if (yang_dnode_exists(dnode, "./dynamic-neighbors-limit")) {
+               uint32_t listen_limit = yang_dnode_get_uint32(
+                       dnode, "./dynamic-neighbors-limit");
+               vty_out(vty, " bgp listen limit %u\n", listen_limit);
        }
 
-       return CMD_SUCCESS;
+       write_quanta = yang_dnode_get_uint32(
+               dnode, "./packet-quanta-config/wpkt-quanta");
+       if (write_quanta != BGP_WRITE_PACKET_MAX)
+               vty_out(vty, " write-quanta %d\n", write_quanta);
+
+       read_quanta = yang_dnode_get_uint32(
+               dnode, "./packet-quanta-config/rpkt-quanta");
+
+       if (read_quanta != BGP_READ_PACKET_MAX)
+               vty_out(vty, " read-quanta %d\n", read_quanta);
 }
 
-DEFUN (bgp_listen_limit,
-       bgp_listen_limit_cmd,
-       "bgp listen limit (1-5000)",
-       "BGP specific commands\n"
-       "BGP Dynamic Neighbors listen commands\n"
-       "Maximum number of BGP Dynamic Neighbors that can be created\n"
-       "Configure Dynamic Neighbors listen limit value\n")
+DEFUN_YANG(bgp_listen_limit,
+          bgp_listen_limit_cmd,
+          "bgp listen limit (1-5000)",
+          "BGP specific commands\n"
+          "BGP Dynamic Neighbors listen commands\n"
+          "Maximum number of BGP Dynamic Neighbors that can be created\n"
+          "Configure Dynamic Neighbors listen limit value\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_number = 3;
-       int listen_limit;
-
-       listen_limit = strtoul(argv[idx_number]->arg, NULL, 10);
 
-       bgp_listen_limit_set(bgp, listen_limit);
+       nb_cli_enqueue_change(
+               vty, "./global/global-neighbor-config/dynamic-neighbors-limit",
+               NB_OP_MODIFY, argv[idx_number]->arg);
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_listen_limit,
-       no_bgp_listen_limit_cmd,
-       "no bgp listen limit [(1-5000)]",
-       NO_STR
-       "BGP specific commands\n"
-       "BGP Dynamic Neighbors listen commands\n"
-       "Maximum number of BGP Dynamic Neighbors that can be created\n"
-       "Configure Dynamic Neighbors listen limit value\n")
+DEFUN_YANG(no_bgp_listen_limit,
+          no_bgp_listen_limit_cmd,
+          "no bgp listen limit [(1-5000)]",
+          NO_STR
+          "BGP specific commands\n"
+          "BGP Dynamic Neighbors listen commands\n"
+          "Maximum number of BGP Dynamic Neighbors that can be created\n"
+          "Configure Dynamic Neighbors listen limit value\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp_listen_limit_unset(bgp);
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(
+               vty, "./global/global-neighbor-config/dynamic-neighbors-limit",
+               NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, NULL);
 }
 
 
@@ -3680,7 +4015,6 @@ void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
        struct listnode *node, *nnode, *rnode, *nrnode;
        struct prefix *range;
        afi_t afi;
-       char buf[PREFIX2STR_BUFFER];
 
        if (bgp->dynamic_neighbors_limit != BGP_DYNAMIC_NEIGHBORS_LIMIT_DEFAULT)
                vty_out(vty, " bgp listen limit %d\n",
@@ -3690,43 +4024,48 @@ void bgp_config_write_listen(struct vty *vty, struct bgp *bgp)
                for (afi = AFI_IP; afi < AFI_MAX; afi++) {
                        for (ALL_LIST_ELEMENTS(group->listen_range[afi], rnode,
                                               nrnode, range)) {
-                               prefix2str(range, buf, sizeof(buf));
                                vty_out(vty,
-                                       " bgp listen range %s peer-group %s\n",
-                                       buf, group->name);
+                                       " bgp listen range %pFX peer-group %s\n",
+                                       range, group->name);
                        }
                }
        }
 }
 
 
-DEFUN (bgp_disable_connected_route_check,
-       bgp_disable_connected_route_check_cmd,
-       "bgp disable-ebgp-connected-route-check",
-       "BGP specific commands\n"
-       "Disable checking if nexthop is connected on ebgp sessions\n")
+DEFUN_YANG(bgp_disable_connected_route_check,
+          bgp_disable_connected_route_check_cmd,
+          "bgp disable-ebgp-connected-route-check",
+          "BGP specific commands\n"
+          "Disable checking if nexthop is connected on ebgp sessions\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       SET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
-       bgp_clear_star_soft_in(vty, bgp->name);
+       nb_cli_enqueue_change(vty,
+                             "./global/ebgp-multihop-connected-route-check",
+                             NB_OP_MODIFY, "true");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
-DEFUN (no_bgp_disable_connected_route_check,
-       no_bgp_disable_connected_route_check_cmd,
-       "no bgp disable-ebgp-connected-route-check",
-       NO_STR
-       "BGP specific commands\n"
-       "Disable checking if nexthop is connected on ebgp sessions\n")
+DEFUN_YANG(no_bgp_disable_connected_route_check,
+          no_bgp_disable_connected_route_check_cmd,
+          "no bgp disable-ebgp-connected-route-check",
+          NO_STR
+          "BGP specific commands\n"
+          "Disable checking if nexthop is connected on ebgp sessions\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       UNSET_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK);
-       bgp_clear_star_soft_in(vty, bgp->name);
+       nb_cli_enqueue_change(vty,
+                             "./global/ebgp-multihop-connected-route-check",
+                             NB_OP_MODIFY, "false");
 
-       return CMD_SUCCESS;
+       return nb_cli_apply_changes(vty, NULL);
 }
 
+void cli_show_router_global_ebgp_multihop_connected_route_check(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " bgp disable-ebgp-connected-route-check\n");
+}
 
 static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
                              const char *as_str, afi_t afi, safi_t safi)
@@ -3792,17 +4131,25 @@ static int peer_remote_as_vty(struct vty *vty, const char *peer_str,
        return bgp_vty_return(vty, ret);
 }
 
-DEFUN (bgp_default_shutdown,
-       bgp_default_shutdown_cmd,
-       "[no] bgp default shutdown",
-       NO_STR
-       BGP_STR
-       "Configure BGP defaults\n"
-       "Apply administrative shutdown to newly configured peers\n")
+DEFUN_YANG(bgp_default_shutdown,
+          bgp_default_shutdown_cmd,
+          "[no] bgp default shutdown",
+          NO_STR BGP_STR
+          "Configure BGP defaults\n"
+          "Apply administrative shutdown to newly configured peers\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       bgp->autoshutdown = !strmatch(argv[0]->text, "no");
-       return CMD_SUCCESS;
+       nb_cli_enqueue_change(vty, "./global/default-shutdown", NB_OP_MODIFY,
+                             strmatch(argv[0]->text, "no") ? "false" : "true");
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_router_bgp_default_shutdown(struct vty *vty,
+                                         struct lyd_node *dnode,
+                                         bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, " bgp default shutdown\n");
 }
 
 DEFPY(bgp_shutdown_msg, bgp_shutdown_msg_cmd, "bgp shutdown message MSG...",
@@ -6828,6 +7175,68 @@ ALIAS_HIDDEN(no_neighbor_filter_list, no_neighbor_filter_list_hidden_cmd,
             "Filter incoming routes\n"
             "Filter outgoing routes\n")
 
+/* Set advertise-map to the peer. */
+static int peer_advertise_map_set_vty(struct vty *vty, const char *ip_str,
+                                     afi_t afi, safi_t safi,
+                                     const char *advertise_str,
+                                     const char *condition_str, bool condition,
+                                     bool set)
+{
+       int ret = CMD_WARNING_CONFIG_FAILED;
+       struct peer *peer;
+       struct route_map *advertise_map;
+       struct route_map *condition_map;
+
+       peer = peer_and_group_lookup_vty(vty, ip_str);
+       if (!peer)
+               return ret;
+
+       condition_map = route_map_lookup_warn_noexist(vty, condition_str);
+       advertise_map = route_map_lookup_warn_noexist(vty, advertise_str);
+
+       if (set)
+               ret = peer_advertise_map_set(peer, afi, safi, advertise_str,
+                                            advertise_map, condition_str,
+                                            condition_map, condition);
+       else
+               ret = peer_advertise_map_unset(peer, afi, safi, advertise_str,
+                                              advertise_map, condition_str,
+                                              condition_map, condition);
+
+       return bgp_vty_return(vty, ret);
+}
+
+DEFPY (neighbor_advertise_map,
+       neighbor_advertise_map_cmd,
+       "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$exist WORD$condition_str",
+       NO_STR
+       NEIGHBOR_STR
+       NEIGHBOR_ADDR_STR2
+       "Route-map to conditionally advertise routes\n"
+       "Name of advertise map\n"
+       "Advertise routes only if prefixes in exist-map are installed in BGP table\n"
+       "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n"
+       "Name of the exist or non exist map\n")
+{
+       bool condition = CONDITION_EXIST;
+
+       if (!strcmp(exist, "non-exist-map"))
+               condition = CONDITION_NON_EXIST;
+
+       return peer_advertise_map_set_vty(vty, neighbor, bgp_node_afi(vty),
+                                         bgp_node_safi(vty), advertise_str,
+                                         condition_str, condition, !no);
+}
+
+ALIAS_HIDDEN(neighbor_advertise_map, neighbor_advertise_map_hidden_cmd,
+            "[no$no] neighbor <A.B.C.D|X:X::X:X|WORD>$neighbor advertise-map WORD$advertise_str <exist-map|non-exist-map>$exist WORD$condition_str",
+            NO_STR NEIGHBOR_STR NEIGHBOR_ADDR_STR2
+            "Route-map to conditionally advertise routes\n"
+            "Name of advertise map\n"
+            "Advertise routes only if prefixes in exist-map are installed in BGP table\n"
+            "Advertise routes only if prefixes in non-exist-map are not installed in BGP table\n"
+            "Name of the exist or non exist map\n")
+
 /* Set route-map to the peer. */
 static int peer_route_map_set_vty(struct vty *vty, const char *ip_str,
                                  afi_t afi, safi_t safi, const char *name_str,
@@ -7675,6 +8084,33 @@ static int set_ecom_list(struct vty *vty, int argc, struct cmd_token **argv,
        return CMD_SUCCESS;
 }
 
+bool vpn_policy_check_import(struct bgp *bgp, afi_t afi, safi_t safi,
+                            bool v2vimport, char *errmsg, size_t errmsg_len)
+{
+       if (!v2vimport) {
+               if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+                              BGP_CONFIG_VRF_TO_VRF_IMPORT)
+                   || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+                                 BGP_CONFIG_VRF_TO_VRF_EXPORT)) {
+                       snprintf(
+                               errmsg, errmsg_len, "%s",
+                               "%% error: Please unconfigure import vrf commands before using vpn commands");
+                       return false;
+               }
+       } else {
+               if (CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+                              BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT)
+                   || CHECK_FLAG(bgp->af_flags[afi][SAFI_UNICAST],
+                                 BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT)) {
+                       snprintf(
+                               errmsg, errmsg_len, "%s",
+                               "%% error: Please unconfigure vpn to vrf commands before using import vrf commands");
+                       return false;
+               }
+       }
+       return true;
+}
+
 /*
  * v2vimport is true if we are handling a `import vrf ...` command
  */
@@ -7717,57 +8153,45 @@ static afi_t vpn_policy_getafi(struct vty *vty, struct bgp *bgp, bool v2vimport)
        return afi;
 }
 
-DEFPY (af_rd_vpn_export,
-       af_rd_vpn_export_cmd,
-       "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str",
-       NO_STR
-       "Specify route distinguisher\n"
-       "Between current address-family and vpn\n"
-       "For routes leaked from current address-family to vpn\n"
-       "Route Distinguisher (<as-number>:<number> | <ip-address>:<number>)\n")
+DEFPY_YANG(
+       af_rd_vpn_export,
+       af_rd_vpn_export_cmd,
+       "[no] rd vpn export ASN:NN_OR_IP-ADDRESS:NN$rd_str",
+       NO_STR
+       "Specify route distinguisher\n"
+       "Between current address-family and vpn\n"
+       "For routes leaked from current address-family to vpn\n"
+       "Route Distinguisher (<as-number>:<number> | <ip-address>:<number>)\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       struct prefix_rd prd;
-       int ret;
+       char base_xpath[XPATH_MAXLEN];
        afi_t afi;
+       safi_t safi;
        int idx = 0;
-       bool yes = true;
-
-       if (argv_find(argv, argc, "no", &idx))
-               yes = false;
 
-       if (yes) {
-               ret = str2prefix_rd(rd_str, &prd);
-               if (!ret) {
-                       vty_out(vty, "%% Malformed rd\n");
-                       return CMD_WARNING_CONFIG_FAILED;
-               }
-       }
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
 
-       afi = vpn_policy_getafi(vty, bgp, false);
-       if (afi == AFI_MAX)
-               return CMD_WARNING_CONFIG_FAILED;
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
 
-       /*
-        * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
-        */
-       vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
-                          bgp_get_default(), bgp);
+       if (argv_find(argv, argc, "no", &idx))
+               nb_cli_enqueue_change(vty, "./rd", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, "./rd", NB_OP_MODIFY, rd_str);
 
-       if (yes) {
-               bgp->vpn_policy[afi].tovpn_rd = prd;
-               SET_FLAG(bgp->vpn_policy[afi].flags,
-                        BGP_VPN_POLICY_TOVPN_RD_SET);
-       } else {
-               UNSET_FLAG(bgp->vpn_policy[afi].flags,
-                          BGP_VPN_POLICY_TOVPN_RD_SET);
-       }
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       /* post-change: re-export vpn routes */
-       vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
-                           bgp_get_default(), bgp);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rd(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       int indent = 2;
 
-       return CMD_SUCCESS;
+       vty_out(vty, "%*srd vpn export %s\n", indent, "",
+               yang_dnode_get_string(dnode, NULL));
 }
 
 ALIAS (af_rd_vpn_export,
@@ -7868,7 +8292,7 @@ ALIAS (af_label_vpn_export,
        "Between current address-family and vpn\n"
        "For routes leaked from current address-family to vpn\n")
 
-DEFPY (af_nexthop_vpn_export,
+DEFPY_YANG (af_nexthop_vpn_export,
        af_nexthop_vpn_export_cmd,
        "[no] nexthop vpn export [<A.B.C.D|X:X::X:X>$nexthop_su]",
        NO_STR
@@ -7878,8 +8302,10 @@ DEFPY (af_nexthop_vpn_export,
        "IPv4 prefix\n"
        "IPv6 prefix\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
+       char base_xpath[XPATH_MAXLEN];
        afi_t afi;
+       safi_t safi;
+       int idx = 0;
        struct prefix p;
 
        if (!no) {
@@ -7891,30 +8317,31 @@ DEFPY (af_nexthop_vpn_export,
                        return CMD_WARNING_CONFIG_FAILED;
        }
 
-       afi = vpn_policy_getafi(vty, bgp, false);
-       if (afi == AFI_MAX)
-               return CMD_WARNING_CONFIG_FAILED;
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
 
-       /*
-        * pre-change: un-export vpn routes (vpn->vrf routes unaffected)
-        */
-       vpn_leak_prechange(BGP_VPN_POLICY_DIR_TOVPN, afi,
-                          bgp_get_default(), bgp);
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
 
-       if (!no) {
-               bgp->vpn_policy[afi].tovpn_nexthop = p;
-               SET_FLAG(bgp->vpn_policy[afi].flags,
-                        BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
-       } else {
-               UNSET_FLAG(bgp->vpn_policy[afi].flags,
-                          BGP_VPN_POLICY_TOVPN_NEXTHOP_SET);
-       }
+       if (argv_find(argv, argc, "no", &idx))
+               nb_cli_enqueue_change(vty, "./nexthop", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, "./nexthop", NB_OP_MODIFY,
+                                     nexthop_su_str);
 
-       /* post-change: re-export vpn routes */
-       vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi,
-                           bgp_get_default(), bgp);
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       return CMD_SUCCESS;
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_nexthop(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       int indent = 2;
+
+       vty_out(vty, "%*snexthop vpn export %s\n", indent, "",
+               yang_dnode_get_string(dnode, NULL));
 }
 
 static int vpn_policy_getdirs(struct vty *vty, const char *dstr, int *dodir)
@@ -8015,7 +8442,7 @@ ALIAS (af_rt_vpn_imexport,
        "For routes leaked from current address-family to vpn\n"
        "both import and export\n")
 
-DEFPY (af_route_map_vpn_imexport,
+DEFPY_YANG (af_route_map_vpn_imexport,
        af_route_map_vpn_imexport_cmd,
 /* future: "route-map <vpn|evpn|vrf NAME> <import|export> RMAP" */
        "[no] route-map vpn <import|export>$direction_str RMAP$rmap_str",
@@ -8026,53 +8453,54 @@ DEFPY (af_route_map_vpn_imexport,
        "For routes leaked from current address-family to vpn\n"
        "name of route-map\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int ret;
-       int dodir[BGP_VPN_POLICY_DIR_MAX] = {0};
-       vpn_policy_direction_t dir;
+       char base_xpath[XPATH_MAXLEN];
        afi_t afi;
+       safi_t safi;
        int idx = 0;
-       bool yes = true;
-
-       if (argv_find(argv, argc, "no", &idx))
-               yes = false;
-
-       afi = vpn_policy_getafi(vty, bgp, false);
-       if (afi == AFI_MAX)
-               return CMD_WARNING_CONFIG_FAILED;
 
-       ret = vpn_policy_getdirs(vty, direction_str, dodir);
-       if (ret != CMD_SUCCESS)
-               return ret;
+       afi = bgp_node_afi(vty);
+       safi = bgp_node_safi(vty);
 
-       for (dir = 0; dir < BGP_VPN_POLICY_DIR_MAX; ++dir) {
-               if (!dodir[dir])
-                       continue;
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi));
+
+       if (argv_find(argv, argc, "no", &idx)) {
+               if (!strcmp(direction_str, "import"))
+                       nb_cli_enqueue_change(vty, "./rmap-import",
+                                             NB_OP_DESTROY, NULL);
+               else if (!strcmp(direction_str, "export"))
+                       nb_cli_enqueue_change(vty, "./rmap-export",
+                                             NB_OP_DESTROY, NULL);
+       } else {
+               if (!strcmp(direction_str, "import"))
+                       nb_cli_enqueue_change(vty, "./rmap-import",
+                                             NB_OP_MODIFY, rmap_str);
+               if (!strcmp(direction_str, "export"))
+                       nb_cli_enqueue_change(vty, "./rmap-export",
+                                             NB_OP_MODIFY, rmap_str);
+       }
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-               vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       int indent = 2;
 
-               if (yes) {
-                       if (bgp->vpn_policy[afi].rmap_name[dir])
-                               XFREE(MTYPE_ROUTE_MAP_NAME,
-                                     bgp->vpn_policy[afi].rmap_name[dir]);
-                       bgp->vpn_policy[afi].rmap_name[dir] = XSTRDUP(
-                                                                     MTYPE_ROUTE_MAP_NAME, rmap_str);
-                       bgp->vpn_policy[afi].rmap[dir] =
-                               route_map_lookup_warn_noexist(vty, rmap_str);
-                       if (!bgp->vpn_policy[afi].rmap[dir])
-                               return CMD_SUCCESS;
-               } else {
-                       if (bgp->vpn_policy[afi].rmap_name[dir])
-                               XFREE(MTYPE_ROUTE_MAP_NAME,
-                                     bgp->vpn_policy[afi].rmap_name[dir]);
-                       bgp->vpn_policy[afi].rmap_name[dir] = NULL;
-                       bgp->vpn_policy[afi].rmap[dir] = NULL;
-               }
+       vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
+               yang_dnode_get_string(dnode, NULL));
+}
 
-               vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
-       }
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_rmap_export(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       int indent = 2;
 
-       return CMD_SUCCESS;
+       vty_out(vty, "%*sroute-map vpn import %s\n", indent, "",
+               yang_dnode_get_string(dnode, NULL));
 }
 
 ALIAS (af_route_map_vpn_imexport,
@@ -8169,24 +8597,18 @@ DEFPY(af_no_import_vrf_route_map, af_no_import_vrf_route_map_cmd,
        return CMD_SUCCESS;
 }
 
-DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
-      "[no] import vrf VIEWVRFNAME$import_name",
-      NO_STR
-      "Import routes from another VRF\n"
-      "VRF to import from\n"
-      "The name of the VRF\n")
+DEFPY_YANG(bgp_imexport_vrf,
+          bgp_imexport_vrf_cmd,
+          "[no] import vrf VIEWVRFNAME$import_name",
+          NO_STR
+          "Import routes from another VRF\n"
+          "VRF to import from\n"
+          "The name of the VRF\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       struct listnode *node;
-       struct bgp *vrf_bgp, *bgp_default;
-       int32_t ret = 0;
-       as_t as = bgp->as;
-       bool remove = false;
-       int32_t idx = 0;
-       char *vname;
-       enum bgp_instance_type bgp_type = BGP_INSTANCE_TYPE_VRF;
+       char base_xpath[XPATH_MAXLEN];
        safi_t safi;
        afi_t afi;
+       int32_t idx = 0;
 
        if (import_name == NULL) {
                vty_out(vty, "%% Missing import name\n");
@@ -8198,70 +8620,32 @@ DEFPY(bgp_imexport_vrf, bgp_imexport_vrf_cmd,
                return CMD_WARNING;
        }
 
-       if (argv_find(argv, argc, "no", &idx))
-               remove = true;
-
-       afi = vpn_policy_getafi(vty, bgp, true);
-       if (afi == AFI_MAX)
-               return CMD_WARNING_CONFIG_FAILED;
-
+       afi = bgp_node_afi(vty);
        safi = bgp_node_safi(vty);
 
-       if (((BGP_INSTANCE_TYPE_DEFAULT == bgp->inst_type)
-            && (strcmp(import_name, VRF_DEFAULT_NAME) == 0))
-           || (bgp->name && (strcmp(import_name, bgp->name) == 0))) {
-               vty_out(vty, "%% Cannot %s vrf %s into itself\n",
-                       remove ? "unimport" : "import", import_name);
-               return CMD_WARNING;
-       }
-
-       bgp_default = bgp_get_default();
-       if (!bgp_default) {
-               /* Auto-create assuming the same AS */
-               ret = bgp_get_vty(&bgp_default, &as, NULL,
-                                 BGP_INSTANCE_TYPE_DEFAULT);
-
-               if (ret) {
-                       vty_out(vty,
-                               "VRF default is not configured as a bgp instance\n");
-                       return CMD_WARNING;
-               }
-       }
-
-       vrf_bgp = bgp_lookup_by_name(import_name);
-       if (!vrf_bgp) {
-               if (strcmp(import_name, VRF_DEFAULT_NAME) == 0)
-                       vrf_bgp = bgp_default;
-               else
-                       /* Auto-create assuming the same AS */
-                       ret = bgp_get_vty(&vrf_bgp, &as, import_name, bgp_type);
-
-               if (ret) {
-                       vty_out(vty,
-                               "VRF %s is not configured as a bgp instance\n",
-                               import_name);
-                       return CMD_WARNING;
-               }
-       }
+       snprintf(
+               base_xpath, sizeof(base_xpath),
+               "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/import-vrf-list[vrf='%s']",
+               yang_afi_safi_value2identity(afi, safi),
+               bgp_afi_safi_get_container_str(afi, safi), import_name);
 
-       if (remove) {
-               vrf_unimport_from_vrf(bgp, vrf_bgp, afi, safi);
-       } else {
-               /* Already importing from "import_vrf"? */
-               for (ALL_LIST_ELEMENTS_RO(bgp->vpn_policy[afi].import_vrf, node,
-                                         vname)) {
-                       if (strcmp(vname, import_name) == 0)
-                               return CMD_WARNING;
-               }
+       if (argv_find(argv, argc, "no", &idx))
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-               vrf_import_from_vrf(bgp, vrf_bgp, afi, safi);
-       }
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       return CMD_SUCCESS;
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vrfs(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       vty_out(vty, "  import vrf %s\n",
+               yang_dnode_get_string(dnode, "./vrf"));
 }
 
 /* This command is valid only in a bgp vrf instance or the default instance */
-DEFPY (bgp_imexport_vpn,
+DEFPY_YANG (bgp_imexport_vpn,
        bgp_imexport_vpn_cmd,
        "[no] <import|export>$direction_str vpn",
        NO_STR
@@ -8269,60 +8653,51 @@ DEFPY (bgp_imexport_vpn,
        "Export routes from this address-family\n"
        "to/from default instance VPN RIB\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int previous_state;
-       afi_t afi;
+       char base_xpath[XPATH_MAXLEN];
        safi_t safi;
-       int idx = 0;
-       bool yes = true;
-       int flag;
-       vpn_policy_direction_t dir;
-
-       if (argv_find(argv, argc, "no", &idx))
-               yes = false;
-
-       if (BGP_INSTANCE_TYPE_VRF != bgp->inst_type &&
-               BGP_INSTANCE_TYPE_DEFAULT != bgp->inst_type) {
-
-               vty_out(vty, "%% import|export vpn valid only for bgp vrf or default instance\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       afi_t afi;
+       int32_t idx = 0;
 
        afi = bgp_node_afi(vty);
        safi = bgp_node_safi(vty);
-       if ((SAFI_UNICAST != safi) || ((AFI_IP != afi) && (AFI_IP6 != afi))) {
-               vty_out(vty, "%% import|export vpn valid only for unicast ipv4|ipv6\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
 
        if (!strcmp(direction_str, "import")) {
-               flag = BGP_CONFIG_MPLSVPN_TO_VRF_IMPORT;
-               dir = BGP_VPN_POLICY_DIR_FROMVPN;
+               snprintf(
+                       base_xpath, sizeof(base_xpath),
+                       "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/import-vpn",
+                       yang_afi_safi_value2identity(afi, safi),
+                       bgp_afi_safi_get_container_str(afi, safi));
        } else if (!strcmp(direction_str, "export")) {
-               flag = BGP_CONFIG_VRF_TO_MPLSVPN_EXPORT;
-               dir = BGP_VPN_POLICY_DIR_TOVPN;
+               snprintf(
+                       base_xpath, sizeof(base_xpath),
+                       "./global/afi-safis/afi-safi[afi-safi-name='%s']/%s/vpn-config/export-vpn",
+                       yang_afi_safi_value2identity(afi, safi),
+                       bgp_afi_safi_get_container_str(afi, safi));
        } else {
                vty_out(vty, "%% unknown direction %s\n", direction_str);
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       previous_state = CHECK_FLAG(bgp->af_flags[afi][safi], flag);
+       if (argv_find(argv, argc, "no", &idx))
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, "true");
 
-       if (yes) {
-               SET_FLAG(bgp->af_flags[afi][safi], flag);
-               if (!previous_state) {
-                       /* trigger export current vrf */
-                       vpn_leak_postchange(dir, afi, bgp_get_default(), bgp);
-               }
-       } else {
-               if (previous_state) {
-                       /* trigger un-export current vrf */
-                       vpn_leak_prechange(dir, afi, bgp_get_default(), bgp);
-               }
-               UNSET_FLAG(bgp->af_flags[afi][safi], flag);
-       }
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       return CMD_SUCCESS;
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_import_vpn(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, "  import vpn\n");
+}
+
+void cli_show_bgp_global_afi_safi_ip_unicast_vpn_config_export_vpn(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       if (yang_dnode_get_bool(dnode, NULL))
+               vty_out(vty, "  export vpn\n");
 }
 
 DEFPY (af_routetarget_import,
@@ -8388,6 +8763,51 @@ DEFPY (af_routetarget_import,
        return CMD_SUCCESS;
 }
 
+void cli_show_bgp_global_afi_safi_header(struct vty *vty,
+                                        struct lyd_node *dnode,
+                                        bool show_defaults)
+{
+       const char *af_name;
+       afi_t afi;
+       safi_t safi;
+
+       af_name = yang_dnode_get_string(dnode, "./afi-safi-name");
+       yang_afi_safi_identity2value(af_name, &afi, &safi);
+
+       vty_out(vty, " !\n address-family ");
+       if (afi == AFI_IP) {
+               if (safi == SAFI_UNICAST)
+                       vty_out(vty, "ipv4 unicast");
+               else if (safi == SAFI_LABELED_UNICAST)
+                       vty_out(vty, "ipv4 labeled-unicast");
+               else if (safi == SAFI_MULTICAST)
+                       vty_out(vty, "ipv4 multicast");
+               else if (safi == SAFI_MPLS_VPN)
+                       vty_out(vty, "ipv4 vpn");
+               else if (safi == SAFI_ENCAP)
+                       vty_out(vty, "ipv4 encap");
+               else if (safi == SAFI_FLOWSPEC)
+                       vty_out(vty, "ipv4 flowspec");
+       } else if (afi == AFI_IP6) {
+               if (safi == SAFI_UNICAST)
+                       vty_out(vty, "ipv6 unicast");
+               else if (safi == SAFI_LABELED_UNICAST)
+                       vty_out(vty, "ipv6 labeled-unicast");
+               else if (safi == SAFI_MULTICAST)
+                       vty_out(vty, "ipv6 multicast");
+               else if (safi == SAFI_MPLS_VPN)
+                       vty_out(vty, "ipv6 vpn");
+               else if (safi == SAFI_ENCAP)
+                       vty_out(vty, "ipv6 encap");
+               else if (safi == SAFI_FLOWSPEC)
+                       vty_out(vty, "ipv6 flowspec");
+       } else if (afi == AFI_L2VPN) {
+               if (safi == SAFI_EVPN)
+                       vty_out(vty, "l2vpn evpn");
+       }
+       vty_out(vty, "\n");
+}
+
 DEFUN_NOSH (address_family_ipv4_safi,
        address_family_ipv4_safi_cmd,
        "address-family ipv4 [<unicast|multicast|vpn|labeled-unicast|flowspec>]",
@@ -8396,19 +8816,28 @@ DEFUN_NOSH (address_family_ipv4_safi,
        BGP_SAFI_WITH_LABEL_HELP_STR)
 {
 
+       safi_t safi = SAFI_UNICAST;
+       const struct lyd_node *vrf_dnode, *bgp_glb_dnode;
+       const char *vrf_name = NULL;
+
        if (argc == 3) {
-               VTY_DECLVAR_CONTEXT(bgp, bgp);
-               safi_t safi = bgp_vty_safi_from_str(argv[2]->text);
-               if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
+               safi = bgp_vty_safi_from_str(argv[2]->text);
+
+               bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode,
+                                              VTY_CURR_XPATH);
+               vrf_dnode = yang_dnode_get_parent(bgp_glb_dnode,
+                                                 "control-plane-protocol");
+               vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf");
+
+               if (!strmatch(vrf_name, VRF_DEFAULT_NAME)
                    && safi != SAFI_UNICAST && safi != SAFI_MULTICAST
                    && safi != SAFI_EVPN) {
                        vty_out(vty,
                                "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
-               vty->node = bgp_node_type(AFI_IP, safi);
-       } else
-               vty->node = BGP_IPV4_NODE;
+       }
+       vty->node = bgp_node_type(AFI_IP, safi);
 
        return CMD_SUCCESS;
 }
@@ -8420,19 +8849,27 @@ DEFUN_NOSH (address_family_ipv6_safi,
        "Address Family\n"
        BGP_SAFI_WITH_LABEL_HELP_STR)
 {
+       safi_t safi = SAFI_UNICAST;
+       const struct lyd_node *vrf_dnode, *bgp_glb_dnode;
+       const char *vrf_name = NULL;
+
        if (argc == 3) {
-               VTY_DECLVAR_CONTEXT(bgp, bgp);
-               safi_t safi = bgp_vty_safi_from_str(argv[2]->text);
-               if (bgp->inst_type != BGP_INSTANCE_TYPE_DEFAULT
+               safi = bgp_vty_safi_from_str(argv[2]->text);
+               bgp_glb_dnode = yang_dnode_get(vty->candidate_config->dnode,
+                                              VTY_CURR_XPATH);
+               vrf_dnode = yang_dnode_get_parent(bgp_glb_dnode,
+                                                 "control-plane-protocol");
+               vrf_name = yang_dnode_get_string(vrf_dnode, "./vrf");
+
+               if (!strmatch(vrf_name, VRF_DEFAULT_NAME)
                    && safi != SAFI_UNICAST && safi != SAFI_MULTICAST
                    && safi != SAFI_EVPN) {
                        vty_out(vty,
                                "Only Unicast/Multicast/EVPN SAFIs supported in non-core instances.\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
-               vty->node = bgp_node_type(AFI_IP6, safi);
-       } else
-               vty->node = BGP_IPV6_NODE;
+       }
+       vty->node = bgp_node_type(AFI_IP6, safi);
 
        return CMD_SUCCESS;
 }
@@ -8489,6 +8926,13 @@ DEFUN_NOSH (exit_address_family,
        return CMD_SUCCESS;
 }
 
+void cli_show_bgp_global_afi_safi_header_end(struct vty *vty,
+                                            struct lyd_node *dnode
+                                            __attribute__((__unused__)))
+{
+       vty_out(vty, " exit-address-family\n");
+}
+
 /* Recalculate bestpath and re-advertise a prefix */
 static int bgp_clear_prefix(struct vty *vty, const char *view_name,
                            const char *ip_str, afi_t afi, safi_t safi,
@@ -8603,6 +9047,8 @@ DEFUN (clear_ip_bgp_all,
        char *clr_arg = NULL;
 
        int idx = 0;
+       char errmsg[BUFSIZ] = {'\0'};
+       int ret;
 
        /* clear [ip] bgp */
        if (argv_find(argv, argc, "ip", &idx))
@@ -8667,7 +9113,12 @@ DEFUN (clear_ip_bgp_all,
        } else
                clr_type = BGP_CLEAR_SOFT_NONE;
 
-       return bgp_clear_vty(vty, vrf, afi, safi, clr_sort, clr_type, clr_arg);
+       ret = bgp_clear_vty(vrf, afi, safi, clr_sort, clr_type, clr_arg, errmsg,
+                           sizeof(errmsg));
+       if (ret != NB_OK)
+               vty_out(vty, "Error description: %s\n", errmsg);
+
+       return ret;
 }
 
 DEFUN (clear_ip_bgp_prefix,
@@ -8855,10 +9306,14 @@ DEFUN (show_bgp_vrfs,
                        int64_t vrf_id_ui = (bgp->vrf_id == VRF_UNKNOWN)
                                                    ? -1
                                                    : (int64_t)bgp->vrf_id;
+                       char buf[BUFSIZ] = {0};
+
                        json_object_string_add(json_vrf, "type", type);
                        json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
                        json_object_string_add(json_vrf, "routerId",
-                                              inet_ntoa(bgp->router_id));
+                                              inet_ntop(AF_INET,
+                                                        &bgp->router_id, buf,
+                                                        sizeof(buf)));
                        json_object_int_add(json_vrf, "numConfiguredPeers",
                                            peers_cfg);
                        json_object_int_add(json_vrf, "numEstablishedPeers",
@@ -8873,13 +9328,11 @@ DEFUN (show_bgp_vrfs,
                                               bgp->vrf_id));
                        json_object_object_add(json_vrfs, name, json_vrf);
                } else {
-                       vty_out(vty,
-                               "%4s  %-5d  %-16s  %-9u  %-10u  %-37s\n",
+                       vty_out(vty, "%4s  %-5d  %-16pI4  %-9u  %-10u  %-37s\n",
                                type,
                                bgp->vrf_id == VRF_UNKNOWN ? -1
                                                           : (int)bgp->vrf_id,
-                               inet_ntoa(bgp->router_id), peers_cfg,
-                               peers_estb, name);
+                               &bgp->router_id, peers_cfg, peers_estb, name);
                        vty_out(vty,"%11s  %-16u  %-21s  %-20s\n", " ",
                                bgp->l3vni,
                                prefix_mac2str(&bgp->rmac, buf, sizeof(buf)),
@@ -8924,8 +9377,7 @@ static void show_tip_entry(struct hash_bucket *bucket, void *args)
        struct vty *vty = (struct vty *)args;
        struct tip_addr *tip = (struct tip_addr *)bucket->data;
 
-       vty_out(vty, "addr: %s, count: %d\n", inet_ntoa(tip->addr),
-               tip->refcnt);
+       vty_out(vty, "addr: %pI4, count: %d\n", &tip->addr, tip->refcnt);
 }
 
 static void bgp_show_martian_nexthops(struct vty *vty, struct bgp *bgp)
@@ -9390,9 +9842,12 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
 
                        /* Usage summary and header */
                        if (use_json) {
+                               char buf[BUFSIZ] = {0};
+
                                json_object_string_add(
                                        json, "routerId",
-                                       inet_ntoa(bgp->router_id));
+                                       inet_ntop(AF_INET, &bgp->router_id, buf,
+                                                 sizeof(buf)));
                                json_object_int_add(json, "as", bgp->as);
                                json_object_int_add(json, "vrfId", vrf_id_ui);
                                json_object_string_add(
@@ -9403,8 +9858,8 @@ static int bgp_show_summary(struct vty *vty, struct bgp *bgp, int afi, int safi,
                                                : bgp->name);
                        } else {
                                vty_out(vty,
-                                       "BGP router identifier %s, local AS number %u vrf-id %d",
-                                       inet_ntoa(bgp->router_id), bgp->as,
+                                       "BGP router identifier %pI4, local AS number %u vrf-id %d",
+                                       &bgp->router_id, bgp->as,
                                        bgp->vrf_id == VRF_UNKNOWN
                                                ? -1
                                                : (int)bgp->vrf_id);
@@ -10486,6 +10941,7 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
        json_object *json_prefA = NULL;
        json_object *json_prefB = NULL;
        json_object *json_addr = NULL;
+       json_object *json_advmap = NULL;
 
        if (use_json) {
                json_addr = json_object_new_object();
@@ -10760,6 +11216,26 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                                               "selectiveUnsuppressRouteMap",
                                               filter->usmap.name);
 
+               /* advertise-map */
+               if (filter->advmap.aname) {
+                       json_advmap = json_object_new_object();
+                       json_object_string_add(json_advmap, "condition",
+                                              filter->advmap.condition
+                                                      ? "EXIST"
+                                                      : "NON_EXIST");
+                       json_object_string_add(json_advmap, "conditionMap",
+                                              filter->advmap.cname);
+                       json_object_string_add(json_advmap, "advertiseMap",
+                                              filter->advmap.aname);
+                       json_object_string_add(json_advmap, "advertiseStatus",
+                                              filter->advmap.update_type
+                                                              == ADVERTISE
+                                                      ? "Advertise"
+                                                      : "Withdraw");
+                       json_object_object_add(json_addr, "advertiseMap",
+                                              json_advmap);
+               }
+
                /* Receive prefix count */
                json_object_int_add(json_addr, "acceptedPrefixCounter",
                                    p->pcount[afi][safi]);
@@ -11055,6 +11531,20 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
                                filter->usmap.map ? "*" : "",
                                filter->usmap.name);
 
+               /* advertise-map */
+               if (filter->advmap.aname && filter->advmap.cname)
+                       vty_out(vty,
+                               "  Condition %s, Condition-map %s%s, Advertise-map %s%s, status: %s\n",
+                               filter->advmap.condition ? "EXIST"
+                                                        : "NON_EXIST",
+                               filter->advmap.cmap ? "*" : "",
+                               filter->advmap.cname,
+                               filter->advmap.amap ? "*" : "",
+                               filter->advmap.aname,
+                               filter->advmap.update_type == ADVERTISE
+                                       ? "Advertise"
+                                       : "Withdraw");
+
                /* Receive prefix count */
                vty_out(vty, "  %u accepted prefixes\n",
                        p->pcount[afi][safi]);
@@ -13884,7 +14374,6 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group)
        struct prefix *range;
        struct peer *conf;
        struct peer *peer;
-       char buf[PREFIX2STR_BUFFER];
        afi_t afi;
        safi_t safi;
        const char *peer_status;
@@ -13938,10 +14427,8 @@ static int bgp_show_one_peer_group(struct vty *vty, struct peer_group *group)
 
 
                        for (ALL_LIST_ELEMENTS(group->listen_range[afi], node,
-                                              nnode, range)) {
-                               prefix2str(range, buf, sizeof(buf));
-                               vty_out(vty, "    %s\n", buf);
-                       }
+                                              nnode, range))
+                               vty_out(vty, "    %pFX\n", range);
                }
        }
 
@@ -14024,24 +14511,23 @@ DEFUN (show_ip_bgp_peer_groups,
 
 /* Redistribute VTY commands.  */
 
-DEFUN (bgp_redistribute_ipv4,
-       bgp_redistribute_ipv4_cmd,
-       "redistribute " FRR_IP_REDIST_STR_BGPD,
-       "Redistribute information from another routing protocol\n"
-       FRR_IP_REDIST_HELP_STR_BGPD)
+DEFUN_YANG (bgp_redistribute_ipv4,
+           bgp_redistribute_ipv4_cmd,
+           "redistribute " FRR_IP_REDIST_STR_BGPD,
+           "Redistribute information from another routing protocol\n"
+           FRR_IP_REDIST_HELP_STR_BGPD)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
-       int type;
+       char base_xpath[XPATH_MAXLEN];
 
-       type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       bgp_redist_add(bgp, AFI_IP, type, 0);
-       return bgp_redistribute_set(bgp, AFI_IP, type, 0, false);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14049,33 +14535,28 @@ ALIAS_HIDDEN(
        "redistribute " FRR_IP_REDIST_STR_BGPD,
        "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD)
 
-DEFUN (bgp_redistribute_ipv4_rmap,
-       bgp_redistribute_ipv4_rmap_cmd,
-       "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP_REDIST_HELP_STR_BGPD
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG (bgp_redistribute_ipv4_rmap,
+           bgp_redistribute_ipv4_rmap_cmd,
+           "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD",
+           "Redistribute information from another routing protocol\n"
+           FRR_IP_REDIST_HELP_STR_BGPD
+           "Route map reference\n"
+           "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
        int idx_word = 3;
-       int type;
-       struct bgp_redist *red;
-       bool changed;
-       struct route_map *route_map = route_map_lookup_warn_noexist(
-               vty, argv[idx_word]->arg);
-
-       type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
 
-       red = bgp_redist_add(bgp, AFI_IP, type, 0);
-       changed =
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14085,32 +14566,28 @@ ALIAS_HIDDEN(
        "Route map reference\n"
        "Pointer to route-map entries\n")
 
-DEFUN (bgp_redistribute_ipv4_metric,
-       bgp_redistribute_ipv4_metric_cmd,
-       "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP_REDIST_HELP_STR_BGPD
-       "Metric for redistributed routes\n"
-       "Default metric\n")
+DEFUN_YANG (bgp_redistribute_ipv4_metric,
+           bgp_redistribute_ipv4_metric_cmd,
+           "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295)",
+           "Redistribute information from another routing protocol\n"
+           FRR_IP_REDIST_HELP_STR_BGPD
+           "Metric for redistributed routes\n"
+           "Default metric\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
        int idx_number = 3;
-       int type;
-       uint32_t metric;
-       struct bgp_redist *red;
-       bool changed;
-
-       type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       metric = strtoul(argv[idx_number]->arg, NULL, 10);
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number]->arg);
 
-       red = bgp_redist_add(bgp, AFI_IP, type, 0);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
-       return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14120,39 +14597,34 @@ ALIAS_HIDDEN(
        "Metric for redistributed routes\n"
        "Default metric\n")
 
-DEFUN (bgp_redistribute_ipv4_rmap_metric,
-       bgp_redistribute_ipv4_rmap_metric_cmd,
-       "redistribute " FRR_IP_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP_REDIST_HELP_STR_BGPD
-       "Route map reference\n"
-       "Pointer to route-map entries\n"
-       "Metric for redistributed routes\n"
-       "Default metric\n")
+DEFUN_YANG(
+       bgp_redistribute_ipv4_rmap_metric,
+       bgp_redistribute_ipv4_rmap_metric_cmd,
+       "redistribute " FRR_IP_REDIST_STR_BGPD
+       " route-map WORD metric (0-4294967295)",
+       "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD
+       "Route map reference\n"
+       "Pointer to route-map entries\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
        int idx_word = 3;
        int idx_number = 5;
-       int type;
-       uint32_t metric;
-       struct bgp_redist *red;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       metric = strtoul(argv[idx_number]->arg, NULL, 10);
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number]->arg);
 
-       red = bgp_redist_add(bgp, AFI_IP, type, 0);
-       changed =
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
-       return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14166,39 +14638,34 @@ ALIAS_HIDDEN(
        "Metric for redistributed routes\n"
        "Default metric\n")
 
-DEFUN (bgp_redistribute_ipv4_metric_rmap,
-       bgp_redistribute_ipv4_metric_rmap_cmd,
-       "redistribute " FRR_IP_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP_REDIST_HELP_STR_BGPD
-       "Metric for redistributed routes\n"
-       "Default metric\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG(
+       bgp_redistribute_ipv4_metric_rmap,
+       bgp_redistribute_ipv4_metric_rmap_cmd,
+       "redistribute " FRR_IP_REDIST_STR_BGPD
+       " metric (0-4294967295) route-map WORD",
+       "Redistribute information from another routing protocol\n" FRR_IP_REDIST_HELP_STR_BGPD
+       "Metric for redistributed routes\n"
+       "Default metric\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
-       int idx_number = 3;
        int idx_word = 5;
-       int type;
-       uint32_t metric;
-       struct bgp_redist *red;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       metric = strtoul(argv[idx_number]->arg, NULL, 10);
+       int idx_number = 3;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
 
-       red = bgp_redist_add(bgp, AFI_IP, type, 0);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, type, metric);
-       changed |=
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       return bgp_redistribute_set(bgp, AFI_IP, type, 0, changed);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number]->arg);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14212,29 +14679,26 @@ ALIAS_HIDDEN(
        "Route map reference\n"
        "Pointer to route-map entries\n")
 
-DEFUN (bgp_redistribute_ipv4_ospf,
-       bgp_redistribute_ipv4_ospf_cmd,
-       "redistribute <ospf|table> (1-65535)",
-       "Redistribute information from another routing protocol\n"
-       "Open Shortest Path First (OSPFv2)\n"
-       "Non-main Kernel Routing Table\n"
-       "Instance ID/Table ID\n")
+DEFUN_YANG (bgp_redistribute_ipv4_ospf,
+           bgp_redistribute_ipv4_ospf_cmd,
+           "redistribute <ospf|table> (1-65535)",
+           "Redistribute information from another routing protocol\n"
+           "Open Shortest Path First (OSPFv2)\n"
+           "Non-main Kernel Routing Table\n"
+           "Instance ID/Table ID\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_ospf_table = 1;
+       int idx_protocol = 1;
        int idx_number = 2;
-       unsigned short instance;
-       unsigned short protocol;
+       char base_xpath[XPATH_MAXLEN];
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, argv[idx_number]->arg);
 
-       if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
-               protocol = ZEBRA_ROUTE_OSPF;
-       else
-               protocol = ZEBRA_ROUTE_TABLE;
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, false);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd,
@@ -14244,37 +14708,32 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf, bgp_redistribute_ipv4_ospf_hidden_cmd,
             "Non-main Kernel Routing Table\n"
             "Instance ID/Table ID\n")
 
-DEFUN (bgp_redistribute_ipv4_ospf_rmap,
-       bgp_redistribute_ipv4_ospf_rmap_cmd,
-       "redistribute <ospf|table> (1-65535) route-map WORD",
-       "Redistribute information from another routing protocol\n"
-       "Open Shortest Path First (OSPFv2)\n"
-       "Non-main Kernel Routing Table\n"
-       "Instance ID/Table ID\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG (bgp_redistribute_ipv4_ospf_rmap,
+           bgp_redistribute_ipv4_ospf_rmap_cmd,
+           "redistribute <ospf|table> (1-65535) route-map WORD",
+           "Redistribute information from another routing protocol\n"
+           "Open Shortest Path First (OSPFv2)\n"
+           "Non-main Kernel Routing Table\n"
+           "Instance ID/Table ID\n"
+           "Route map reference\n"
+           "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_ospf_table = 1;
+       int idx_protocol = 1;
        int idx_number = 2;
        int idx_word = 4;
-       struct bgp_redist *red;
-       unsigned short instance;
-       int protocol;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
-               protocol = ZEBRA_ROUTE_OSPF;
-       else
-               protocol = ZEBRA_ROUTE_TABLE;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, argv[idx_number]->arg);
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       changed =
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap,
@@ -14287,38 +14746,32 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap,
             "Route map reference\n"
             "Pointer to route-map entries\n")
 
-DEFUN (bgp_redistribute_ipv4_ospf_metric,
-       bgp_redistribute_ipv4_ospf_metric_cmd,
-       "redistribute <ospf|table> (1-65535) metric (0-4294967295)",
-       "Redistribute information from another routing protocol\n"
-       "Open Shortest Path First (OSPFv2)\n"
-       "Non-main Kernel Routing Table\n"
-       "Instance ID/Table ID\n"
-       "Metric for redistributed routes\n"
-       "Default metric\n")
+DEFUN_YANG(bgp_redistribute_ipv4_ospf_metric,
+          bgp_redistribute_ipv4_ospf_metric_cmd,
+          "redistribute <ospf|table> (1-65535) metric (0-4294967295)",
+          "Redistribute information from another routing protocol\n"
+          "Open Shortest Path First (OSPFv2)\n"
+          "Non-main Kernel Routing Table\n"
+          "Instance ID/Table ID\n"
+          "Metric for redistributed routes\n"
+          "Default metric\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_ospf_table = 1;
+       int idx_protocol = 1;
        int idx_number = 2;
        int idx_number_2 = 4;
-       uint32_t metric;
-       struct bgp_redist *red;
-       unsigned short instance;
-       int protocol;
-       bool changed;
-
-       if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
-               protocol = ZEBRA_ROUTE_OSPF;
-       else
-               protocol = ZEBRA_ROUTE_TABLE;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, argv[idx_number]->arg);
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       metric = strtoul(argv[idx_number_2]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number_2]->arg);
 
-       red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol,
-                                               metric);
-       return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric,
@@ -14331,45 +14784,38 @@ ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric,
             "Metric for redistributed routes\n"
             "Default metric\n")
 
-DEFUN (bgp_redistribute_ipv4_ospf_rmap_metric,
-       bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
-       "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)",
-       "Redistribute information from another routing protocol\n"
-       "Open Shortest Path First (OSPFv2)\n"
-       "Non-main Kernel Routing Table\n"
-       "Instance ID/Table ID\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n"
-       "Metric for redistributed routes\n"
-       "Default metric\n")
+DEFUN_YANG(
+       bgp_redistribute_ipv4_ospf_rmap_metric,
+       bgp_redistribute_ipv4_ospf_rmap_metric_cmd,
+       "redistribute <ospf|table> (1-65535) route-map WORD metric (0-4294967295)",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Non-main Kernel Routing Table\n"
+       "Instance ID/Table ID\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_ospf_table = 1;
+       int idx_protocol = 1;
        int idx_number = 2;
        int idx_word = 4;
        int idx_number_2 = 6;
-       uint32_t metric;
-       struct bgp_redist *red;
-       unsigned short instance;
-       int protocol;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
-               protocol = ZEBRA_ROUTE_OSPF;
-       else
-               protocol = ZEBRA_ROUTE_TABLE;
+       char base_xpath[XPATH_MAXLEN];
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       metric = strtoul(argv[idx_number_2]->arg, NULL, 10);
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, argv[idx_number]->arg);
 
-       red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       changed =
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol,
-                                               metric);
-       return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number_2]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14385,45 +14831,38 @@ ALIAS_HIDDEN(
        "Metric for redistributed routes\n"
        "Default metric\n")
 
-DEFUN (bgp_redistribute_ipv4_ospf_metric_rmap,
-       bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
-       "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD",
-       "Redistribute information from another routing protocol\n"
-       "Open Shortest Path First (OSPFv2)\n"
-       "Non-main Kernel Routing Table\n"
-       "Instance ID/Table ID\n"
-       "Metric for redistributed routes\n"
-       "Default metric\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG(
+       bgp_redistribute_ipv4_ospf_metric_rmap,
+       bgp_redistribute_ipv4_ospf_metric_rmap_cmd,
+       "redistribute <ospf|table> (1-65535) metric (0-4294967295) route-map WORD",
+       "Redistribute information from another routing protocol\n"
+       "Open Shortest Path First (OSPFv2)\n"
+       "Non-main Kernel Routing Table\n"
+       "Instance ID/Table ID\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_ospf_table = 1;
+       int idx_protocol = 1;
        int idx_number = 2;
        int idx_number_2 = 4;
        int idx_word = 6;
-       uint32_t metric;
-       struct bgp_redist *red;
-       unsigned short instance;
-       int protocol;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
-               protocol = ZEBRA_ROUTE_OSPF;
-       else
-               protocol = ZEBRA_ROUTE_TABLE;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, argv[idx_number]->arg);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       metric = strtoul(argv[idx_number_2]->arg, NULL, 10);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       red = bgp_redist_add(bgp, AFI_IP, protocol, instance);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP, protocol,
-                                               metric);
-       changed |=
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number_2]->arg);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14439,32 +14878,31 @@ ALIAS_HIDDEN(
        "Route map reference\n"
        "Pointer to route-map entries\n")
 
-DEFUN (no_bgp_redistribute_ipv4_ospf,
-       no_bgp_redistribute_ipv4_ospf_cmd,
-       "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]",
-       NO_STR
-       "Redistribute information from another routing protocol\n"
-       "Open Shortest Path First (OSPFv2)\n"
-       "Non-main Kernel Routing Table\n"
-       "Instance ID/Table ID\n"
-       "Metric for redistributed routes\n"
-       "Default metric\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG (no_bgp_redistribute_ipv4_ospf,
+           no_bgp_redistribute_ipv4_ospf_cmd,
+           "no redistribute <ospf|table> (1-65535) [{metric (0-4294967295)|route-map WORD}]",
+           NO_STR
+           "Redistribute information from another routing protocol\n"
+           "Open Shortest Path First (OSPFv2)\n"
+           "Non-main Kernel Routing Table\n"
+           "Instance ID/Table ID\n"
+           "Metric for redistributed routes\n"
+           "Default metric\n"
+           "Route map reference\n"
+           "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
-       int idx_ospf_table = 2;
+       int idx_protocol = 2;
        int idx_number = 3;
-       unsigned short instance;
-       int protocol;
+       char base_xpath[XPATH_MAXLEN];
 
-       if (strncmp(argv[idx_ospf_table]->arg, "o", 1) == 0)
-               protocol = ZEBRA_ROUTE_OSPF;
-       else
-               protocol = ZEBRA_ROUTE_TABLE;
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, argv[idx_number]->arg);
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       return bgp_redistribute_unset(bgp, AFI_IP, protocol, instance);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14480,27 +14918,28 @@ ALIAS_HIDDEN(
        "Route map reference\n"
        "Pointer to route-map entries\n")
 
-DEFUN (no_bgp_redistribute_ipv4,
-       no_bgp_redistribute_ipv4_cmd,
-       "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]",
-       NO_STR
-       "Redistribute information from another routing protocol\n"
-       FRR_IP_REDIST_HELP_STR_BGPD
-       "Metric for redistributed routes\n"
-       "Default metric\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG (no_bgp_redistribute_ipv4,
+           no_bgp_redistribute_ipv4_cmd,
+           "no redistribute " FRR_IP_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]",
+           NO_STR
+           "Redistribute information from another routing protocol\n"
+           FRR_IP_REDIST_HELP_STR_BGPD
+           "Metric for redistributed routes\n"
+           "Default metric\n"
+           "Route map reference\n"
+           "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 2;
-       int type;
+       char base_xpath[XPATH_MAXLEN];
 
-       type = proto_redistnum(AFI_IP, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       return bgp_redistribute_unset(bgp, AFI_IP, type, 0);
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14514,56 +14953,50 @@ ALIAS_HIDDEN(
        "Route map reference\n"
        "Pointer to route-map entries\n")
 
-DEFUN (bgp_redistribute_ipv6,
-       bgp_redistribute_ipv6_cmd,
-       "redistribute " FRR_IP6_REDIST_STR_BGPD,
-       "Redistribute information from another routing protocol\n"
-       FRR_IP6_REDIST_HELP_STR_BGPD)
+DEFUN_YANG (bgp_redistribute_ipv6,
+           bgp_redistribute_ipv6_cmd,
+           "redistribute " FRR_IP6_REDIST_STR_BGPD,
+           "Redistribute information from another routing protocol\n"
+           FRR_IP6_REDIST_HELP_STR_BGPD)
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
-       int type;
+       char base_xpath[XPATH_MAXLEN];
 
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
 
-       bgp_redist_add(bgp, AFI_IP6, type, 0);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, false);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFUN (bgp_redistribute_ipv6_rmap,
-       bgp_redistribute_ipv6_rmap_cmd,
-       "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP6_REDIST_HELP_STR_BGPD
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG (bgp_redistribute_ipv6_rmap,
+           bgp_redistribute_ipv6_rmap_cmd,
+           "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD",
+           "Redistribute information from another routing protocol\n"
+           FRR_IP6_REDIST_HELP_STR_BGPD
+           "Route map reference\n"
+           "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
        int idx_word = 3;
-       int type;
-       struct bgp_redist *red;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       char base_xpath[XPATH_MAXLEN];
 
-       red = bgp_redist_add(bgp, AFI_IP6, type, 0);
-       changed =
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFUN (bgp_redistribute_ipv6_metric,
+DEFUN_YANG (bgp_redistribute_ipv6_metric,
        bgp_redistribute_ipv6_metric_cmd,
        "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295)",
        "Redistribute information from another routing protocol\n"
@@ -14571,120 +15004,123 @@ DEFUN (bgp_redistribute_ipv6_metric,
        "Metric for redistributed routes\n"
        "Default metric\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
        int idx_number = 3;
-       int type;
-       uint32_t metric;
-       struct bgp_redist *red;
-       bool changed;
-
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       metric = strtoul(argv[idx_number]->arg, NULL, 10);
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
 
-       red = bgp_redist_add(bgp, AFI_IP6, type, 0);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFUN (bgp_redistribute_ipv6_rmap_metric,
-       bgp_redistribute_ipv6_rmap_metric_cmd,
-       "redistribute " FRR_IP6_REDIST_STR_BGPD " route-map WORD metric (0-4294967295)",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP6_REDIST_HELP_STR_BGPD
-       "Route map reference\n"
-       "Pointer to route-map entries\n"
-       "Metric for redistributed routes\n"
-       "Default metric\n")
+DEFUN_YANG(
+       bgp_redistribute_ipv6_rmap_metric,
+       bgp_redistribute_ipv6_rmap_metric_cmd,
+       "redistribute " FRR_IP6_REDIST_STR_BGPD
+       " route-map WORD metric (0-4294967295)",
+       "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD
+       "Route map reference\n"
+       "Pointer to route-map entries\n"
+       "Metric for redistributed routes\n"
+       "Default metric\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
        int idx_word = 3;
        int idx_number = 5;
-       int type;
-       uint32_t metric;
-       struct bgp_redist *red;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       metric = strtoul(argv[idx_number]->arg, NULL, 10);
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
 
-       red = bgp_redist_add(bgp, AFI_IP6, type, 0);
-       changed =
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       changed |= bgp_redistribute_metric_set(bgp, red, AFI_IP6, type,
-                                               metric);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFUN (bgp_redistribute_ipv6_metric_rmap,
-       bgp_redistribute_ipv6_metric_rmap_cmd,
-       "redistribute " FRR_IP6_REDIST_STR_BGPD " metric (0-4294967295) route-map WORD",
-       "Redistribute information from another routing protocol\n"
-       FRR_IP6_REDIST_HELP_STR_BGPD
-       "Metric for redistributed routes\n"
-       "Default metric\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG(
+       bgp_redistribute_ipv6_metric_rmap,
+       bgp_redistribute_ipv6_metric_rmap_cmd,
+       "redistribute " FRR_IP6_REDIST_STR_BGPD
+       " metric (0-4294967295) route-map WORD",
+       "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD
+       "Metric for redistributed routes\n"
+       "Default metric\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 1;
-       int idx_number = 3;
        int idx_word = 5;
-       int type;
-       uint32_t metric;
-       struct bgp_redist *red;
-       bool changed;
-       struct route_map *route_map =
-               route_map_lookup_warn_noexist(vty, argv[idx_word]->arg);
-
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       metric = strtoul(argv[idx_number]->arg, NULL, 10);
+       int idx_number = 3;
+       char base_xpath[XPATH_MAXLEN];
+
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number]->arg);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
 
-       red = bgp_redist_add(bgp, AFI_IP6, type, 0);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, SAFI_UNICAST,
-                                               metric);
-       changed |=
-               bgp_redistribute_rmap_set(red, argv[idx_word]->arg, route_map);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
-DEFUN (no_bgp_redistribute_ipv6,
-       no_bgp_redistribute_ipv6_cmd,
-       "no redistribute " FRR_IP6_REDIST_STR_BGPD " [{metric (0-4294967295)|route-map WORD}]",
-       NO_STR
-       "Redistribute information from another routing protocol\n"
-       FRR_IP6_REDIST_HELP_STR_BGPD
-       "Metric for redistributed routes\n"
-       "Default metric\n"
-       "Route map reference\n"
-       "Pointer to route-map entries\n")
+DEFUN_YANG(
+       no_bgp_redistribute_ipv6,
+       no_bgp_redistribute_ipv6_cmd,
+       "no redistribute " FRR_IP6_REDIST_STR_BGPD
+       " [{metric (0-4294967295)|route-map WORD}]",
+       NO_STR
+       "Redistribute information from another routing protocol\n" FRR_IP6_REDIST_HELP_STR_BGPD
+       "Metric for redistributed routes\n"
+       "Default metric\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
 {
-       VTY_DECLVAR_CONTEXT(bgp, bgp);
        int idx_protocol = 2;
-       int type;
+       char base_xpath[XPATH_MAXLEN];
 
-       type = proto_redistnum(AFI_IP6, argv[idx_protocol]->text);
-       if (type < 0) {
-               vty_out(vty, "%% Invalid route type\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
+       snprintf(base_xpath, sizeof(base_xpath), FRR_BGP_AFI_SAFI_REDIST_XPATH,
+                yang_afi_safi_value2identity(AFI_IP6, SAFI_UNICAST),
+                bgp_afi_safi_get_container_str(AFI_IP6, SAFI_UNICAST),
+                argv[idx_protocol]->text, "0");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       return bgp_redistribute_unset(bgp, AFI_IP6, type, 0);
+void cli_show_bgp_global_afi_safi_ip_unicast_redistribution_list(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       uint32_t instance = 0;
+
+       vty_out(vty, "  redistribute %s",
+               yang_dnode_get_string(dnode, "./route-type"));
+       if ((instance = yang_dnode_get_uint16(dnode, "./route-instance")))
+               vty_out(vty, " %d", instance);
+       if (yang_dnode_exists(dnode, "./metric"))
+               vty_out(vty, " metric %u",
+                       yang_dnode_get_uint32(dnode, "./metric"));
+       if (yang_dnode_exists(dnode, "./rmap-policy-import"))
+               vty_out(vty, " route-map %s",
+                       yang_dnode_get_string(dnode, "./rmap-policy-import"));
+       vty_out(vty, "\n");
 }
 
 static void bgp_config_write_redistribute(struct vty *vty, struct bgp *bgp,
@@ -14773,6 +15209,10 @@ static bool peergroup_filter_check(struct peer *peer, afi_t afi, safi_t safi,
                return !!(filter->map[direct].name);
        case PEER_FT_UNSUPPRESS_MAP:
                return !!(filter->usmap.name);
+       case PEER_FT_ADVERTISE_MAP:
+               return !!(filter->advmap.aname
+                         && ((filter->advmap.condition == direct)
+                             && filter->advmap.cname));
        default:
                return false;
        }
@@ -14958,6 +15398,18 @@ static void bgp_config_write_filter(struct vty *vty, struct peer *peer,
                vty_out(vty, "  neighbor %s unsuppress-map %s\n", addr,
                        filter->usmap.name);
 
+       /* advertise-map : always applied in OUT direction*/
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_ADVERTISE_MAP,
+                                  CONDITION_NON_EXIST))
+               vty_out(vty,
+                       "  neighbor %s advertise-map %s non-exist-map %s\n",
+                       addr, filter->advmap.aname, filter->advmap.cname);
+
+       if (peergroup_filter_check(peer, afi, safi, PEER_FT_ADVERTISE_MAP,
+                                  CONDITION_EXIST))
+               vty_out(vty, "  neighbor %s advertise-map %s exist-map %s\n",
+                       addr, filter->advmap.aname, filter->advmap.cname);
+
        /* filter-list. */
        if (peergroup_filter_check(peer, afi, safi, PEER_FT_FILTER_LIST,
                                   FILTER_IN))
@@ -15668,8 +16120,8 @@ int bgp_config_write(struct vty *vty)
 
                /* BGP router ID. */
                if (bgp->router_id_static.s_addr != 0)
-                       vty_out(vty, " bgp router-id %s\n",
-                               inet_ntoa(bgp->router_id_static));
+                       vty_out(vty, " bgp router-id %pI4\n",
+                               &bgp->router_id_static);
 
                /* BGP log-neighbor-changes. */
                if (!!CHECK_FLAG(bgp->flags, BGP_FLAG_LOG_NEIGHBOR_CHANGES)
@@ -15735,8 +16187,8 @@ int bgp_config_write(struct vty *vty)
 
                /* BGP cluster ID. */
                if (CHECK_FLAG(bgp->config, BGP_CONFIG_CLUSTER_ID))
-                       vty_out(vty, " bgp cluster-id %s\n",
-                               inet_ntoa(bgp->cluster_id));
+                       vty_out(vty, " bgp cluster-id %pI4\n",
+                               &bgp->cluster_id);
 
                /* Disable ebgp connected nexthop check */
                if (CHECK_FLAG(bgp->flags, BGP_FLAG_DISABLE_NH_CONNECTED_CHK))
@@ -17162,6 +17614,17 @@ void bgp_vty_init(void)
        install_element(BGP_VPNV6_NODE, &neighbor_unsuppress_map_cmd);
        install_element(BGP_VPNV6_NODE, &no_neighbor_unsuppress_map_cmd);
 
+       /* "neighbor advertise-map" commands. */
+       install_element(BGP_NODE, &neighbor_advertise_map_hidden_cmd);
+       install_element(BGP_IPV4_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_IPV4M_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_IPV4L_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_IPV6_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_IPV6M_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_IPV6L_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_VPNV4_NODE, &neighbor_advertise_map_cmd);
+       install_element(BGP_VPNV6_NODE, &neighbor_advertise_map_cmd);
+
        /* neighbor maximum-prefix-out commands. */
        install_element(BGP_NODE, &neighbor_maximum_prefix_out_cmd);
        install_element(BGP_NODE, &no_neighbor_maximum_prefix_out_cmd);
@@ -17709,9 +18172,10 @@ DEFUN (no_community_list_expanded_all,
        return CMD_SUCCESS;
 }
 
-ALIAS(no_community_list_expanded_all, no_bgp_community_list_expanded_all_list_cmd,
+ALIAS(no_community_list_expanded_all,
+      no_bgp_community_list_expanded_all_list_cmd,
       "no bgp community-list <(100-500)|expanded WORD>",
-      NO_STR IP_STR COMMUNITY_LIST_STR
+      NO_STR BGP_STR COMMUNITY_LIST_STR
       "Community list number (expanded)\n"
       "Add an expanded community-list entry\n"
       "Community list name\n")
@@ -18330,7 +18794,7 @@ DEFUN (no_extcommunity_list_standard_all,
 ALIAS(no_extcommunity_list_standard_all,
       no_bgp_extcommunity_list_standard_all_list_cmd,
       "no bgp extcommunity-list <(1-99)|standard WORD>",
-      NO_STR IP_STR EXTCOMMUNITY_LIST_STR
+      NO_STR BGP_STR EXTCOMMUNITY_LIST_STR
       "Extended Community list number (standard)\n"
       "Specify standard extcommunity-list\n"
       "Community list name\n")
@@ -18395,7 +18859,7 @@ DEFUN (no_extcommunity_list_expanded_all,
 ALIAS(no_extcommunity_list_expanded_all,
       no_bgp_extcommunity_list_expanded_all_list_cmd,
       "no bgp extcommunity-list <(100-500)|expanded WORD>",
-      NO_STR IP_STR EXTCOMMUNITY_LIST_STR
+      NO_STR BGP_STR EXTCOMMUNITY_LIST_STR
       "Extended Community list number (expanded)\n"
       "Specify expanded extcommunity-list\n"
       "Extended Community list name\n")
index 95eefbc36fe3133b306b44307e74334d90cb1893..349efbac454a3f738f90b629a4ad2505941bb003 100644 (file)
@@ -180,5 +180,19 @@ int bgp_vty_find_and_parse_bgp(struct vty *vty, struct cmd_token **argv,
 extern int bgp_show_summary_vty(struct vty *vty, const char *name, afi_t afi,
                                safi_t safi, bool show_failed,
                                bool show_established, bool use_json);
+extern int bgp_clear_star_soft_in(const char *name, char *errmsg,
+                                 size_t errmsg_len);
+extern int bgp_clear_star_soft_out(const char *name, char *errmsg,
+                                  size_t errmsg_len);
+int bgp_wpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set);
+int bgp_rpkt_quanta_config_vty(struct bgp *bgp, uint32_t quanta, bool set);
+extern int bgp_maxpaths_config_vty(struct bgp *bgp, afi_t afi, safi_t safi,
+                                  int peer_type, uint16_t maxpaths,
+                                  uint16_t options, int set, char *errmsg,
+                                  size_t errmsg_len);
+extern const char *bgp_afi_safi_get_container_str(afi_t afi, safi_t safi);
+extern bool vpn_policy_check_import(struct bgp *bgp, afi_t afi, safi_t safi,
+                                   bool v2vimport, char *errmsg,
+                                   size_t errmsg_len);
 
 #endif /* _QUAGGA_BGP_VTY_H */
index a32e47f446364c348a11e334b2010cb73332218f..957db4cbc123e79829937bd647f43140a38dfcf6 100644 (file)
@@ -91,11 +91,9 @@ static int bgp_router_id_update(ZAPI_CALLBACK_ARGS)
 
        zebra_router_id_update_read(zclient->ibuf, &router_id);
 
-       if (BGP_DEBUG(zebra, ZEBRA)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&router_id, buf, sizeof(buf));
-               zlog_debug("Rx Router Id update VRF %u Id %s", vrf_id, buf);
-       }
+       if (BGP_DEBUG(zebra, ZEBRA))
+               zlog_debug("Rx Router Id update VRF %u Id %pFX", vrf_id,
+                          &router_id);
 
        bgp_router_id_zebra_bump(vrf_id, &router_id);
        return 0;
@@ -313,12 +311,9 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS)
        if (ifc == NULL)
                return 0;
 
-       if (bgp_debug_zebra(ifc->address)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(ifc->address, buf, sizeof(buf));
-               zlog_debug("Rx Intf address add VRF %u IF %s addr %s", vrf_id,
-                          ifc->ifp->name, buf);
-       }
+       if (bgp_debug_zebra(ifc->address))
+               zlog_debug("Rx Intf address add VRF %u IF %s addr %pFX", vrf_id,
+                          ifc->ifp->name, ifc->address);
 
        if (!bgp)
                return 0;
@@ -350,12 +345,9 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)
        if (ifc == NULL)
                return 0;
 
-       if (bgp_debug_zebra(ifc->address)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(ifc->address, buf, sizeof(buf));
-               zlog_debug("Rx Intf address del VRF %u IF %s addr %s", vrf_id,
-                          ifc->ifp->name, buf);
-       }
+       if (bgp_debug_zebra(ifc->address))
+               zlog_debug("Rx Intf address del VRF %u IF %s addr %pFX", vrf_id,
+                          ifc->ifp->name, ifc->address);
 
        if (bgp && if_is_operative(ifc->ifp)) {
                bgp_connected_delete(bgp, ifc);
@@ -376,12 +368,9 @@ static int bgp_interface_nbr_address_add(ZAPI_CALLBACK_ARGS)
        if (ifc == NULL)
                return 0;
 
-       if (bgp_debug_zebra(ifc->address)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(ifc->address, buf, sizeof(buf));
-               zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %s", vrf_id,
-                          ifc->ifp->name, buf);
-       }
+       if (bgp_debug_zebra(ifc->address))
+               zlog_debug("Rx Intf neighbor add VRF %u IF %s addr %pFX",
+                          vrf_id, ifc->ifp->name, ifc->address);
 
        if (if_is_operative(ifc->ifp)) {
                bgp = bgp_lookup_by_vrf_id(vrf_id);
@@ -402,12 +391,9 @@ static int bgp_interface_nbr_address_delete(ZAPI_CALLBACK_ARGS)
        if (ifc == NULL)
                return 0;
 
-       if (bgp_debug_zebra(ifc->address)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(ifc->address, buf, sizeof(buf));
-               zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %s", vrf_id,
-                          ifc->ifp->name, buf);
-       }
+       if (bgp_debug_zebra(ifc->address))
+               zlog_debug("Rx Intf neighbor del VRF %u IF %s addr %pFX",
+                          vrf_id, ifc->ifp->name, ifc->address);
 
        if (if_is_operative(ifc->ifp)) {
                bgp = bgp_lookup_by_vrf_id(vrf_id);
@@ -534,22 +520,20 @@ static int zebra_read_route(ZAPI_CALLBACK_ARGS)
        }
 
        if (bgp_debug_zebra(&api.prefix)) {
-               char buf[2][PREFIX_STRLEN];
+               char buf[PREFIX_STRLEN];
 
-               prefix2str(&api.prefix, buf[0], sizeof(buf[0]));
                if (add) {
-                       inet_ntop(api.prefix.family, &nexthop, buf[1],
-                                 sizeof(buf[1]));
+                       inet_ntop(api.prefix.family, &nexthop, buf,
+                                 sizeof(buf));
                        zlog_debug(
-                               "Rx route ADD VRF %u %s[%d] %s nexthop %s (type %d if %u) metric %u tag %" ROUTE_TAG_PRI,
+                               "Rx route ADD VRF %u %s[%d] %pFX nexthop %s (type %d if %u) metric %u tag %" ROUTE_TAG_PRI,
                                vrf_id, zebra_route_string(api.type),
-                               api.instance, buf[0], buf[1], nhtype,
-                               ifindex, api.metric, api.tag);
+                               api.instance, &api.prefix, buf, nhtype, ifindex,
+                               api.metric, api.tag);
                } else {
-                       zlog_debug(
-                               "Rx route DEL VRF %u %s[%d] %s",
-                               vrf_id, zebra_route_string(api.type),
-                               api.instance, buf[0]);
+                       zlog_debug("Rx route DEL VRF %u %s[%d] %s", vrf_id,
+                                  zebra_route_string(api.type), api.instance,
+                                  buf);
                }
        }
 
@@ -944,10 +928,8 @@ static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p,
                if (p->family == AF_INET) {
                        char buf[2][INET_ADDRSTRLEN];
                        zlog_debug(
-                               "Zebra rmap deny: IPv4 route %s/%d nexthop %s",
-                               inet_ntop(AF_INET, &p->u.prefix4, buf[0],
-                                         sizeof(buf[0])),
-                               p->prefixlen,
+                               "Zebra rmap deny: IPv4 route %pFX nexthop %s",
+                               p,
                                inet_ntop(AF_INET, &path->attr->nexthop, buf[1],
                                          sizeof(buf[1])));
                }
@@ -958,12 +940,10 @@ static bool bgp_table_map_apply(struct route_map *map, const struct prefix *p,
 
                        nexthop = bgp_path_info_to_ipv6_nexthop(path, &ifindex);
                        zlog_debug(
-                               "Zebra rmap deny: IPv6 route %s/%d nexthop %s",
-                               inet_ntop(AF_INET6, &p->u.prefix6, buf[0],
-                                         sizeof(buf[0])),
-                               p->prefixlen,
-                               inet_ntop(AF_INET6, nexthop,
-                                         buf[1], sizeof(buf[1])));
+                               "Zebra rmap deny: IPv6 route %pFX nexthop %s",
+                               p,
+                               inet_ntop(AF_INET6, nexthop, buf[1],
+                                         sizeof(buf[1])));
                }
        }
        return false;
@@ -1440,18 +1420,17 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
        }
 
        if (bgp_debug_zebra(p)) {
-               char prefix_buf[PREFIX_STRLEN];
                char nh_buf[INET6_ADDRSTRLEN];
                char eth_buf[ETHER_ADDR_STRLEN + 7] = {'\0'};
                char buf1[ETHER_ADDR_STRLEN];
                char label_buf[20];
                int i;
 
-               prefix2str(&api.prefix, prefix_buf, sizeof(prefix_buf));
-               zlog_debug("Tx route %s VRF %u %s metric %u tag %" ROUTE_TAG_PRI
-                          " count %d",
-                          valid_nh_count ? "add" : "delete", bgp->vrf_id,
-                          prefix_buf, api.metric, api.tag, api.nexthop_num);
+               zlog_debug(
+                       "Tx route %s VRF %u %pFX metric %u tag %" ROUTE_TAG_PRI
+                       " count %d",
+                       valid_nh_count ? "add" : "delete", bgp->vrf_id,
+                       &api.prefix, api.metric, api.tag, api.nexthop_num);
                for (i = 0; i < api.nexthop_num; i++) {
                        api_nh = &api.nexthops[i];
 
@@ -1600,12 +1579,9 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info,
        if (is_route_parent_evpn(info))
                SET_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE);
 
-       if (bgp_debug_zebra(p)) {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(&api.prefix, buf, sizeof(buf));
-               zlog_debug("Tx route delete VRF %u %s", bgp->vrf_id, buf);
-       }
+       if (bgp_debug_zebra(p))
+               zlog_debug("Tx route delete VRF %u %pFX", bgp->vrf_id,
+                          &api.prefix);
 
        zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 }
@@ -2414,6 +2390,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
 {
        struct prefix pfx;
        uint8_t fam = AF_INET;
+       char ifname[INTERFACE_NAMSIZ];
 
        if (pbra->nh.type == NEXTHOP_TYPE_IPV6)
                fam = AF_INET6;
@@ -2455,7 +2432,7 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
        stream_put(s, &pfx.u.prefix, prefix_blen(&pfx));
 
        stream_putw(s, 0);  /* dst port */
-
+       stream_putc(s, 0);  /* dsfield */
        /* if pbr present, fwmark is not used */
        if (pbr)
                stream_putl(s, 0);
@@ -2464,7 +2441,8 @@ static void bgp_encode_pbr_rule_action(struct stream *s,
 
        stream_putl(s, pbra->table_id);
 
-       stream_putl(s, 0); /* ifindex unused */
+       memset(ifname, 0, sizeof(ifname));
+       stream_put(s, ifname, INTERFACE_NAMSIZ); /* ifname unused */
 }
 
 static void bgp_encode_pbr_ipset_match(struct stream *s,
@@ -2569,6 +2547,7 @@ static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS)
        char buf[ESI_STR_LEN];
        struct in_addr originator_ip;
        uint8_t active;
+       uint16_t df_pref;
 
        bgp = bgp_lookup_by_vrf_id(vrf_id);
        if (!bgp)
@@ -2578,14 +2557,15 @@ static int bgp_zebra_process_local_es_add(ZAPI_CALLBACK_ARGS)
        stream_get(&esi, s, sizeof(esi_t));
        originator_ip.s_addr = stream_get_ipv4(s);
        active = stream_getc(s);
+       df_pref = stream_getw(s);
 
        if (BGP_DEBUG(zebra, ZEBRA))
-               zlog_debug("Rx add ESI %s originator-ip %s active %u",
-                               esi_to_str(&esi, buf, sizeof(buf)),
-                               inet_ntoa(originator_ip),
-                               active);
+               zlog_debug(
+                       "Rx add ESI %s originator-ip %pI4 active %u df_pref %u",
+                       esi_to_str(&esi, buf, sizeof(buf)),
+                       &originator_ip, active, df_pref);
 
-       bgp_evpn_local_es_add(bgp, &esi, originator_ip, active);
+       bgp_evpn_local_es_add(bgp, &esi, originator_ip, active, df_pref);
 
        return 0;
 }
@@ -2792,7 +2772,6 @@ static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS)
        struct stream *s = NULL;
        struct bgp *bgp_vrf = NULL;
        struct prefix p;
-       char buf[PREFIX_STRLEN];
 
        memset(&p, 0, sizeof(struct prefix));
        s = zclient->ibuf;
@@ -2803,8 +2782,7 @@ static void bgp_zebra_process_local_ip_prefix(ZAPI_CALLBACK_ARGS)
                return;
 
        if (BGP_DEBUG(zebra, ZEBRA))
-               zlog_debug("Recv prefix %s %s on vrf %s",
-                          prefix2str(&p, buf, sizeof(buf)),
+               zlog_debug("Recv prefix %pFX %s on vrf %s", &p,
                           (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
                           vrf_id_to_name(vrf_id));
 
index 426097054163cd6c765cbed5a4ee022df3035c02..0095a1cab062119a4daae9ed382505cb291c244a 100644 (file)
@@ -54,6 +54,7 @@
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_errors.h"
 #include "bgpd/bgp_community.h"
+#include "bgpd/bgp_conditional_adv.h"
 #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_regex.h"
 #include "bgpd/bgp_clist.h"
@@ -332,10 +333,9 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id)
                                if (bgp->established_peers == 0) {
                                        if (BGP_DEBUG(zebra, ZEBRA))
                                                zlog_debug(
-                                                       "RID change : vrf %s(%u), RTR ID %s",
+                                                       "RID change : vrf %s(%u), RTR ID %pI4",
                                                        bgp->name_pretty,
-                                                       bgp->vrf_id,
-                                                       inet_ntoa(*addr));
+                                                       bgp->vrf_id, addr);
                                        /*
                                         * if old router-id was 0x0, set flag
                                         * to use this new value
@@ -363,10 +363,9 @@ void bgp_router_id_zebra_bump(vrf_id_t vrf_id, const struct prefix *router_id)
                                if (bgp->established_peers == 0) {
                                        if (BGP_DEBUG(zebra, ZEBRA))
                                                zlog_debug(
-                                                       "RID change : vrf %s(%u), RTR ID %s",
+                                                       "RID change : vrf %s(%u), RTR ID %pI4",
                                                        bgp->name_pretty,
-                                                       bgp->vrf_id,
-                                                       inet_ntoa(*addr));
+                                                       bgp->vrf_id, addr);
                                        /*
                                         * if old router-id was 0x0, set flag
                                         * to use this new value
@@ -397,10 +396,6 @@ int bgp_cluster_id_set(struct bgp *bgp, struct in_addr *cluster_id)
        struct peer *peer;
        struct listnode *node, *nnode;
 
-       if (bgp_config_check(bgp, BGP_CONFIG_CLUSTER_ID)
-           && IPV4_ADDR_SAME(&bgp->cluster_id, cluster_id))
-               return 0;
-
        IPV4_ADDR_COPY(&bgp->cluster_id, cluster_id);
        bgp_config_set(bgp, BGP_CONFIG_CLUSTER_ID);
 
@@ -473,14 +468,14 @@ void bgp_timers_unset(struct bgp *bgp)
 }
 
 /* BGP confederation configuration.  */
-int bgp_confederation_id_set(struct bgp *bgp, as_t as)
+void bgp_confederation_id_set(struct bgp *bgp, as_t as)
 {
        struct peer *peer;
        struct listnode *node, *nnode;
        int already_confed;
 
        if (as == 0)
-               return BGP_ERR_INVALID_AS;
+               return;
 
        /* Remember - were we doing confederation before? */
        already_confed = bgp_config_check(bgp, BGP_CONFIG_CONFEDERATION);
@@ -528,7 +523,7 @@ int bgp_confederation_id_set(struct bgp *bgp, as_t as)
                        }
                }
        }
-       return 0;
+       return;
 }
 
 int bgp_confederation_id_unset(struct bgp *bgp)
@@ -2744,7 +2739,6 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
        struct listnode *node, *nnode;
        struct peer *peer;
        afi_t afi;
-       char buf[PREFIX2STR_BUFFER];
 
        afi = family2afi(range->family);
 
@@ -2757,8 +2751,6 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
        if (!prefix)
                return BGP_ERR_DYNAMIC_NEIGHBORS_RANGE_NOT_FOUND;
 
-       prefix2str(prefix, buf, sizeof(buf));
-
        /* Dispose off any dynamic neighbors that exist due to this listen range
         */
        for (ALL_LIST_ELEMENTS(group->peer, node, nnode, peer)) {
@@ -2769,8 +2761,8 @@ int peer_group_listen_range_del(struct peer_group *group, struct prefix *range)
                if (prefix_match(prefix, &prefix2)) {
                        if (bgp_debug_neighbor_events(peer))
                                zlog_debug(
-                                       "Deleting dynamic neighbor %s group %s upon delete of listen range %s",
-                                       peer->host, group->name, buf);
+                                       "Deleting dynamic neighbor %s group %s upon delete of listen range %pFX",
+                                       peer->host, group->name, prefix);
                        peer_delete(peer);
                }
        }
@@ -2987,6 +2979,8 @@ static struct bgp *bgp_create(as_t *as, const char *name,
        }
 
        bgp_lock(bgp);
+
+       bgp_process_queue_init(bgp);
        bgp->heuristic_coalesce = true;
        bgp->inst_type = inst_type;
        bgp->vrf_id = (inst_type == BGP_INSTANCE_TYPE_DEFAULT) ? VRF_DEFAULT
@@ -3028,7 +3022,7 @@ static struct bgp *bgp_create(as_t *as, const char *name,
                bgp->gr_info[afi][safi].eor_received = 0;
                bgp->gr_info[afi][safi].t_select_deferral = NULL;
                bgp->gr_info[afi][safi].t_route_select = NULL;
-               bgp->gr_info[afi][safi].route_list = list_new();
+               bgp->gr_info[afi][safi].gr_deferred = 0;
        }
 
        bgp->v_update_delay = bm->v_update_delay;
@@ -3242,12 +3236,10 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
                return bgp_check_main_socket(create, bgp);
 }
 
-/* Called from VTY commands. */
-int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
-           enum bgp_instance_type inst_type)
+int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *name,
+                              enum bgp_instance_type inst_type)
 {
        struct bgp *bgp;
-       struct vrf *vrf = NULL;
 
        /* Multiple instance check. */
        if (name)
@@ -3255,7 +3247,6 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
        else
                bgp = bgp_get_default();
 
-       /* Already exists. */
        if (bgp) {
                if (bgp->as != *as) {
                        *as = bgp->as;
@@ -3266,6 +3257,27 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
                *bgp_val = bgp;
                return BGP_SUCCESS;
        }
+       *bgp_val = NULL;
+
+       return BGP_SUCCESS;
+}
+
+/* Called from VTY commands. */
+int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
+           enum bgp_instance_type inst_type)
+{
+       struct bgp *bgp;
+       struct vrf *vrf = NULL;
+       int ret = 0;
+
+       ret = bgp_lookup_by_as_name_type(bgp_val, as, name, inst_type);
+       switch (ret) {
+       case BGP_ERR_INSTANCE_MISMATCH:
+               return ret;
+       case BGP_SUCCESS:
+               if (*bgp_val)
+                       return ret;
+       }
 
        bgp = bgp_create(as, name, inst_type);
        if (bgp_option_check(BGP_OPT_NO_ZEBRA) && name)
@@ -3382,14 +3394,21 @@ int bgp_delete(struct bgp *bgp)
 
        /* Delete the graceful restart info */
        FOREACH_AFI_SAFI (afi, safi) {
+               struct thread *t;
+
                gr_info = &bgp->gr_info[afi][safi];
                if (!gr_info)
                        continue;
 
                BGP_TIMER_OFF(gr_info->t_select_deferral);
+
+               t = gr_info->t_route_select;
+               if (t) {
+                       void *info = THREAD_ARG(t);
+
+                       XFREE(MTYPE_TMP, info);
+               }
                BGP_TIMER_OFF(gr_info->t_route_select);
-               if (gr_info->route_list)
-                       list_delete(&gr_info->route_list);
        }
 
        if (BGP_DEBUG(zebra, ZEBRA)) {
@@ -3493,6 +3512,9 @@ int bgp_delete(struct bgp *bgp)
                        bgp_set_evpn(bgp_get_default());
        }
 
+       if (bgp->process_queue)
+               work_queue_free_and_null(&bgp->process_queue);
+
        thread_master_free_unused(bm->master);
        bgp_unlock(bgp); /* initial reference */
 
@@ -3758,7 +3780,6 @@ struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
        struct prefix *listen_range;
        int dncount;
        char buf[PREFIX2STR_BUFFER];
-       char buf1[PREFIX2STR_BUFFER];
 
        sockunion2hostprefix(su, &prefix);
 
@@ -3775,12 +3796,11 @@ struct peer *peer_lookup_dynamic_neighbor(struct bgp *bgp, union sockunion *su)
                return NULL;
 
        prefix2str(&prefix, buf, sizeof(buf));
-       prefix2str(listen_range, buf1, sizeof(buf1));
 
        if (bgp_debug_neighbor_events(NULL))
                zlog_debug(
-                       "Dynamic Neighbor %s matches group %s listen range %s",
-                       buf, group->name, buf1);
+                       "Dynamic Neighbor %s matches group %s listen range %pFX",
+                       buf, group->name, listen_range);
 
        /* Are we within the listen limit? */
        dncount = gbgp->dynamic_neighbors_count;
@@ -6573,6 +6593,172 @@ int peer_unsuppress_map_unset(struct peer *peer, afi_t afi, safi_t safi)
        return 0;
 }
 
+static void peer_advertise_map_filter_update(struct peer *peer, afi_t afi,
+                                            safi_t safi, const char *amap_name,
+                                            struct route_map *amap,
+                                            const char *cmap_name,
+                                            struct route_map *cmap,
+                                            bool condition, bool set)
+{
+       struct bgp_filter *filter;
+       bool filter_exists = false;
+
+       filter = &peer->filter[afi][safi];
+
+       /* advertise-map is already configured. */
+       if (filter->advmap.aname) {
+               filter_exists = true;
+               XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.aname);
+               XFREE(MTYPE_BGP_FILTER_NAME, filter->advmap.cname);
+       }
+
+       route_map_counter_decrement(filter->advmap.amap);
+
+       /* Removed advertise-map configuration */
+       if (!set) {
+               memset(filter, 0, sizeof(struct bgp_filter));
+
+               /* decrement condition_filter_count delete timer if
+                * this is the last advertise-map to be removed.
+                */
+               if (filter_exists)
+                       bgp_conditional_adv_disable(peer, afi, safi);
+
+               return;
+       }
+
+       /* Update filter data with newly configured values. */
+       filter->advmap.aname = XSTRDUP(MTYPE_BGP_FILTER_NAME, amap_name);
+       filter->advmap.cname = XSTRDUP(MTYPE_BGP_FILTER_NAME, cmap_name);
+       filter->advmap.amap = amap;
+       filter->advmap.cmap = cmap;
+       filter->advmap.condition = condition;
+       route_map_counter_increment(filter->advmap.amap);
+       peer->advmap_config_change[afi][safi] = true;
+
+       /* Increment condition_filter_count and/or create timer. */
+       if (!filter_exists) {
+               filter->advmap.update_type = ADVERTISE;
+               bgp_conditional_adv_enable(peer, afi, safi);
+       }
+}
+
+/* Set advertise-map to the peer but do not process peer route updates here.  *
+ * Hold filter changes until the conditional routes polling thread is called  *
+ * AS we need to advertise/withdraw prefixes (in advertise-map) based on the  *
+ * condition (exist-map/non-exist-map) and routes(specified in condition-map) *
+ * in BGP table. So do not call peer_on_policy_change() here, only create     *
+ * polling timer thread, update filters and increment condition_filter_count.
+ */
+int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
+                          const char *advertise_name,
+                          struct route_map *advertise_map,
+                          const char *condition_name,
+                          struct route_map *condition_map, bool condition)
+{
+       struct peer *member;
+       struct listnode *node, *nnode;
+
+       /* Set configuration on peer. */
+       peer_advertise_map_filter_update(peer, afi, safi, advertise_name,
+                                        advertise_map, condition_name,
+                                        condition_map, condition, true);
+
+       /* Check if handling a regular peer & Skip peer-group mechanics. */
+       if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+               /* Set override-flag and process peer route updates. */
+               SET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
+                        PEER_FT_ADVERTISE_MAP);
+               return 0;
+       }
+
+       /*
+        * Set configuration on all peer-group members, unless they are
+        * explicitely overriding peer-group configuration.
+        */
+       for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
+               /* Skip peers with overridden configuration. */
+               if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
+                              PEER_FT_ADVERTISE_MAP))
+                       continue;
+
+               /* Set configuration on peer-group member. */
+               peer_advertise_map_filter_update(
+                       member, afi, safi, advertise_name, advertise_map,
+                       condition_name, condition_map, condition, true);
+       }
+
+       return 0;
+}
+
+/* Unset advertise-map from the peer. */
+int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
+                            const char *advertise_name,
+                            struct route_map *advertise_map,
+                            const char *condition_name,
+                            struct route_map *condition_map, bool condition)
+{
+       struct peer *member;
+       struct listnode *node, *nnode;
+
+       /* advertise-map is not configured */
+       if (!peer->filter[afi][safi].advmap.aname)
+               return 0;
+
+       /* Unset override-flag unconditionally. */
+       UNSET_FLAG(peer->filter_override[afi][safi][RMAP_OUT],
+                  PEER_FT_ADVERTISE_MAP);
+
+       /* Inherit configuration from peer-group if peer is member. */
+       if (peer_group_active(peer)) {
+               PEER_STR_ATTR_INHERIT(peer, peer->group,
+                                     filter[afi][safi].advmap.aname,
+                                     MTYPE_BGP_FILTER_NAME);
+               PEER_ATTR_INHERIT(peer, peer->group,
+                                 filter[afi][safi].advmap.amap);
+       } else
+               peer_advertise_map_filter_update(
+                       peer, afi, safi, advertise_name, advertise_map,
+                       condition_name, condition_map, condition, false);
+
+       /* Check if handling a regular peer and skip peer-group mechanics. */
+       if (!CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP)) {
+               /* Process peer route updates. */
+               if (BGP_DEBUG(update, UPDATE_OUT))
+                       zlog_debug("%s: Send normal update to %s for %s",
+                                  __func__, peer->host,
+                                  get_afi_safi_str(afi, safi, false));
+
+               peer_on_policy_change(peer, afi, safi, 1);
+               return 0;
+       }
+
+       /*
+        * Remove configuration on all peer-group members, unless they are
+        * explicitely overriding peer-group configuration.
+        */
+       for (ALL_LIST_ELEMENTS(peer->group->peer, node, nnode, member)) {
+               /* Skip peers with overridden configuration. */
+               if (CHECK_FLAG(member->filter_override[afi][safi][RMAP_OUT],
+                              PEER_FT_ADVERTISE_MAP))
+                       continue;
+               /* Remove configuration on peer-group member. */
+               peer_advertise_map_filter_update(
+                       member, afi, safi, advertise_name, advertise_map,
+                       condition_name, condition_map, condition, false);
+
+               /* Process peer route updates. */
+               if (BGP_DEBUG(update, UPDATE_OUT))
+                       zlog_debug("%s: Send normal update to %s for %s ",
+                                  __func__, member->host,
+                                  get_afi_safi_str(afi, safi, false));
+
+               peer_on_policy_change(member, afi, safi, 1);
+       }
+
+       return 0;
+}
+
 int peer_maximum_prefix_set(struct peer *peer, afi_t afi, safi_t safi,
                            uint32_t max, uint8_t threshold, int warning,
                            uint16_t restart, bool force)
@@ -7073,8 +7259,6 @@ void bgp_master_init(struct thread_master *master, const int buffer_size)
        bm->terminating = false;
        bm->socket_buffer = buffer_size;
 
-       bgp_process_queue_init();
-
        bgp_mac_init();
        /* init the rd id space.
           assign 0th index in the bitfield,
@@ -7279,14 +7463,10 @@ void bgp_terminate(void)
                                bgp_notify_send(peer, BGP_NOTIFY_CEASE,
                                                BGP_NOTIFY_CEASE_PEER_UNCONFIG);
 
-       if (bm->process_main_queue)
-               work_queue_free_and_null(&bm->process_main_queue);
-
        if (bm->t_rmap_update)
                BGP_TIMER_OFF(bm->t_rmap_update);
 
        bgp_mac_finish();
-       bgp_evpn_mh_finish();
 }
 
 struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
index 9f72a3e19e2a473a20f6db9a5506c1ab34bdc37a..480a3ad129545dc8cb92e1122848dcea865bcef0 100644 (file)
@@ -122,9 +122,6 @@ struct bgp_master {
        /* BGP thread master.  */
        struct thread_master *master;
 
-       /* work queues */
-       struct work_queue *process_main_queue;
-
        /* Listening sockets */
        struct list *listen_sockets;
 
@@ -268,8 +265,8 @@ struct graceful_restart_info {
        uint32_t eor_received;
        /* Deferral Timer */
        struct thread *t_select_deferral;
-       /* Route list */
-       struct list *route_list;
+       /* Routes Deferred */
+       uint32_t gr_deferred;
        /* Best route select */
        struct thread *t_route_select;
        /* AFI, SAFI enabled */
@@ -391,8 +388,9 @@ struct bgp {
                *t_maxmed_onstartup; /* non-null when max-med onstartup is on */
        uint8_t maxmed_onstartup_over; /* Flag to make it effective only once */
 
-       uint8_t v_maxmed_admin; /* 1/0 if max-med administrative is on/off */
-#define BGP_MAXMED_ADMIN_UNCONFIGURED  0 /* Off by default */
+       bool v_maxmed_admin; /* true/false if max-med administrative is on/off
+                             */
+#define BGP_MAXMED_ADMIN_UNCONFIGURED false /* Off by default */
        uint32_t maxmed_admin_value; /* Max-med value when administrative in on
                                      */
 #define BGP_MAXMED_VALUE_DEFAULT  4294967294 /* Maximum by default */
@@ -681,6 +679,13 @@ struct bgp {
        /* Weighted ECMP related config. */
        enum bgp_link_bw_handling lb_handling;
 
+       /* Process Queue for handling routes */
+       struct work_queue *process_queue;
+
+       /* BGP Conditional advertisement */
+       uint32_t condition_filter_count;
+       struct thread *t_condition_check;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp)
@@ -758,6 +763,12 @@ struct bgp_nexthop {
 #define BGP_GTSM_HOPS_DISABLED  0
 #define BGP_GTSM_HOPS_CONNECTED 1
 
+/* Advertise map */
+#define CONDITION_NON_EXIST    false
+#define CONDITION_EXIST                true
+
+enum update_type { WITHDRAW, ADVERTISE };
+
 #include "filter.h"
 
 /* BGP filter structure. */
@@ -791,6 +802,19 @@ struct bgp_filter {
                char *name;
                struct route_map *map;
        } usmap;
+
+       /* Advertise-map */
+       struct {
+               char *aname;
+               struct route_map *amap;
+
+               bool condition;
+
+               char *cname;
+               struct route_map *cmap;
+
+               enum update_type update_type;
+       } advmap;
 };
 
 /* IBGP/EBGP identifier.  We also have a CONFED peer, which is to say,
@@ -1354,6 +1378,7 @@ struct peer {
 #define PEER_FT_PREFIX_LIST           (1U << 2) /* prefix-list */
 #define PEER_FT_ROUTE_MAP             (1U << 3) /* route-map */
 #define PEER_FT_UNSUPPRESS_MAP        (1U << 4) /* unsuppress-map */
+#define PEER_FT_ADVERTISE_MAP         (1U << 5) /* advertise-map */
 
        /* ORF Prefix-list */
        struct prefix_list *orf_plist[AFI_MAX][SAFI_MAX];
@@ -1447,6 +1472,10 @@ struct peer {
        /* Sender side AS path loop detection. */
        bool as_path_loop_detection;
 
+       /* Conditional advertisement */
+       bool advmap_config_change[AFI_MAX][SAFI_MAX];
+       bool advmap_table_change;
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(peer)
@@ -1827,7 +1856,7 @@ extern void bgp_router_id_static_set(struct bgp *, struct in_addr);
 extern int bgp_cluster_id_set(struct bgp *, struct in_addr *);
 extern int bgp_cluster_id_unset(struct bgp *);
 
-extern int bgp_confederation_id_set(struct bgp *, as_t);
+extern void bgp_confederation_id_set(struct bgp *, as_t);
 extern int bgp_confederation_id_unset(struct bgp *);
 extern bool bgp_confederation_peers_check(struct bgp *, as_t);
 
@@ -1938,11 +1967,25 @@ extern int peer_unsuppress_map_set(struct peer *peer, afi_t afi, safi_t safi,
                                   const char *name,
                                   struct route_map *route_map);
 
+extern int peer_advertise_map_set(struct peer *peer, afi_t afi, safi_t safi,
+                                 const char *advertise_name,
+                                 struct route_map *advertise_map,
+                                 const char *condition_name,
+                                 struct route_map *condition_map,
+                                 bool condition);
+
 extern int peer_password_set(struct peer *, const char *);
 extern int peer_password_unset(struct peer *);
 
 extern int peer_unsuppress_map_unset(struct peer *, afi_t, safi_t);
 
+extern int peer_advertise_map_unset(struct peer *peer, afi_t afi, safi_t safi,
+                                   const char *advertise_name,
+                                   struct route_map *advertise_map,
+                                   const char *condition_name,
+                                   struct route_map *condition_map,
+                                   bool condition);
+
 extern int peer_maximum_prefix_set(struct peer *, afi_t, safi_t, uint32_t,
                                   uint8_t, int, uint16_t, bool force);
 extern int peer_maximum_prefix_unset(struct peer *, afi_t, safi_t);
@@ -2180,6 +2223,9 @@ extern struct peer *peer_new(struct bgp *bgp);
 
 extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
                                        const char *ip_str, bool use_json);
+extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,
+                                     const char *name,
+                                     enum bgp_instance_type inst_type);
 
 /* Hooks */
 DECLARE_HOOK(peer_status_changed, (struct peer * peer), (peer))
index 2bcef97fc3d04d3c4afee64f734c6e969f33b7be..88c92f7954ad89319f11ef1d0828419952478ee5 100644 (file)
@@ -170,14 +170,8 @@ struct rfapi_nve_group_cfg *bgp_rfapi_cfg_match_group(struct rfapi_cfg *hc,
 
 #ifdef BGP_VNC_DEBUG_MATCH_GROUP
        {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(vn, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s: vn prefix: %s", __func__, buf);
-
-               prefix2str(un, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s: un prefix: %s", __func__, buf);
-
+               vnc_zlog_debug_verbose("%s: vn prefix: %pFX", __func__, vn);
+               vnc_zlog_debug_verbose("%s: un prefix: %pFX", __func__, un);
                vnc_zlog_debug_verbose(
                        "%s: rn_vn=%p, rn_un=%p, rfg_vn=%p, rfg_un=%p",
                        __func__, rn_vn, rn_un, rfg_vn, rfg_un);
@@ -4215,23 +4209,13 @@ int bgp_rfapi_cfg_write(struct vty *vty, struct bgp *bgp)
                                ++write;
                                vty_out(vty, " vnc nve-group %s\n", rfg->name);
 
-                               if (rfg->vn_prefix.family && rfg->vn_node) {
-                                       char buf[PREFIX_STRLEN];
+                               if (rfg->vn_prefix.family && rfg->vn_node)
+                                       vty_out(vty, "  prefix %s %pFX\n", "vn",
+                                               &rfg->vn_prefix);
 
-                                       prefix2str(&rfg->vn_prefix, buf,
-                                                  sizeof(buf));
-                                       vty_out(vty, "  prefix %s %s\n", "vn",
-                                               buf);
-                               }
-
-                               if (rfg->un_prefix.family && rfg->un_node) {
-                                       char buf[PREFIX_STRLEN];
-
-                                       prefix2str(&rfg->un_prefix, buf,
-                                                  sizeof(buf));
-                                       vty_out(vty, "  prefix %s %s\n", "un",
-                                               buf);
-                               }
+                               if (rfg->un_prefix.family && rfg->un_node)
+                                       vty_out(vty, "  prefix %s %pFX\n", "un",
+                                               &rfg->un_prefix);
 
 
                                if (rfg->rd.prefixlen) {
index 0ff4b2c825103f14c64cecfd0912d5a51ae63295..2d81a6ce65c1e0c2f69158da0d622900a23f6619 100644 (file)
@@ -362,12 +362,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
        afi_t afi; /* of the VN address */
        struct bgp_dest *bn;
        struct bgp_path_info *bpi;
-       char buf[PREFIX_STRLEN];
        char buf2[RD_ADDRSTRLEN];
        struct prefix_rd prd0;
 
-       prefix2str(p, buf, sizeof(buf));
-
        afi = family2afi(p->family);
        assert(afi == AFI_IP || afi == AFI_IP6);
 
@@ -380,9 +377,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
        bn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
 
        vnc_zlog_debug_verbose(
-               "%s: peer=%p, prefix=%s, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
-               __func__, peer, buf, prefix_rd2str(prd, buf2, sizeof(buf2)),
-               afi, safi, bn, (bn ? bgp_dest_get_bgp_path_info(bn) : NULL));
+               "%s: peer=%p, prefix=%pFX, prd=%s afi=%d, safi=%d bn=%p, bn->info=%p",
+               __func__, peer, p, prefix_rd2str(prd, buf2, sizeof(buf2)), afi,
+               safi, bn, (bn ? bgp_dest_get_bgp_path_info(bn) : NULL));
 
        for (bpi = (bn ? bgp_dest_get_bgp_path_info(bn) : NULL); bpi;
             bpi = bpi->next) {
@@ -418,8 +415,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
                         * no local nexthops
                         */
                        vnc_zlog_debug_verbose(
-                               "%s: lnh list already empty at prefix %s",
-                               __func__, buf);
+                               "%s: lnh list already empty at prefix %pFX",
+                               __func__, p);
                        goto done;
                }
 
@@ -445,8 +442,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
                         * list->del on data */
                        rfapi_nexthop_free(pLnh);
                } else {
-                       vnc_zlog_debug_verbose("%s: desired lnh not found %s",
-                                              __func__, buf);
+                       vnc_zlog_debug_verbose("%s: desired lnh not found %pFX",
+                                              __func__, p);
                }
                goto done;
        }
@@ -459,10 +456,9 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
        rfapiProcessWithdraw(peer, rfd, p, prd, NULL, afi, safi, type, kill);
 
        if (bpi) {
-               prefix2str(p, buf, sizeof(buf));
                vnc_zlog_debug_verbose(
-                       "%s: Found route (safi=%d) to delete at prefix %s",
-                       __func__, safi, buf);
+                       "%s: Found route (safi=%d) to delete at prefix %pFX",
+                       __func__, safi, p);
 
                if (safi == SAFI_MPLS_VPN) {
                        struct bgp_dest *pdest = NULL;
@@ -488,8 +484,8 @@ void del_vnc_route(struct rfapi_descriptor *rfd,
                bgp_process(bgp, bn, afi, safi);
        } else {
                vnc_zlog_debug_verbose(
-                       "%s: Couldn't find route (safi=%d) at prefix %s",
-                       __func__, safi, buf);
+                       "%s: Couldn't find route (safi=%d) at prefix %pFX",
+                       __func__, safi, p);
        }
 done:
        bgp_dest_unlock_node(bn);
@@ -1577,12 +1573,10 @@ rfapi_query_inner(void *handle, struct rfapi_ip_addr *target,
        }
 
        {
-               char buf[PREFIX_STRLEN];
                char *s;
 
-               prefix2str(&p, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s(rfd=%p, target=%s, ppNextHop=%p)",
-                                      __func__, rfd, buf, ppNextHopEntry);
+               vnc_zlog_debug_verbose("%s(rfd=%p, target=%pFX, ppNextHop=%p)",
+                                      __func__, rfd, &p, ppNextHopEntry);
 
                s = ecommunity_ecom2str(rfd->import_table->rt_import_list,
                                        ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
@@ -2397,16 +2391,10 @@ int rfapi_register(void *handle, struct rfapi_ip_prefix *prefix,
        afi = family2afi(prefix->prefix.addr_family);
        assert(afi);
 
-
-       {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(&p, buf, sizeof(buf));
-               vnc_zlog_debug_verbose(
-                       "%s(rfd=%p, pfx=%s, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)",
-                       __func__, rfd, buf, lifetime, options_un, options_vn,
-                       action_str);
-       }
+       vnc_zlog_debug_verbose(
+               "%s(rfd=%p, pfx=%pFX, lifetime=%d, opts_un=%p, opts_vn=%p, action=%s)",
+               __func__, rfd, &p, lifetime, options_un, options_vn,
+               action_str);
 
        /*
         * These tests come after the prefix conversion so that we can
index c3ad95ff28d4b7f0a351ffd1134a3efbf09d3299..e3581addee13909e146b04e0e72c68d021d4643a 100644 (file)
@@ -265,11 +265,12 @@ void rfapiCheckRefcount(struct agg_node *rn, safi_t safi, int lockoffset)
                }
        }
 
-       if (count_bpi + count_monitor + lockoffset != rn->lock) {
+       if (count_bpi + count_monitor + lockoffset
+           != agg_node_get_lock_count(rn)) {
                vnc_zlog_debug_verbose(
                        "%s: count_bpi=%d, count_monitor=%d, lockoffset=%d, rn->lock=%d",
                        __func__, count_bpi, count_monitor, lockoffset,
-                       rn->lock);
+                       agg_node_get_lock_count(rn));
                assert(0);
        }
 }
@@ -611,11 +612,8 @@ rfapiMonitorMoveShorter(struct agg_node *original_vpn_node, int lockoffset)
 
 #ifdef DEBUG_MONITOR_MOVE_SHORTER
        {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(&original_vpn_node->p, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s: called with node pfx=%s", __func__,
-                                      buf);
+               vnc_zlog_debug_verbose("%s: called with node pfx=%pFX",
+                                      __func__, &original_vpn_node->p);
        }
 #endif
 
@@ -750,11 +748,8 @@ rfapiMonitorMoveShorter(struct agg_node *original_vpn_node, int lockoffset)
 
 #ifdef DEBUG_MONITOR_MOVE_SHORTER
        {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(&par->p, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s: moved to node pfx=%s", __func__,
-                                      buf);
+               vnc_zlog_debug_verbose("%s: moved to node pfx=%pFX", __func__,
+                                      &par->p);
        }
 #endif
 
@@ -863,9 +858,9 @@ static void rfapiBgpInfoChainFree(struct bgp_path_info *bpi)
                if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
                    && bpi->extra->vnc.import.timer) {
 
-                       struct thread *t =
-                               (struct thread *)bpi->extra->vnc.import.timer;
-                       struct rfapi_withdraw *wcb = t->arg;
+                       struct thread **t =
+                               &(bpi->extra->vnc.import.timer);
+                       struct rfapi_withdraw *wcb = (*t)->arg;
 
                        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
                        thread_cancel(t);
@@ -1555,12 +1550,9 @@ static int rfapiNhlAddNodeRoutes(
                }
                if (!skiplist_search(seen_nexthops, &pfx_vn, NULL)) {
 #ifdef DEBUG_RETURNED_NHL
-                       char buf[PREFIX_STRLEN];
-
-                       prefix2str(&pfx_vn, buf, sizeof(buf));
                        vnc_zlog_debug_verbose(
-                               "%s: already put VN/nexthop %s, skip", __func__,
-                               buf);
+                               "%s: already put VN/nexthop %pFX, skip",
+                               __func__, &pfx_vn);
 #endif
                        continue;
                }
@@ -3101,10 +3093,9 @@ static void rfapiBgpInfoFilteredImportEncap(
                                if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
                                    && bpi->extra->vnc.import.timer) {
 
-                                       struct thread *t =
-                                               (struct thread *)bpi->extra->vnc
-                                                       .import.timer;
-                                       struct rfapi_withdraw *wcb = t->arg;
+                                       struct thread **t =
+                                               &(bpi->extra->vnc.import.timer);
+                                       struct rfapi_withdraw *wcb = (*t)->arg;
 
                                        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
                                        thread_cancel(t);
@@ -3194,9 +3185,9 @@ static void rfapiBgpInfoFilteredImportEncap(
                        "%s: removing holddown bpi matching NVE of new route",
                        __func__);
                if (bpi->extra->vnc.import.timer) {
-                       struct thread *t =
-                               (struct thread *)bpi->extra->vnc.import.timer;
-                       struct rfapi_withdraw *wcb = t->arg;
+                       struct thread **t =
+                               &(bpi->extra->vnc.import.timer);
+                       struct rfapi_withdraw *wcb = (*t)->arg;
 
                        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
                        thread_cancel(t);
@@ -3557,10 +3548,9 @@ void rfapiBgpInfoFilteredImportVPN(
                                if (CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)
                                    && bpi->extra->vnc.import.timer) {
 
-                                       struct thread *t =
-                                               (struct thread *)bpi->extra->vnc
-                                                       .import.timer;
-                                       struct rfapi_withdraw *wcb = t->arg;
+                                       struct thread **t =
+                                               &(bpi->extra->vnc.import.timer);
+                                       struct rfapi_withdraw *wcb = (*t)->arg;
 
                                        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
                                        thread_cancel(t);
@@ -3633,12 +3623,9 @@ void rfapiBgpInfoFilteredImportVPN(
                rfapiCopyUnEncap2VPN(ern->info, info_new);
                agg_unlock_node(ern); /* undo lock in route_note_match */
        } else {
-               char bpf[PREFIX_STRLEN];
-
-               prefix2str(&vn_prefix, bpf, sizeof(bpf));
                /* Not a big deal, just means VPN route got here first */
-               vnc_zlog_debug_verbose("%s: no encap route for vn addr %s",
-                                      __func__, bpf);
+               vnc_zlog_debug_verbose("%s: no encap route for vn addr %pFX",
+                                      __func__, &vn_prefix);
                info_new->extra->vnc.import.un_family = 0;
        }
 
@@ -3665,7 +3652,8 @@ void rfapiBgpInfoFilteredImportVPN(
        }
 
        vnc_zlog_debug_verbose("%s: inserting bpi %p at prefix %pRN #%d",
-                              __func__, info_new, rn, rn->lock);
+                              __func__, info_new, rn,
+                              agg_node_get_lock_count(rn));
 
        rfapiBgpInfoAttachSorted(rn, info_new, afi, SAFI_MPLS_VPN);
        rfapiItBiIndexAdd(rn, info_new);
@@ -3778,9 +3766,9 @@ void rfapiBgpInfoFilteredImportVPN(
                        "%s: removing holddown bpi matching NVE of new route",
                        __func__);
                if (bpi->extra->vnc.import.timer) {
-                       struct thread *t =
-                               (struct thread *)bpi->extra->vnc.import.timer;
-                       struct rfapi_withdraw *wcb = t->arg;
+                       struct thread **t =
+                               &(bpi->extra->vnc.import.timer);
+                       struct rfapi_withdraw *wcb = (*t)->arg;
 
                        XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
                        thread_cancel(t);
@@ -4439,13 +4427,9 @@ static void rfapiDeleteRemotePrefixesIt(
                        struct bgp_path_info *next;
                        const struct prefix *rn_p = agg_node_get_prefix(rn);
 
-                       if (p && VNC_DEBUG(IMPORT_DEL_REMOTE)) {
-                               char p1line[PREFIX_STRLEN];
-
-                               prefix2str(p, p1line, sizeof(p1line));
-                               vnc_zlog_debug_any("%s: want %s, have %pRN",
-                                                  __func__, p1line, rn);
-                       }
+                       if (p && VNC_DEBUG(IMPORT_DEL_REMOTE))
+                               vnc_zlog_debug_any("%s: want %pFX, have %pRN",
+                                                  __func__, p, rn);
 
                        if (p && prefix_cmp(p, rn_p))
                                continue;
@@ -4512,12 +4496,11 @@ static void rfapiDeleteRemotePrefixesIt(
                                                continue;
                                        if (bpi->extra->vnc.import.timer) {
 
-                                               struct thread *t =
-                                                       (struct thread *)bpi
-                                                               ->extra->vnc
-                                                               .import.timer;
+                                               struct thread **t =
+                                                       &(bpi->extra->vnc
+                                                               .import.timer);
                                                struct rfapi_withdraw *wcb =
-                                                       t->arg;
+                                                       (*t)->arg;
 
                                                wcb->import_table
                                                        ->holddown_count[afi] -=
index cd26892b84d486e044aaa296499a0888252f0bd5..ce916c104b3b7c1f90be7a6eef74c851a0655ec5 100644 (file)
@@ -620,10 +620,7 @@ void rfapiMonitorDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
                rfapiMonitorDetachImport(m);
        }
 
-       if (m->timer) {
-               thread_cancel(m->timer);
-               m->timer = NULL;
-       }
+       thread_cancel(&m->timer);
 
        /*
         * remove from rfd list
@@ -660,10 +657,7 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd)
                                        rfapiMonitorDetachImport(m);
                                }
 
-                               if (m->timer) {
-                                       thread_cancel(m->timer);
-                                       m->timer = NULL;
-                               }
+                               thread_cancel(&m->timer);
 
                                XFREE(MTYPE_RFAPI_MONITOR, m);
                                rn->info = NULL;
@@ -697,10 +691,7 @@ int rfapiMonitorDelHd(struct rfapi_descriptor *rfd)
 #endif
                        }
 
-                       if (mon_eth->timer) {
-                               thread_cancel(mon_eth->timer);
-                               mon_eth->timer = NULL;
-                       }
+                       thread_cancel(&mon_eth->timer);
 
                        /*
                         * remove from rfd list
@@ -766,8 +757,7 @@ static void rfapiMonitorTimerRestart(struct rfapi_monitor_vpn *m)
                if (m->rfd->response_lifetime - remain < 2)
                        return;
 
-               thread_cancel(m->timer);
-               m->timer = NULL;
+               thread_cancel(&m->timer);
        }
 
        {
@@ -846,9 +836,6 @@ void rfapiMonitorItNodeChanged(
        struct bgp *bgp = bgp_get_default();
        const struct prefix *p = agg_node_get_prefix(rn);
        afi_t afi = family2afi(p->family);
-#if DEBUG_L2_EXTRA
-       char buf_prefix[PREFIX_STRLEN];
-#endif
 
        assert(bgp);
        assert(import_table);
@@ -856,9 +843,8 @@ void rfapiMonitorItNodeChanged(
        nves_seen = skiplist_new(0, NULL, NULL);
 
 #if DEBUG_L2_EXTRA
-       prefix2str(&it_node->p, buf_prefix, sizeof(buf_prefix));
-       vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%s",
-                              __func__, import_table, it_node, buf_prefix);
+       vnc_zlog_debug_verbose("%s: it=%p, it_node=%p, it_node->prefix=%pFX",
+                              __func__, import_table, it_node, &it_node->p);
 #endif
 
        if (AFI_L2VPN == afi) {
@@ -934,14 +920,10 @@ void rfapiMonitorItNodeChanged(
                                        assert(!skiplist_insert(nves_seen,
                                                                m->rfd, NULL));
 
-                                       char buf_target_pfx[PREFIX_STRLEN];
-
-                                       prefix2str(&m->p, buf_target_pfx,
-                                                  sizeof(buf_target_pfx));
                                        vnc_zlog_debug_verbose(
-                                               "%s: update rfd %p attached to pfx %pRN (targ=%s)",
+                                               "%s: update rfd %p attached to pfx %pRN (targ=%pFX)",
                                                __func__, m->rfd, m->node,
-                                               buf_target_pfx);
+                                               &m->p);
 
                                        /*
                                         * update its RIB
@@ -1086,8 +1068,7 @@ static void rfapiMonitorEthTimerRestart(struct rfapi_monitor_eth *m)
                if (m->rfd->response_lifetime - remain < 2)
                        return;
 
-               thread_cancel(m->timer);
-               m->timer = NULL;
+               thread_cancel(&m->timer);
        }
 
        {
@@ -1269,21 +1250,15 @@ static void rfapiMonitorEthDetachImport(
        rn = agg_node_get(it->imported_vpn[AFI_L2VPN], &pfx_mac_buf);
        assert(rn);
 
-#if DEBUG_L2_EXTRA
-       char buf_prefix[PREFIX_STRLEN];
-
-       prefix2str(agg_node_get_prefix(rn), buf_prefix, sizeof(buf_prefix));
-#endif
-
        /*
         * Get sl to detach from
         */
        sl = RFAPI_MONITOR_ETH(rn);
 #if DEBUG_L2_EXTRA
        vnc_zlog_debug_verbose(
-               "%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%s, LNI=%d, detaching eth mon %p",
-               __func__, it, rn, rn->lock, sl, buf_prefix, mon->logical_net_id,
-               mon);
+               "%s: it=%p, rn=%p, rn->lock=%d, sl=%p, pfx=%pFX, LNI=%d, detaching eth mon %p",
+               __func__, it, rn, rn->lock, sl, agg_node_get_prefix(rn),
+               mon->logical_net_id, mon);
 #endif
        assert(sl);
 
@@ -1432,10 +1407,7 @@ void rfapiMonitorEthDel(struct bgp *bgp, struct rfapi_descriptor *rfd,
                rfapiMonitorEthDetachImport(bgp, val);
        }
 
-       if (val->timer) {
-               thread_cancel(val->timer);
-               val->timer = NULL;
-       }
+       thread_cancel(&val->timer);
 
        /*
         * remove from rfd list
index e068eb7af62ce8a74e7416b08c65582c8e225d99..630a379ec2163e1a5f8af12faca97867fbb0bc36 100644 (file)
@@ -269,9 +269,8 @@ static void rfapi_info_free(struct rfapi_info *goner)
                        struct rfapi_rib_tcb *tcb;
 
                        tcb = goner->timer->arg;
-                       thread_cancel(goner->timer);
+                       thread_cancel(&goner->timer);
                        XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
-                       goner->timer = NULL;
                }
                XFREE(MTYPE_RFAPI_INFO, goner);
        }
@@ -338,13 +337,11 @@ static void rfapiRibStartTimer(struct rfapi_descriptor *rfd,
                               struct agg_node *rn, /* route node attached to */
                               int deleted)
 {
-       struct thread *t = ri->timer;
        struct rfapi_rib_tcb *tcb = NULL;
 
-       if (t) {
-               tcb = t->arg;
-               thread_cancel(t);
-               ri->timer = NULL;
+       if (ri->timer) {
+               tcb = ri->timer->arg;
+               thread_cancel(&ri->timer);
        } else {
                tcb = XCALLOC(MTYPE_RFAPI_RECENT_DELETE,
                              sizeof(struct rfapi_rib_tcb));
@@ -802,7 +799,7 @@ int rfapiRibPreloadBi(
         */
        trn = agg_node_get(rfd->rsp_times[afi], p); /* locks trn */
        trn->info = (void *)(uintptr_t)bgp_clock();
-       if (trn->lock > 1)
+       if (agg_node_get_lock_count(trn) > 1)
                agg_unlock_node(trn);
 
        return 0;
@@ -907,10 +904,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                        delete_list = list_new();
                        while (0
                               == skiplist_first(slRibPt, NULL, (void **)&ri)) {
-
-                               char buf[PREFIX_STRLEN];
-                               char buf2[PREFIX_STRLEN];
-
                                listnode_add(delete_list, ri);
                                vnc_zlog_debug_verbose(
                                        "%s: after listnode_add, delete_list->count=%d",
@@ -921,18 +914,15 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                                if (ri->timer) {
                                        struct rfapi_rib_tcb *tcb;
 
-                                       tcb = ((struct thread *)ri->timer)->arg;
-                                       thread_cancel(ri->timer);
+                                       tcb = ri->timer->arg;
+                                       thread_cancel(&ri->timer);
                                        XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
-                                       ri->timer = NULL;
                                }
 
-                               prefix2str(&ri->rk.vn, buf, sizeof(buf));
-                               prefix2str(&ri->un, buf2, sizeof(buf2));
                                vnc_zlog_debug_verbose(
-                                       "%s:   put dl pfx=%pRN vn=%s un=%s cost=%d life=%d vn_options=%p",
-                                       __func__, pn, buf, buf2, ri->cost,
-                                       ri->lifetime, ri->vn_options);
+                                       "%s:   put dl pfx=%pRN vn=%pFX un=%pFX cost=%d life=%d vn_options=%p",
+                                       __func__, pn, &ri->rk.vn, &ri->un,
+                                       ri->cost, ri->lifetime, ri->vn_options);
 
                                skiplist_delete_first(slRibPt);
                        }
@@ -1009,11 +999,9 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
                                if (ori->timer) {
                                        struct rfapi_rib_tcb *tcb;
 
-                                       tcb = ((struct thread *)ori->timer)
-                                                     ->arg;
-                                       thread_cancel(ori->timer);
+                                       tcb = ori->timer->arg;
+                                       thread_cancel(&ori->timer);
                                        XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
-                                       ori->timer = NULL;
                                }
 
 #if DEBUG_PROCESS_PENDING_NODE
@@ -1242,7 +1230,7 @@ callback:
                        trn = agg_node_get(rfd->rsp_times[afi],
                                           p); /* locks trn */
                        trn->info = (void *)(uintptr_t)bgp_clock();
-                       if (trn->lock > 1)
+                       if (agg_node_get_lock_count(trn) > 1)
                                agg_unlock_node(trn);
 
                        rfapiRfapiIpAddr2Str(&new->vn_address, buf, BUFSIZ);
@@ -1357,11 +1345,9 @@ callback:
                                if (ri->timer) {
                                        struct rfapi_rib_tcb *tcb;
 
-                                       tcb = ((struct thread *)ri->timer)->arg;
-                                       thread_cancel(
-                                               (struct thread *)ri->timer);
+                                       tcb = ri->timer->arg;
+                                       thread_cancel(&ri->timer);
                                        XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
-                                       ri->timer = NULL;
                                }
                                RFAPI_RIB_CHECK_COUNTS(0, delete_list->count);
 
@@ -1589,7 +1575,6 @@ void rfapiRibUpdatePendingNode(
        afi_t afi;
        uint32_t queued_flag;
        int count = 0;
-       char buf[PREFIX_STRLEN];
 
        vnc_zlog_debug_verbose("%s: entry", __func__);
 
@@ -1602,8 +1587,7 @@ void rfapiRibUpdatePendingNode(
 
        prefix = agg_node_get_prefix(it_node);
        afi = family2afi(prefix->family);
-       prefix2str(prefix, buf, sizeof(buf));
-       vnc_zlog_debug_verbose("%s: prefix=%s", __func__, buf);
+       vnc_zlog_debug_verbose("%s: prefix=%pFX", __func__, prefix);
 
        pn = agg_node_get(rfd->rib_pending[afi], prefix);
        assert(pn);
@@ -1809,11 +1793,8 @@ int rfapiRibFTDFilterRecentPrefix(
 
 #ifdef DEBUG_FTD_FILTER_RECENT
        {
-               char buf_pfx[PREFIX_STRLEN];
-
-               prefix2str(agg_node_get_prefix(it_rn), buf_pfx,
-                          sizeof(buf_pfx));
-               vnc_zlog_debug_verbose("%s: prefix %s", __func__, buf_pfx);
+               vnc_zlog_debug_verbose("%s: prefix %pFX", __func__,
+                                      agg_node_get_prefix(it_rn));
        }
 #endif
 
@@ -1833,7 +1814,7 @@ int rfapiRibFTDFilterRecentPrefix(
         */
        trn = agg_node_get(rfd->rsp_times[afi], p); /* locks trn */
        prefix_time = (time_t)trn->info;
-       if (trn->lock > 1)
+       if (agg_node_get_lock_count(trn) > 1)
                agg_unlock_node(trn);
 
 #ifdef DEBUG_FTD_FILTER_RECENT
@@ -1974,21 +1955,18 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
 
 #if DEBUG_NHL
                {
-                       char str_vn[PREFIX_STRLEN];
                        char str_aux_prefix[PREFIX_STRLEN];
 
-                       str_vn[0] = 0;
                        str_aux_prefix[0] = 0;
 
-                       prefix2str(&rk.vn, str_vn, sizeof(str_vn));
                        prefix2str(&rk.aux_prefix, str_aux_prefix,
                                   sizeof(str_aux_prefix));
 
                        if (!rk.aux_prefix.family) {
                        }
                        vnc_zlog_debug_verbose(
-                               "%s:   rk.vn=%s rk.aux_prefix=%s", __func__,
-                               str_vn,
+                               "%s:   rk.vn=%pFX rk.aux_prefix=%s", __func__,
+                               &rk.vn,
                                (rk.aux_prefix.family ? str_aux_prefix : "-"));
                }
                vnc_zlog_debug_verbose(
@@ -2069,20 +2047,13 @@ rfapiRibPreload(struct bgp *bgp, struct rfapi_descriptor *rfd,
                 */
                trn = agg_node_get(rfd->rsp_times[afi], &pfx); /* locks trn */
                trn->info = (void *)(uintptr_t)bgp_clock();
-               if (trn->lock > 1)
+               if (agg_node_get_lock_count(trn) > 1)
                        agg_unlock_node(trn);
 
-               {
-                       char str_pfx[PREFIX_STRLEN];
-                       char str_pfx_vn[PREFIX_STRLEN];
-
-                       prefix2str(&pfx, str_pfx, sizeof(str_pfx));
-                       prefix2str(&rk.vn, str_pfx_vn, sizeof(str_pfx_vn));
-                       vnc_zlog_debug_verbose(
-                               "%s:   added pfx=%s nh[vn]=%s, cost=%u, lifetime=%u, allowed=%d",
-                               __func__, str_pfx, str_pfx_vn, nhp->prefix.cost,
-                               nhp->lifetime, allowed);
-               }
+               vnc_zlog_debug_verbose(
+                       "%s:   added pfx=%pFX nh[vn]=%pFX, cost=%u, lifetime=%u, allowed=%d",
+                       __func__, &pfx, &rk.vn, nhp->prefix.cost, nhp->lifetime,
+                       allowed);
 
                if (allowed) {
                        if (tail)
index d74404ea564d518986d205d2778cea11af1acb2c..b9a6c4ddc4e9aa802ff2e57d57d11157f4568e80 100644 (file)
@@ -751,7 +751,7 @@ void rfapiShowItNode(void *stream, struct agg_node *rn)
        if (rfapiStream2Vty(stream, &fp, &vty, &out, &vty_newline) == 0)
                return;
 
-       fp(out, "%pRN @%p #%d%s", rn, rn, rn->lock, HVTYNL);
+       fp(out, "%pRN @%p #%d%s", rn, rn, agg_node_get_lock_count(rn), HVTYNL);
 
        for (bpi = rn->info; bpi; bpi = bpi->next) {
                rfapiPrintBi(stream, bpi);
@@ -787,7 +787,8 @@ void rfapiShowImportTable(void *stream, const char *label, struct agg_table *rt,
                }
 
                fp(out, "%s/%d @%p #%d%s", buf, p->prefixlen, rn,
-                  rn->lock - 1, /* account for loop iterator locking */
+                  agg_node_get_lock_count(rn)
+                          - 1, /* account for loop iterator locking */
                   HVTYNL);
 
                for (bpi = rn->info; bpi; bpi = bpi->next) {
@@ -1595,7 +1596,6 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)
        int rc;
        afi_t afi;
        struct rfapi_adb *adb;
-       char buf[PREFIX_STRLEN];
 
        vty_out(vty, "%-10p ", rfd);
        rfapiPrintRfapiIpAddr(vty, &rfd->un_addr);
@@ -1647,9 +1647,8 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)
                        if (family != adb->u.s.prefix_ip.family)
                                continue;
 
-                       prefix2str(&adb->u.s.prefix_ip, buf, sizeof(buf));
-
-                       vty_out(vty, "  Adv Pfx: %s%s", buf, HVTYNL);
+                       vty_out(vty, "  Adv Pfx: %pFX%s", &adb->u.s.prefix_ip,
+                               HVTYNL);
                        rfapiPrintAdvertisedInfo(vty, rfd, SAFI_MPLS_VPN,
                                                 &adb->u.s.prefix_ip);
                }
@@ -1658,10 +1657,7 @@ void rfapiPrintDescriptor(struct vty *vty, struct rfapi_descriptor *rfd)
                                (void **)&adb, &cursor);
             rc == 0; rc = skiplist_next(rfd->advertised.ip0_by_ether, NULL,
                                         (void **)&adb, &cursor)) {
-
-               prefix2str(&adb->u.s.prefix_eth, buf, sizeof(buf));
-
-               vty_out(vty, "  Adv Pfx: %s%s", buf, HVTYNL);
+               vty_out(vty, "  Adv Pfx: %pFX%s", &adb->u.s.prefix_eth, HVTYNL);
 
                /* TBD update the following function to print ethernet info */
                /* Also need to pass/use rd */
@@ -1862,11 +1858,9 @@ void rfapiPrintNhl(void *stream, struct rfapi_next_hop_entry *next_hops)
                                        break;
 
                                case RFAPI_VN_OPTION_TYPE_LOCAL_NEXTHOP:
-                                       prefix2str(&vo->v.local_nexthop.addr,
-                                                  pbuf, sizeof(pbuf));
-                                       fp(out, "%sLNH %s cost=%d%s", offset,
-                                          pbuf, vo->v.local_nexthop.cost,
-                                          HVTYNL);
+                                       fp(out, "%sLNH %pFX cost=%d%s", offset,
+                                          &vo->v.local_nexthop.addr,
+                                          vo->v.local_nexthop.cost, HVTYNL);
                                        break;
 
                                default:
index 0480704b277ff5d3d3fd34bcaf15ec167388b975..11f39b2b82a379ce94cf70af4350d780a0282006 100644 (file)
@@ -1711,14 +1711,11 @@ void vnc_direct_bgp_rh_add_route(struct bgp *bgp, afi_t afi,
        rfapiGetVncLifetime(attr, &eti->lifetime);
        eti->lifetime = rfapiGetHolddownFromLifetime(eti->lifetime);
 
-       if (eti->timer) {
-               /*
-                * export expiration timer is already running on
-                * this route: cancel it
-                */
-               thread_cancel(eti->timer);
-               eti->timer = NULL;
-       }
+       /*
+        * export expiration timer is already running on
+        * this route: cancel it
+        */
+       thread_cancel(&eti->timer);
 
        bgp_update(peer, prefix, /* prefix */
                   0,            /* addpath_id */
@@ -1865,7 +1862,7 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
                        if (!bgp_dest_has_bgp_path_info_data(dest))
                                continue;
 
-                       vnc_zlog_debug_verbose("%s: checking prefix %pRN",
+                       vnc_zlog_debug_verbose("%s: checking prefix %pBD",
                                               __func__, dest);
 
                        dest_p = bgp_dest_get_prefix(dest);
@@ -1947,15 +1944,12 @@ void vnc_direct_bgp_rh_vpn_enable(struct bgp *bgp, afi_t afi)
                                        rfapiGetVncLifetime(ri->attr,
                                                            &eti->lifetime);
 
-                                       if (eti->timer) {
-                                               /*
-                                                * export expiration timer is
-                                                * already running on
-                                                * this route: cancel it
-                                                */
-                                               thread_cancel(eti->timer);
-                                               eti->timer = NULL;
-                                       }
+                                       /*
+                                        * export expiration timer is
+                                        * already running on
+                                        * this route: cancel it
+                                        */
+                                       thread_cancel(&eti->timer);
 
                                        vnc_zlog_debug_verbose(
                                                "%s: calling bgp_update",
@@ -2024,8 +2018,7 @@ void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi)
                                        ZEBRA_ROUTE_VNC_DIRECT_RH,
                                        BGP_ROUTE_REDISTRIBUTE);
                                if (eti) {
-                                       if (eti->timer)
-                                               thread_cancel(eti->timer);
+                                       thread_cancel(&eti->timer);
                                        vnc_eti_delete(eti);
                                }
 
index 85d64b5a72daad0286130a25844911881a83f972..0b6b39b966f740026ee9088f5fb9d95d78f6e6b3 100644 (file)
@@ -206,19 +206,11 @@ static void print_rhn_list(const char *tag1, const char *tag2)
 
        /* XXX uses secret knowledge of skiplist structure */
        for (p = sl->header->forward[0]; p; p = p->forward[0]) {
-               char kbuf[PREFIX_STRLEN];
-               char hbuf[PREFIX_STRLEN];
-               char ubuf[PREFIX_STRLEN];
-
                pb = p->value;
 
-               prefix2str(p->key, kbuf, sizeof(kbuf));
-               prefix2str(&pb->hpfx, hbuf, sizeof(hbuf));
-               prefix2str(&pb->upfx, ubuf, sizeof(ubuf));
-
                vnc_zlog_debug_verbose(
-                       "RHN Entry %d (q=%p): kpfx=%s, upfx=%s, hpfx=%s, ubpi=%p",
-                       ++count, p, kbuf, ubuf, hbuf, pb->ubpi);
+                       "RHN Entry %d (q=%p): kpfx=%pFX, upfx=%pFX, hpfx=%pFX, ubpi=%p",
+                       ++count, p, p->key, &pb->upfx, &pb->hpfx, pb->ubpi);
        }
 }
 #endif
@@ -260,15 +252,9 @@ static void vnc_rhnck(char *tag)
                 * pfx */
                assert(!vnc_prefix_cmp(&pb->hpfx, pkey));
                if (vnc_prefix_cmp(&pb->hpfx, &pfx_orig_nexthop)) {
-                       char str_onh[PREFIX_STRLEN];
-                       char str_nve_pfx[PREFIX_STRLEN];
-
-                       prefix2str(&pfx_orig_nexthop, str_onh, sizeof(str_onh));
-                       prefix2str(&pb->hpfx, str_nve_pfx, sizeof(str_nve_pfx));
-
                        vnc_zlog_debug_verbose(
-                               "%s: %s: FATAL: resolve_nve_nexthop list item bpi nexthop %s != nve pfx %s",
-                               __func__, tag, str_onh, str_nve_pfx);
+                               "%s: %s: FATAL: resolve_nve_nexthop list item bpi nexthop %pFX != nve pfx %pFX",
+                               __func__, tag, &pfx_orig_nexthop, &pb->hpfx);
                        assert(0);
                }
        }
@@ -529,13 +515,7 @@ static void vnc_import_bgp_add_route_mode_resolve_nve_one_rd(
        if (!table_rd)
                return;
 
-       {
-               char str_nh[PREFIX_STRLEN];
-
-               prefix2str(ubpi_nexthop, str_nh, sizeof(str_nh));
-
-               vnc_zlog_debug_verbose("%s: ubpi_nexthop=%s", __func__, str_nh);
-       }
+       vnc_zlog_debug_verbose("%s: ubpi_nexthop=%pFX", __func__, ubpi_nexthop);
 
        /* exact match */
        bd = bgp_node_lookup(table_rd, ubpi_nexthop);
@@ -574,12 +554,9 @@ static void vnc_import_bgp_add_route_mode_resolve_nve(
 
        /*debugging */
        if (VNC_DEBUG(VERBOSE)) {
-               char str_pfx[PREFIX_STRLEN];
                char str_nh[PREFIX_STRLEN];
                struct prefix nh;
 
-               prefix2str(prefix, str_pfx, sizeof(str_pfx));
-
                nh.prefixlen = 0;
                rfapiUnicastNexthop2Prefix(afi, info->attr, &nh);
                if (nh.prefixlen) {
@@ -590,8 +567,8 @@ static void vnc_import_bgp_add_route_mode_resolve_nve(
                }
 
                vnc_zlog_debug_verbose(
-                       "%s(bgp=%p, unicast prefix=%s, unicast nh=%s)",
-                       __func__, bgp, str_pfx, str_nh);
+                       "%s(bgp=%p, unicast prefix=%pFX, unicast nh=%s)",
+                       __func__, bgp, prefix, str_nh);
        }
 
        if (info->type != ZEBRA_ROUTE_BGP) {
@@ -713,12 +690,7 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp,
        uint32_t local_pref;
        uint32_t *med = NULL;
 
-       {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(prefix, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf);
-       }
+       vnc_zlog_debug_verbose("%s(prefix=%pFX) entry", __func__, prefix);
 
        if (!afi) {
                flog_err(EC_LIB_DEVELOPMENT, "%s: can't get afi of prefix",
@@ -783,12 +755,8 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp,
                ahr_flags |= RFAPI_AHR_NO_TUNNEL_SUBTLV;
        }
 
-       if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(vn_pfx, buf, sizeof(buf));
-               vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf);
-       }
+       if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
+               vnc_zlog_debug_any("%s vn_pfx=%pFX", __func__, vn_pfx);
 
        /*
         * Compute VN address
@@ -899,12 +867,7 @@ static void vnc_import_bgp_add_route_mode_nvegroup(
        struct route_map *rmap = NULL;
        uint32_t local_pref;
 
-       {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(prefix, buf, sizeof(buf));
-               vnc_zlog_debug_verbose("%s(prefix=%s) entry", __func__, buf);
-       }
+       vnc_zlog_debug_verbose("%s(prefix=%pFX) entry", __func__, prefix);
 
        assert(rfg);
 
@@ -985,12 +948,8 @@ static void vnc_import_bgp_add_route_mode_nvegroup(
                vncHDBgpDirect.un_addr = pfx_un.prefix;
        }
 
-       if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(vn_pfx, buf, sizeof(buf));
-               vnc_zlog_debug_any("%s vn_pfx=%s", __func__, buf);
-       }
+       if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
+               vnc_zlog_debug_any("%s vn_pfx=%pFX", __func__, vn_pfx);
 
        /*
         * Compute VN address
@@ -1288,12 +1247,7 @@ static void vnc_import_bgp_del_route_mode_resolve_nve_one_rd(
        if (!table_rd)
                return;
 
-       {
-               char str_nh[PREFIX_STRLEN];
-
-               prefix2str(ubpi_nexthop, str_nh, sizeof(str_nh));
-               vnc_zlog_debug_verbose("%s: ubpi_nexthop=%s", __func__, str_nh);
-       }
+       vnc_zlog_debug_verbose("%s: ubpi_nexthop=%pFX", __func__, ubpi_nexthop);
 
 
        /* exact match */
@@ -1467,17 +1421,11 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
                memset(&pfx_unicast_nexthop, 0,
                       sizeof(struct prefix)); /* keep valgrind happy */
 
-               if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE)) {
-                       char hbuf[PREFIX_STRLEN];
-                       char ubuf[PREFIX_STRLEN];
-
-                       prefix2str(&pb->hpfx, hbuf, sizeof(hbuf));
-                       prefix2str(&pb->upfx, ubuf, sizeof(ubuf));
-
+               if (VNC_DEBUG(IMPORT_BGP_ADD_ROUTE))
                        vnc_zlog_debug_any(
-                               "%s: examining RHN Entry (q=%p): upfx=%s, hpfx=%s, ubpi=%p",
-                               __func__, cursor, ubuf, hbuf, pb->ubpi);
-               }
+                               "%s: examining RHN Entry (q=%p): upfx=%pFX, hpfx=%pFX, ubpi=%p",
+                               __func__, cursor, &pb->upfx, &pb->hpfx,
+                               pb->ubpi);
 
                if (process_unicast_route(bgp, afi, &pb->upfx, pb->ubpi, &ecom,
                                          &pfx_unicast_nexthop)) {
@@ -1497,16 +1445,9 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
                 * Sanity check
                 */
                if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) {
-                       char str_unh[PREFIX_STRLEN];
-                       char str_nve_pfx[PREFIX_STRLEN];
-
-                       prefix2str(&pfx_unicast_nexthop, str_unh,
-                                  sizeof(str_unh));
-                       prefix2str(prefix, str_nve_pfx, sizeof(str_nve_pfx));
-
                        vnc_zlog_debug_verbose(
-                               "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %s != nve pfx %s",
-                               __func__, str_unh, str_nve_pfx);
+                               "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %pFX != nve pfx %pFX",
+                               __func__, &pfx_unicast_nexthop, prefix);
                        assert(0);
                }
 
@@ -1521,13 +1462,9 @@ void vnc_import_bgp_add_vnc_host_route_mode_resolve_nve(
 #if DEBUG_RHN_LIST
                /* debug */
                {
-                       char pbuf[PREFIX_STRLEN];
-
-                       prefix2str(prefix, pbuf, sizeof(pbuf));
-
                        vnc_zlog_debug_verbose(
-                               "%s: advancing past RHN Entry (q=%p): with prefix %s",
-                               __func__, cursor, pbuf);
+                               "%s: advancing past RHN Entry (q=%p): with prefix %pFX",
+                               __func__, cursor, prefix);
                        print_rhn_list(__func__, NULL); /* debug */
                }
 #endif
@@ -1550,14 +1487,8 @@ void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
        struct rfapi_cfg *hc = NULL;
        int rc;
 
-       {
-               char str_pfx[PREFIX_STRLEN];
-
-               prefix2str(prefix, str_pfx, sizeof(str_pfx));
-
-               vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%s)", __func__,
-                                      bgp, str_pfx);
-       }
+       vnc_zlog_debug_verbose("%s(bgp=%p, nve prefix=%pFX)", __func__, bgp,
+                              prefix);
 
        if (afi != AFI_IP && afi != AFI_IP6)
                return;
@@ -1621,16 +1552,9 @@ void vnc_import_bgp_del_vnc_host_route_mode_resolve_nve(
                 * Sanity check
                 */
                if (vnc_prefix_cmp(&pfx_unicast_nexthop, prefix)) {
-                       char str_unh[PREFIX_STRLEN];
-                       char str_nve_pfx[PREFIX_STRLEN];
-
-                       prefix2str(&pfx_unicast_nexthop, str_unh,
-                                  sizeof(str_unh));
-                       prefix2str(prefix, str_nve_pfx, sizeof(str_nve_pfx));
-
                        vnc_zlog_debug_verbose(
-                               "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %s != nve pfx %s",
-                               __func__, str_unh, str_nve_pfx);
+                               "%s: FATAL: resolve_nve_nexthop list item bpi nexthop %pFX != nve pfx %pFX",
+                               __func__, &pfx_unicast_nexthop, prefix);
                        assert(0);
                }
 
@@ -2305,13 +2229,11 @@ void vnc_import_bgp_exterior_add_route_interior(
                                     (void **)&pfx_exterior, &cursor)) {
 
                struct prefix pfx_nexthop;
-               char buf[PREFIX_STRLEN];
                afi_t afi_exterior = family2afi(pfx_exterior->family);
 
-               prefix2str(pfx_exterior, buf, sizeof(buf));
                vnc_zlog_debug_verbose(
-                       "%s: checking exterior orphan at prefix %s", __func__,
-                       buf);
+                       "%s: checking exterior orphan at prefix %pFX", __func__,
+                       pfx_exterior);
 
                if (afi_exterior != afi) {
                        vnc_zlog_debug_verbose(
@@ -2602,15 +2524,10 @@ void vnc_import_bgp_add_route(struct bgp *bgp, const struct prefix *prefix,
 
        if (VNC_DEBUG(VERBOSE)) {
                struct prefix pfx_nexthop;
-               char buf[PREFIX_STRLEN];
-               char buf_nh[PREFIX_STRLEN];
 
-               prefix2str(prefix, buf, sizeof(buf));
                rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop);
-               prefix2str(&pfx_nexthop, buf_nh, sizeof(buf_nh));
-
-               vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf,
-                                      buf_nh);
+               vnc_zlog_debug_verbose("%s: pfx %pFX, nh %pFX", __func__,
+                                      prefix, &pfx_nexthop);
        }
 #if DEBUG_RHN_LIST
        print_rhn_list(__func__, "ENTER ");
@@ -2673,15 +2590,10 @@ void vnc_import_bgp_del_route(struct bgp *bgp, const struct prefix *prefix,
 
        {
                struct prefix pfx_nexthop;
-               char buf[PREFIX_STRLEN];
-               char buf_nh[PREFIX_STRLEN];
 
-               prefix2str(prefix, buf, sizeof(buf));
                rfapiUnicastNexthop2Prefix(afi, info->attr, &pfx_nexthop);
-               prefix2str(&pfx_nexthop, buf_nh, sizeof(buf_nh));
-
-               vnc_zlog_debug_verbose("%s: pfx %s, nh %s", __func__, buf,
-                                      buf_nh);
+               vnc_zlog_debug_verbose("%s: pfx %pFX, nh %pFX", __func__,
+                                      prefix, &pfx_nexthop);
        }
 #if DEBUG_RHN_LIST
        print_rhn_list(__func__, "ENTER ");
index 008c7b28b7934d8a77ae1bec7ced57087541b484..b254f11ce7c9cdfe1d12cec3e3de83ffce194fae 100644 (file)
@@ -363,15 +363,11 @@ static int vnc_zebra_read_route(ZAPI_CALLBACK_ARGS)
        else
                vnc_redistribute_delete(&api.prefix, api.type);
 
-       if (BGP_DEBUG(zebra, ZEBRA)) {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(&api.prefix, buf, sizeof(buf));
+       if (BGP_DEBUG(zebra, ZEBRA))
                vnc_zlog_debug_verbose(
-                       "%s: Zebra rcvd: route delete %s %s metric %u",
-                       __func__, zebra_route_string(api.type), buf,
+                       "%s: Zebra rcvd: route delete %s %pFX metric %u",
+                       __func__, zebra_route_string(api.type), &api.prefix,
                        api.metric);
-       }
 
        return 0;
 }
@@ -425,14 +421,10 @@ static void vnc_zebra_route_msg(const struct prefix *p, unsigned int nhp_count,
                }
        }
 
-       if (BGP_DEBUG(zebra, ZEBRA)) {
-               char buf[PREFIX_STRLEN];
-
-               prefix2str(&api.prefix, buf, sizeof(buf));
+       if (BGP_DEBUG(zebra, ZEBRA))
                vnc_zlog_debug_verbose(
-                       "%s: Zebra send: route %s %s, nhp_count=%d", __func__,
-                       (add ? "add" : "del"), buf, nhp_count);
-       }
+                       "%s: Zebra send: route %s %pFX, nhp_count=%d", __func__,
+                       (add ? "add" : "del"), &api.prefix, nhp_count);
 
        zclient_route_send((add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE),
                           zclient_vnc, &api);
index d1f93957ee1a80ef87a133ab0f973ed93ae9a149..ea60b921d1b5c5888b078b3e98dabdf560172fd8 100644 (file)
@@ -61,6 +61,7 @@ bgpd_libbgp_a_SOURCES = \
        bgpd/bgp_bfd.c \
        bgpd/bgp_clist.c \
        bgpd/bgp_community.c \
+       bgpd/bgp_conditional_adv.c \
        bgpd/bgp_damp.c \
        bgpd/bgp_debug.c \
        bgpd/bgp_dump.c \
@@ -102,6 +103,9 @@ bgpd_libbgp_a_SOURCES = \
        bgpd/bgp_vty.c \
        bgpd/bgp_zebra.c \
        bgpd/bgpd.c \
+       bgpd/bgp_nb.c \
+       bgpd/bgp_nb_config.c \
+       bgpd/bgp_trace.c \
        # end
 
 if ENABLE_BGP_VNC
@@ -134,6 +138,7 @@ noinst_HEADERS += \
        bgpd/bgp_bfd.h \
        bgpd/bgp_clist.h \
        bgpd/bgp_community.h \
+       bgpd/bgp_conditional_adv.h \
        bgpd/bgp_damp.h \
        bgpd/bgp_debug.h \
        bgpd/bgp_dump.h \
@@ -175,6 +180,8 @@ noinst_HEADERS += \
        bgpd/bgp_vty.h \
        bgpd/bgp_zebra.h \
        bgpd/bgpd.h \
+       bgpd/bgp_nb.h \
+       bgpd/bgp_trace.h \
        \
        bgpd/rfapi/bgp_rfapi_cfg.h \
        bgpd/rfapi/rfapi_import.h \
@@ -205,8 +212,8 @@ bgpd_bgpd_CFLAGS = $(AM_CFLAGS)
 bgpd_bgp_btoa_CFLAGS = $(AM_CFLAGS)
 
 # RFPLDADD is set in bgpd/rfp-example/librfp/subdir.am
-bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM)
-bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM)
+bgpd_bgpd_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS)
+bgpd_bgp_btoa_LDADD = bgpd/libbgp.a $(RFPLDADD) lib/libfrr.la $(LIBCAP) $(LIBM) $(UST_LIBS)
 
 bgpd_bgpd_snmp_la_SOURCES = bgpd/bgp_snmp.c
 bgpd_bgpd_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu99
@@ -231,3 +238,16 @@ clippy_scan += \
        bgpd/bgp_rpki.c \
        bgpd/bgp_vty.c \
        # end
+
+nodist_bgpd_bgpd_SOURCES = \
+       yang/frr-bgp-types.yang.c \
+       yang/frr-bgp.yang.c \
+       yang/frr-bgp-common-structure.yang.c \
+       yang/frr-bgp-common.yang.c \
+       yang/frr-bgp-common-multiprotocol.yang.c \
+       yang/frr-bgp-neighbor.yang.c \
+       yang/frr-bgp-peer-group.yang.c \
+       yang/frr-bgp-bmp.yang.c \
+       yang/frr-bgp-rpki.yang.c \
+       yang/frr-deviations-bgp-datacenter.yang.c \
+       # end
index 3cc74c41108fd08e052cf773e953061daa0919fb..237552c1408b0c2c380ea94e857f9b8b2bee445f 100755 (executable)
@@ -139,6 +139,13 @@ AC_ARG_WITH([yangmodelsdir], [AS_HELP_STRING([--with-yangmodelsdir=DIR], [yang m
 ])
 AC_SUBST([yangmodelsdir])
 
+AC_ARG_WITH([vici-socket], [AS_HELP_STRING([--with-vici-socket=PATH], [vici-socket (/var/run/charon.vici)])], [
+       vici_socket="$withval"
+], [
+       vici_socket="/var/run/charon.vici"
+])
+AC_DEFINE_UNQUOTED([VICI_SOCKET], ["$vici_socket"], [StrongSWAN vici socket path])
+
 AC_ARG_ENABLE(tcmalloc,
        AS_HELP_STRING([--enable-tcmalloc], [Turn on tcmalloc]),
 [case "${enableval}" in
@@ -444,6 +451,11 @@ fi
 AC_SUBST([AC_LDFLAGS])
 AM_CONDITIONAL([STATIC_BIN], [test "$enable_static_bin" = "yes"])
 
+AC_ARG_ENABLE([rpath],
+  [AS_HELP_STRING([--enable-rpath], [set hardcoded rpaths in the executable @<:@default=yes@:>@])],
+  [],
+  [enable_rpath=yes])
+
 dnl $AR and $RANLIB are set by LT_INIT above
 AC_MSG_CHECKING([whether $AR supports D option])
 if $AR crD conftest.a >/dev/null 2>/dev/null; then
@@ -559,6 +571,10 @@ AC_ARG_ENABLE([grpc],
   AS_HELP_STRING([--enable-grpc], [enable the gRPC northbound plugin]))
 AC_ARG_ENABLE([zeromq],
   AS_HELP_STRING([--enable-zeromq], [enable ZeroMQ handler (libfrrzmq)]))
+AC_ARG_ENABLE([lttng],
+  AS_HELP_STRING([--enable-lttng], [enable LTTng tracing]))
+AC_ARG_ENABLE([usdt],
+  AS_HELP_STRING([--enable-usdt], [enable USDT probes]))
 AC_ARG_WITH([libpam],
   AS_HELP_STRING([--with-libpam], [use libpam for PAM support in vtysh]))
 AC_ARG_ENABLE([ospfapi],
@@ -1844,6 +1860,30 @@ if test "$enable_grpc" = "yes"; then
   ])
 fi
 
+dnl -----
+dnl LTTng
+dnl -----
+if test "$enable_lttng" = "yes"; then
+  PKG_CHECK_MODULES([UST], [lttng-ust >= 2.12.0], [
+    AC_DEFINE([HAVE_LTTNG], [1], [Enable LTTng support])
+    LTTNG=true
+  ], [
+    AC_MSG_ERROR([configuration specifies --enable-lttng but lttng-ust was not found])
+  ])
+fi
+
+dnl ----
+dnl USDT
+dnl ----
+if test "$enable_usdt" = "yes"; then
+  AC_CHECK_HEADERS([sys/sdt.h], [
+    AC_DEFINE([HAVE_USDT], [1], [Enable USDT probes])
+    USDT=true
+  ], [
+    AC_MSG_ERROR([configuration specifies --enable-usdt but no USDT kernel headers (sys/sdt.h) found])
+  ])
+fi
+
 dnl ------
 dnl ZeroMQ
 dnl ------
@@ -2492,6 +2532,14 @@ AS_IF([test "$with_pkg_git_version" = "yes"], [
 ## It's already in CVS until texinfo 4.7 is more common.
 AC_OUTPUT
 
+if test "$enable_rpath" = "yes" ; then
+       true
+else
+       # See https://old-en.opensuse.org/openSUSE:Packaging_Guidelines#Removing_Rpath
+       sed -i 's|^hardcode_libdir_flag_spec=.*|hardcode_libdir_flag_spec=""|g' libtool
+       sed -i 's|^runpath_var=LD_RUN_PATH|runpath_var=DIE_RPATH_DIE|g' libtool
+fi
+
 echo "
 FRRouting configuration
 ------------------------------
@@ -2512,6 +2560,7 @@ group for vty sockets   : ${enable_vty_group}
 config file mask        : ${enable_configfile_mask}
 log file mask           : ${enable_logfile_mask}
 zebra protobuf enabled  : ${enable_protobuf:-no}
+vici socket path        : ${vici_socket}
 
 The above user and group must have read/write access to the state file
 directory and to the config files in the config file directory."
index 9acfab739a943f376ccc58fb23dcb843c402781b..f4bb65ec79b493fc7f87ac2b59d5d436b5aaa89d 100644 (file)
@@ -21,48 +21,48 @@ from sphinx.highlighting import lexers
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+# sys.path.insert(0, os.path.abspath('.'))
 
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.0'
+needs_sphinx = "1.0"
 
 # prolog for various variable substitutions
-rst_prolog = ''
+rst_prolog = ""
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['sphinx.ext.todo', 'sphinx.ext.graphviz']
+extensions = ["sphinx.ext.todo", "sphinx.ext.graphviz"]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
 
 # The suffix(es) of source filenames.
 # You can specify multiple suffix as a list of string:
 # source_suffix = ['.rst']
-source_suffix = '.rst'
+source_suffix = ".rst"
 
 # The encoding of source files.
-#source_encoding = 'utf-8-sig'
+# source_encoding = 'utf-8-sig'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # General information about the project.
-project = u'FRR'
-copyright = u'2017, FRR'
-author = u'FRR authors'
+project = u"FRR"
+copyright = u"2017, FRR"
+author = u"FRR authors"
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 
 # The short X.Y version.
-version = u'?.?'
+version = u"?.?"
 # The full version, including alpha/beta/rc tags.
-release = u'?.?-?'
+release = u"?.?-?"
 
 
 # -----------------------------------------------------------------------------
@@ -72,48 +72,49 @@ release = u'?.?-?'
 # Various installation prefixes. Values are extracted from config.status.
 # Reasonable defaults are set in case that file does not exist.
 replace_vars = {
-    'AUTHORS': author,
-    'COPYRIGHT_YEAR': '1999-2005',
-    'COPYRIGHT_STR': 'Copyright (c) 1999-2005',
-    'PACKAGE_NAME': project.lower(),
-    'PACKAGE_TARNAME': project.lower(),
-    'PACKAGE_STRING': project.lower() + ' latest',
-    'PACKAGE_URL': 'https://frrouting.org/',
-    'PACKAGE_VERSION': 'latest',
-    'INSTALL_PREFIX_ETC': '/etc/frr',
-    'INSTALL_PREFIX_SBIN': '/usr/lib/frr',
-    'INSTALL_PREFIX_STATE': '/var/run/frr',
-    'INSTALL_PREFIX_MODULES': '/usr/lib/frr/modules',
-    'INSTALL_USER': 'frr',
-    'INSTALL_GROUP': 'frr',
-    'INSTALL_VTY_GROUP': 'frrvty',
-    'GROUP': 'frr',
-    'USER': 'frr',
+    "AUTHORS": author,
+    "COPYRIGHT_YEAR": "1999-2005",
+    "COPYRIGHT_STR": "Copyright (c) 1999-2005",
+    "PACKAGE_NAME": project.lower(),
+    "PACKAGE_TARNAME": project.lower(),
+    "PACKAGE_STRING": project.lower() + " latest",
+    "PACKAGE_URL": "https://frrouting.org/",
+    "PACKAGE_VERSION": "latest",
+    "INSTALL_PREFIX_ETC": "/etc/frr",
+    "INSTALL_PREFIX_SBIN": "/usr/lib/frr",
+    "INSTALL_PREFIX_STATE": "/var/run/frr",
+    "INSTALL_PREFIX_MODULES": "/usr/lib/frr/modules",
+    "INSTALL_USER": "frr",
+    "INSTALL_GROUP": "frr",
+    "INSTALL_VTY_GROUP": "frrvty",
+    "GROUP": "frr",
+    "USER": "frr",
 }
 
 # extract version information, installation location, other stuff we need to
 # use when building final documents
 val = re.compile('^S\["([^"]+)"\]="(.*)"$')
 try:
-    with open('../../config.status', 'r') as cfgstatus:
+    with open("../../config.status", "r") as cfgstatus:
         for ln in cfgstatus.readlines():
             m = val.match(ln)
-            if not m or m.group(1) not in replace_vars.keys(): continue
+            if not m or m.group(1) not in replace_vars.keys():
+                continue
             replace_vars[m.group(1)] = m.group(2)
 except IOError:
     # if config.status doesn't exist, just ignore it
     pass
 
 # manually fill out some of these we can't get from config.status
-replace_vars['COPYRIGHT_STR'] = "Copyright (c)"
-replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR'])
-replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS'])
-release = replace_vars['PACKAGE_VERSION']
-version = release.split('-')[0]
+replace_vars["COPYRIGHT_STR"] = "Copyright (c)"
+replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["COPYRIGHT_YEAR"])
+replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["AUTHORS"])
+release = replace_vars["PACKAGE_VERSION"]
+version = release.split("-")[0]
 
 # add substitutions to prolog
 for key, value in replace_vars.items():
-    rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value)
+    rst_prolog += ".. |{0}| replace:: {1}\n".format(key, value)
 
 
 # The language for content autogenerated by Sphinx. Refer to documentation
@@ -125,37 +126,42 @@ language = None
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
-#today = ''
+# today = ''
 # Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# today_fmt = '%B %d, %Y'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'building-libyang.rst', 'topotests-snippets.rst', 'include-compile.rst']
+exclude_patterns = [
+    "_build",
+    "building-libyang.rst",
+    "topotests-snippets.rst",
+    "include-compile.rst",
+]
 
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
-#default_role = None
+# default_role = None
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
+# add_function_parentheses = True
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#add_module_names = True
+# add_module_names = True
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#show_authors = False
+# show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# modindex_common_prefix = []
 
 # If true, keep warnings as "system message" paragraphs in the built documents.
-#keep_warnings = False
+# keep_warnings = False
 
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = True
@@ -165,165 +171,158 @@ todo_include_todos = True
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-html_theme = 'default'
+html_theme = "default"
 
 try:
     import sphinx_rtd_theme
 
-    html_theme = 'sphinx_rtd_theme'
+    html_theme = "sphinx_rtd_theme"
 except ImportError:
     pass
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {
+# html_theme_options = {
 #    'sidebarbgcolor': '#374249'
-#}
+# }
 
 # Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
+# html_theme_path = []
 
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
-#html_title = None
+# html_title = None
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
+# html_short_title = None
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-html_logo = '../figures/frr-icon.svg'
+html_logo = "../figures/frr-icon.svg"
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
 # pixels large.
-html_favicon = '../figures/frr-logo-icon.png'
+html_favicon = "../figures/frr-logo-icon.png"
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
 
 # Add any extra paths that contain custom files (such as robots.txt or
 # .htaccess) here, relative to this directory. These files are copied
 # directly to the root of the documentation.
-#html_extra_path = []
+# html_extra_path = []
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+# html_last_updated_fmt = '%b %d, %Y'
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
-#html_use_smartypants = True
+# html_use_smartypants = True
 
 # Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# html_sidebars = {}
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
 
 # If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
 
 # If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
 
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
 
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
 
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
 
 # Language to be used for generating the HTML full-text search index.
 # Sphinx supports the following languages:
 #   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
 #   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
-#html_search_language = 'en'
+# html_search_language = 'en'
 
 # A dictionary with options for the search language support, empty by default.
 # Now only 'ja' uses this config value
-#html_search_options = {'type': 'default'}
+# html_search_options = {'type': 'default'}
 
 # The name of a javascript file (relative to the configuration directory) that
 # implements a search results scorer. If empty, the default will be used.
-#html_search_scorer = 'scorer.js'
+# html_search_scorer = 'scorer.js'
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'FRRdoc'
+htmlhelp_basename = "FRRdoc"
 
 # -- Options for LaTeX output ---------------------------------------------
 
 latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-
-# Latex figure (float) alignment
-#'figure_align': 'htbp',
+    # The paper size ('letterpaper' or 'a4paper').
+    #'papersize': 'letterpaper',
+    # The font size ('10pt', '11pt' or '12pt').
+    #'pointsize': '10pt',
+    # Additional stuff for the LaTeX preamble.
+    #'preamble': '',
+    # Latex figure (float) alignment
+    #'figure_align': 'htbp',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'FRR.tex', u"FRR Developer's Manual",
-     u'FRR', 'manual'),
+    (master_doc, "FRR.tex", u"FRR Developer's Manual", u"FRR", "manual"),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
-latex_logo = '../figures/frr-logo-medium.png'
+latex_logo = "../figures/frr-logo-medium.png"
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
 
 # If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
 
 # If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
 
 # Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
 
 # If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
 
 
 # -- Options for manual page output ---------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    (master_doc, 'frr', u"FRR Developer's Manual",
-     [author], 1)
-]
+man_pages = [(master_doc, "frr", u"FRR Developer's Manual", [author], 1)]
 
 # If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
 
 
 # -- Options for Texinfo output -------------------------------------------
@@ -332,38 +331,44 @@ man_pages = [
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'frr', u"FRR Developer's Manual",
-     author, 'FRR', 'One line description of project.',
-     'Miscellaneous'),
+    (
+        master_doc,
+        "frr",
+        u"FRR Developer's Manual",
+        author,
+        "FRR",
+        "One line description of project.",
+        "Miscellaneous",
+    ),
 ]
 
 # Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
+# texinfo_appendices = []
 
 # If false, no module index is generated.
-#texinfo_domain_indices = True
+# texinfo_domain_indices = True
 
 # How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
+# texinfo_show_urls = 'footnote'
 
 # If true, do not generate a @detailmenu in the "Top" node's menu.
-#texinfo_no_detailmenu = False
+# texinfo_no_detailmenu = False
 
 # contents of ../extra/frrlexer.py.
 # This is read here to support VPATH build. Since this section is execfile()'d
 # with the file location, we can safely use a relative path here to save the
 # contents of the lexer file for later use even if our relative path changes
 # due to VPATH.
-with open('../extra/frrlexer.py', 'rb') as lex:
+with open("../extra/frrlexer.py", "rb") as lex:
     frrlexerpy = lex.read()
 
 # custom extensions here
 def setup(app):
     # object type for FRR CLI commands, can be extended to document parent CLI
     # node later on
-    app.add_object_type('clicmd', 'clicmd')
+    app.add_object_type("clicmd", "clicmd")
     # css overrides for HTML theme
-    app.add_stylesheet('overrides.css')
+    app.add_stylesheet("overrides.css")
     # load Pygments lexer for FRR config syntax
     #
     # NB: in Pygments 2.2+ this can be done with `load_lexer_from_file`, but we
@@ -373,4 +378,4 @@ def setup(app):
     # frrlexer = pygments.lexers.load_lexer_from_file('../extra/frrlexer.py', lexername="FRRLexer")
     custom_namespace = {}
     exec(frrlexerpy, custom_namespace)
-    lexers['frr'] = custom_namespace['FRRLexer']()
+    lexers["frr"] = custom_namespace["FRRLexer"]()
index 1f803b37725b27539e77c67cbc7c7149c0171bdb..1ba0f31c8a1a8fbb4ed6cedea8156180204f2af2 100644 (file)
@@ -9,6 +9,7 @@ FRRouting Developer's Guide
    packaging
    process-architecture
    library
+   tracing
    testing
    bgpd
    fpm
index 0430ad72a3b10f7f43cbb0c16352d0b370ea153f..2f2444373c842d23378bdeccae0493a771a0812e 100644 (file)
@@ -83,6 +83,8 @@ Extensions
 +-----------+--------------------------+----------------------------------------------+
 | ``%pNHs`` | ``struct nexthop *``     | ``1.2.3.4 if 15``                            |
 +-----------+--------------------------+----------------------------------------------+
+| ``%pFX``  + ``struct bgp_dest *``    | ``fe80::1234/64`` available in BGP only      |
++-----------+--------------------------+----------------------------------------------+
 
 Printf features like field lengths can be used normally with these extensions,
 e.g. ``%-15pI4`` works correctly.
diff --git a/doc/developer/tracing.rst b/doc/developer/tracing.rst
new file mode 100644 (file)
index 0000000..ee0a6be
--- /dev/null
@@ -0,0 +1,314 @@
+.. _tracing:
+
+Tracing
+=======
+
+FRR has a small but growing number of static tracepoints available for use with
+various tracing systems. These tracepoints can assist with debugging,
+performance analysis and to help understand program flow. They can also be used
+for monitoring.
+
+Developers are encouraged to write new static tracepoints where sensible. They
+are not compiled in by default, and even when they are, they have no overhead
+unless enabled by a tracer, so it is okay to be liberal with them.
+
+
+Supported tracers
+-----------------
+
+Presently two types of tracepoints are supported:
+
+- `LTTng tracepoints <https://lttng.org/>`_
+- `USDT probes <http://dtrace.org/guide/chp-usdt.html>`_
+
+LTTng is a tracing framework for Linux only. It offers extremely low overhead
+and very rich tracing capabilities. FRR supports LTTng-UST, which is the
+userspace implementation. LTTng tracepoints are very rich in detail. No kernel
+modules are needed. Besides only being available for Linux, the primary
+downside of LTTng is the need to link to ``lttng-ust``.
+
+USDT probes originate from Solaris, where they were invented for use with
+dtrace. They are a kernel feature. At least Linux and FreeBSD support them. No
+library is needed; support is compiled in via a system header
+(``<sys/sdt.h>``). USDT probes are much slower than LTTng tracepoints and offer
+less flexibility in what information can be gleaned from them.
+
+LTTng is capable of tracing USDT probes but has limited support for them.
+SystemTap and dtrace both work only with USDT probes.
+
+
+Usage
+-----
+
+To compile with tracepoints, use one of the following configure flags:
+
+.. program:: configure.ac
+
+.. option:: --enable-lttng=yes
+
+   Generate LTTng tracepoints
+
+.. option:: --enable-usdt=yes
+
+   Generate USDT probes
+
+To trace with LTTng, compile with either one (prefer :option:`--enable-lttng`
+run the target in non-forking mode (no ``-d``) and use LTTng as usual (refer to
+LTTng user manual). When using USDT probes with LTTng, follow the example in
+`this article
+<https://lttng.org/blog/2019/10/15/new-dynamic-user-space-tracing-in-lttng/>`_.
+To trace with dtrace or SystemTap, compile with :option:`--enable-usdt=yes` and
+use your tracer as usual.
+
+To see available USDT probes::
+
+  readelf -n /usr/lib/frr/bgpd
+
+Example::
+
+  root@host ~> readelf -n /usr/lib/frr/bgpd
+
+  Displaying notes found in: .note.ABI-tag
+    Owner                 Data size    Description
+    GNU                  0x00000010    NT_GNU_ABI_TAG (ABI version tag)
+      OS: Linux, ABI: 3.2.0
+
+  Displaying notes found in: .note.gnu.build-id
+    Owner                 Data size    Description
+    GNU                  0x00000014    NT_GNU_BUILD_ID (unique build ID bitstring)
+      Build ID: 4f42933a69dcb42a519bc459b2105177c8adf55d
+
+  Displaying notes found in: .note.stapsdt
+    Owner                 Data size    Description
+    stapsdt              0x00000045    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: packet_read
+      Location: 0x000000000045ee48, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-96(%rbp) 8@-104(%rbp)
+    stapsdt              0x00000047    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: open_process
+      Location: 0x000000000047c43b, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-224(%rbp) 2@-226(%rbp)
+    stapsdt              0x00000049    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: update_process
+      Location: 0x000000000047c4bf, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-208(%rbp) 2@-210(%rbp)
+    stapsdt              0x0000004f    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: notification_process
+      Location: 0x000000000047c557, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-192(%rbp) 2@-194(%rbp)
+    stapsdt              0x0000004c    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: keepalive_process
+      Location: 0x000000000047c5db, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-176(%rbp) 2@-178(%rbp)
+    stapsdt              0x0000004a    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: refresh_process
+      Location: 0x000000000047c673, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-160(%rbp) 2@-162(%rbp)
+    stapsdt              0x0000004d    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: capability_process
+      Location: 0x000000000047c6f7, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-144(%rbp) 2@-146(%rbp)
+    stapsdt              0x0000006f    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: output_filter
+      Location: 0x000000000048e33a, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp)
+    stapsdt              0x0000007d    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: process_update
+      Location: 0x0000000000491f10, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-800(%rbp) 8@-808(%rbp) 4@-812(%rbp) 4@-816(%rbp) 4@-820(%rbp) 8@-832(%rbp)
+    stapsdt              0x0000006e    NT_STAPSDT (SystemTap probe descriptors)
+      Provider: frr_bgp
+      Name: input_filter
+      Location: 0x00000000004940ed, Base: 0x00000000005a09d2, Semaphore: 0x0000000000000000
+      Arguments: 8@-144(%rbp) 8@-152(%rbp) 4@-156(%rbp) 4@-160(%rbp) 8@-168(%rbp)
+
+
+To see available LTTng probes, run the target, create a session and then::
+
+  lttng list --userspace | grep frr
+
+Example::
+
+  root@host ~> lttng list --userspace | grep frr
+  PID: 11157 - Name: /usr/lib/frr/bgpd
+        frr_libfrr:route_node_get (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:list_sort (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:list_delete_node (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:list_remove (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:list_add (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:memfree (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:memalloc (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:frr_pthread_stop (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:frr_pthread_run (loglevel: TRACE_DEBUG_LINE (13)) (type: tracepoint)
+        frr_libfrr:thread_call (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:thread_cancel_async (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:thread_cancel (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:schedule_write (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:schedule_read (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:schedule_event (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:schedule_timer (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:hash_release (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:hash_insert (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_libfrr:hash_get (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:output_filter (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:input_filter (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:process_update (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:packet_read (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:refresh_process (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:capability_process (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:notification_process (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:update_process (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:keepalive_process (loglevel: TRACE_INFO (6)) (type: tracepoint)
+        frr_bgp:open_process (loglevel: TRACE_INFO (6)) (type: tracepoint)
+
+When using LTTng, you can also get zlogs as trace events by enabling
+the ``lttng_ust_tracelog:*`` event class.
+
+Concepts
+--------
+
+Tracepoints are statically defined points in code where a developer has
+determined that outside observers might gain something from knowing what is
+going on at that point. It's like logging but with the ability to dump large
+amounts of internal data with much higher performance. LTTng has a good summary
+`here <https://lttng.org/docs/#doc-what-is-tracing>`_.
+
+Each tracepoint has a "provider" and name. The provider is basically a
+namespace; for example, ``bgpd`` uses the provider name ``frr_bgp``. The name
+is arbitrary, but because providers share a global namespace on the user's
+system, all providers from FRR should be prefixed by ``frr_``. The tracepoint
+name is just the name of the event. Events are globally named by their provider
+and name. For example, the event when BGP reads a packet from a peer is
+``frr_bgp:packet_read``.
+
+To do tracing, the tracing tool of choice is told which events to listen to.
+For example, to listen to all events from FRR's BGP implementation, you would
+enable the events ``frr_bgp:*``. In the same tracing session you could also
+choose to record all memory allocations by enabling the ``malloc`` tracepoints
+in ``libc`` as well as all kernel skb operations using the various in-kernel
+tracepoints. This allows you to build as complete a view as desired of what the
+system is doing during the tracing window (subject to what tracepoints are
+available).
+
+Of particular use are the tracepoints for FRR's internal event scheduler;
+tracing these allows you to see all events executed by all event loops for the
+target(s) in question. Here's a couple events selected from a trace of BGP
+during startup::
+
+   ...
+
+   [18:41:35.750131763] (+0.000048901) host frr_libfrr:thread_call: { cpu_id =
+   1 }, { threadmaster_name = "default", function_name = "zclient_connect",
+   scheduled_from = "lib/zclient.c", scheduled_on_line = 3877, thread_addr =
+   0x0, file_descriptor = 0, event_value = 0, argument_ptr = 0xA37F70, timer =
+   0 }
+
+   [18:41:35.750175124] (+0.000020001) host frr_libfrr:thread_call: { cpu_id =
+   1 }, { threadmaster_name = "default", function_name = "frr_config_read_in",
+   scheduled_from = "lib/libfrr.c", scheduled_on_line = 934, thread_addr = 0x0,
+   file_descriptor = 0, event_value = 0, argument_ptr = 0x0, timer = 0 }
+
+   [18:41:35.753341264] (+0.000010532) host frr_libfrr:thread_call: { cpu_id =
+   1 }, { threadmaster_name = "default", function_name = "bgp_event",
+   scheduled_from = "bgpd/bgpd.c", scheduled_on_line = 142, thread_addr = 0x0,
+   file_descriptor = 2, event_value = 2, argument_ptr = 0xE4D780, timer = 2 }
+
+   [18:41:35.753404186] (+0.000004910) host frr_libfrr:thread_call: { cpu_id =
+   1 }, { threadmaster_name = "default", function_name = "zclient_read",
+   scheduled_from = "lib/zclient.c", scheduled_on_line = 3891, thread_addr =
+   0x0, file_descriptor = 40, event_value = 40, argument_ptr = 0xA37F70, timer
+   = 40 }
+
+   ...
+
+
+Very useful for getting a time-ordered look into what the process is doing.
+
+
+Adding Tracepoints
+------------------
+
+Adding new tracepoints is a two step process:
+
+1. Define the tracepoint
+2. Use the tracepoint
+
+Tracepoint definitions state the "provider" and name of the tracepoint, along
+with any values it will produce, and how to format them. This is done with
+macros provided by LTTng. USDT probes do not use definitions and are inserted
+at the trace site with a single macro. However, to maintain support for both
+platforms, you must define an LTTng tracepoint when adding a new one.
+``frrtrace()`` will expand to the appropriate ``DTRACE_PROBEn`` macro when USDT
+is in use.
+
+If you are adding new tracepoints to a daemon that has no tracepoints, that
+daemon's ``subdir.am`` must be updated to conditionally link ``lttng-ust``.
+Look at ``bgpd/subdir.am`` for an example of how to do this; grep for
+``UST_LIBS``. Create new files named ``<daemon>_trace.[ch]``. Use
+``bgpd/bgp_trace.[h]`` as boilerplate. If you are adding tracepoints to a
+daemon that already has them, look for the ``<daemon>_trace.h`` file;
+tracepoints are written here.
+
+Refer to the `LTTng developer docs
+<https://lttng.org/docs/#doc-c-application>`_ for details on how to define
+tracepoints.
+
+To use them, simply add a call to ``frrtrace()`` at the point you'd like the
+event to be emitted, like so:
+
+.. code-block:: c
+
+   ...
+
+   switch (type) {
+   case BGP_MSG_OPEN:
+           frrtrace(2, frr_bgp, open_process, peer, size); /* tracepoint */
+           atomic_fetch_add_explicit(&peer->open_in, 1,
+                                     memory_order_relaxed);
+           mprc = bgp_open_receive(peer, size);
+
+   ...
+
+After recompiling this tracepoint will now be available, either as a USDT probe
+or LTTng tracepoint, depending on your compilation choice.
+
+
+trace.h
+^^^^^^^
+
+Because FRR supports multiple types of tracepoints, the code for creating them
+abstracts away the underlying system being used. This abstraction code is in
+``lib/trace.h``. There are 2 function-like macros that are used for working
+with tracepoints.
+
+- ``frrtrace()`` defines tracepoints
+- ``frrtrace_enabled()`` checks whether a tracepoint is enabled
+
+There is also ``frrtracelog()``, which is used in zlog core code to make zlog
+messages available as trace events to LTTng. This should not be used elsewhere.
+
+There is additional documentation in the header. The key thing to note is that
+you should never include ``trace.h`` in source where you plan to put
+tracepoints; include the tracepoint definition header instead (e.g.
+:file:`bgp_trace.h`).
+
+
+Limitations
+-----------
+
+Tracers do not like ``fork()`` or ``dlopen()``. LTTng has some workarounds for
+this involving interceptor libraries using ``LD_PRELOAD``.
+
+USDT tracepoints are relatively high overhead and probably shouldn't be used
+for "flight recorder" functionality, i.e. enabling and passively recording all
+events for monitoring purposes. It's generally okay to use LTTng like this,
+though.
index f345464a354000663b016f64bbca61aa3d93eb2b..4183ac6480c7a78d954aa4b959a8651c1d895ddb 100644 (file)
@@ -779,13 +779,12 @@ necessary replacements.
 .. _style-exceptions:
 
 Exceptions
-^^^^^^^^^^
+""""""""""
 
 FRR project code comes from a variety of sources, so there are some
 stylistic exceptions in place. They are organized here by branch.
 
-For ``master``
-""""""""""""""
+For ``master``:
 
 BSD coding style applies to:
 
@@ -797,8 +796,7 @@ BSD coding style applies to:
 -  Indents are 4 spaces
 -  Function return types are on their own line
 
-For ``stable/3.0`` and ``stable/2.0``
-"""""""""""""""""""""""""""""""""""""
+For ``stable/3.0`` and ``stable/2.0``:
 
 GNU coding style apply to the following parts:
 
@@ -816,6 +814,21 @@ BSD coding style applies to:
 
 -  ``ldpd/``
 
+
+Python Code
+^^^^^^^^^^^
+
+Format all Python code with `black <https://github.com/psf/black>`_.
+
+In a line::
+
+   python3 -m black <file.py>
+
+Run this on any Python files you modify before committing.
+
+FRR's Python code has been formatted with black version 19.10b.
+
+
 YANG
 ^^^^
 
index 528bec985ba9bef798ca2bb53fa6c4456713a7b3..e177c3983f72a85e391a72ff36b4da75d9be51ac 100644 (file)
@@ -22,17 +22,18 @@ class FRRLexer(RegexLexer):
     name = "frr"
     aliases = ["frr"]
     tokens = {
-        'root': [
-            (r'^[ \t]*!.*?\n', Comment.Singleline),
+        "root": [
+            (r"^[ \t]*!.*?\n", Comment.Singleline),
             (r'"(\\\\|\\"|[^"])*"', String.Double),
-            (r'[a-f0-9]*:[a-f0-9]*:[a-f0-9:]*(:\d+\.\d+\.\d+\.\d+)?(/\d+)?',
-             Number),  # IPv6
-            (r'\d+\.\d+\.\d+\.\d+(/\d+)?', Number),  # IPv4
-            (r'^([ \t]*)(no[ \t]+)?([-\w]+)',
-             bygroups(Text, Keyword, Name.Function)),
-            (r'[ \t]+', Text),
-            (r'\n', Text),
-            (r'\d+', Number),
-            (r'\S+', Text),
+            (
+                r"[a-f0-9]*:[a-f0-9]*:[a-f0-9:]*(:\d+\.\d+\.\d+\.\d+)?(/\d+)?",
+                Number,
+            ),  # IPv6
+            (r"\d+\.\d+\.\d+\.\d+(/\d+)?", Number),  # IPv4
+            (r"^([ \t]*)(no[ \t]+)?([-\w]+)", bygroups(Text, Keyword, Name.Function)),
+            (r"[ \t]+", Text),
+            (r"\n", Text),
+            (r"\d+", Number),
+            (r"\S+", Text),
         ],
     }
index 8b9bb021a356411e96b82a10f8cd34888e3c5c88..186f7932b21de75377d783f0dafeb54377c08a23 100644 (file)
@@ -19,48 +19,48 @@ import re
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+# sys.path.insert(0, os.path.abspath('.'))
 
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.0'
+needs_sphinx = "1.0"
 
 # prolog for various variable substitutions
-rst_prolog = ''
+rst_prolog = ""
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['sphinx.ext.todo']
+extensions = ["sphinx.ext.todo"]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
 
 # The suffix(es) of source filenames.
 # You can specify multiple suffix as a list of string:
 # source_suffix = ['.rst']
-source_suffix = '.rst'
+source_suffix = ".rst"
 
 # The encoding of source files.
-#source_encoding = 'utf-8-sig'
+# source_encoding = 'utf-8-sig'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # General information about the project.
-project = u'FRR'
-copyright = u'2017, FRR'
-author = u'FRR authors'
+project = u"FRR"
+copyright = u"2017, FRR"
+author = u"FRR authors"
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 
 # The short X.Y version.
-version = u'?.?'
+version = u"?.?"
 # The full version, including alpha/beta/rc tags.
-release = u'?.?-?'
+release = u"?.?-?"
 
 
 # -----------------------------------------------------------------------------
@@ -70,48 +70,49 @@ release = u'?.?-?'
 # Various installation prefixes. Values are extracted from config.status.
 # Reasonable defaults are set in case that file does not exist.
 replace_vars = {
-    'AUTHORS': author,
-    'COPYRIGHT_YEAR': '1999-2005',
-    'COPYRIGHT_STR': 'Copyright (c) 1999-2005',
-    'PACKAGE_NAME': project.lower(),
-    'PACKAGE_TARNAME': project.lower(),
-    'PACKAGE_STRING': project.lower() + ' latest',
-    'PACKAGE_URL': 'https://frrouting.org/',
-    'PACKAGE_VERSION': 'latest',
-    'INSTALL_PREFIX_ETC': '/etc/frr',
-    'INSTALL_PREFIX_SBIN': '/usr/lib/frr',
-    'INSTALL_PREFIX_STATE': '/var/run/frr',
-    'INSTALL_PREFIX_MODULES': '/usr/lib/frr/modules',
-    'INSTALL_USER': 'frr',
-    'INSTALL_GROUP': 'frr',
-    'INSTALL_VTY_GROUP': 'frrvty',
-    'GROUP': 'frr',
-    'USER': 'frr',
+    "AUTHORS": author,
+    "COPYRIGHT_YEAR": "1999-2005",
+    "COPYRIGHT_STR": "Copyright (c) 1999-2005",
+    "PACKAGE_NAME": project.lower(),
+    "PACKAGE_TARNAME": project.lower(),
+    "PACKAGE_STRING": project.lower() + " latest",
+    "PACKAGE_URL": "https://frrouting.org/",
+    "PACKAGE_VERSION": "latest",
+    "INSTALL_PREFIX_ETC": "/etc/frr",
+    "INSTALL_PREFIX_SBIN": "/usr/lib/frr",
+    "INSTALL_PREFIX_STATE": "/var/run/frr",
+    "INSTALL_PREFIX_MODULES": "/usr/lib/frr/modules",
+    "INSTALL_USER": "frr",
+    "INSTALL_GROUP": "frr",
+    "INSTALL_VTY_GROUP": "frrvty",
+    "GROUP": "frr",
+    "USER": "frr",
 }
 
 # extract version information, installation location, other stuff we need to
 # use when building final documents
 val = re.compile('^S\["([^"]+)"\]="(.*)"$')
 try:
-    with open('../../config.status', 'r') as cfgstatus:
+    with open("../../config.status", "r") as cfgstatus:
         for ln in cfgstatus.readlines():
             m = val.match(ln)
-            if not m or m.group(1) not in replace_vars.keys(): continue
+            if not m or m.group(1) not in replace_vars.keys():
+                continue
             replace_vars[m.group(1)] = m.group(2)
 except IOError:
     # if config.status doesn't exist, just ignore it
     pass
 
 # manually fill out some of these we can't get from config.status
-replace_vars['COPYRIGHT_STR'] = "Copyright (c)"
-replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR'])
-replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS'])
-release = replace_vars['PACKAGE_VERSION']
-version = release.split('-')[0]
+replace_vars["COPYRIGHT_STR"] = "Copyright (c)"
+replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["COPYRIGHT_YEAR"])
+replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["AUTHORS"])
+release = replace_vars["PACKAGE_VERSION"]
+version = release.split("-")[0]
 
 # add substitutions to prolog
 for key, value in replace_vars.items():
-    rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value)
+    rst_prolog += ".. |{0}| replace:: {1}\n".format(key, value)
 
 
 # The language for content autogenerated by Sphinx. Refer to documentation
@@ -123,37 +124,43 @@ language = None
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
-#today = ''
+# today = ''
 # Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# today_fmt = '%B %d, %Y'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'common-options.rst', 'epilogue.rst', 'defines.rst', 'bfd-options.rst']
+exclude_patterns = [
+    "_build",
+    "common-options.rst",
+    "epilogue.rst",
+    "defines.rst",
+    "bfd-options.rst",
+]
 
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
-#default_role = None
+# default_role = None
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
+# add_function_parentheses = True
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#add_module_names = True
+# add_module_names = True
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#show_authors = False
+# show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# modindex_common_prefix = []
 
 # If true, keep warnings as "system message" paragraphs in the built documents.
-#keep_warnings = False
+# keep_warnings = False
 
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = True
@@ -163,31 +170,31 @@ todo_include_todos = True
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-html_theme = 'default'
+html_theme = "default"
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {}
+# html_theme_options = {}
 
 # Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
+# html_theme_path = []
 
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
-#html_title = None
+# html_title = None
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
+# html_short_title = None
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-#html_logo = None
+# html_logo = None
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
 # pixels large.
-#html_favicon = None
+# html_favicon = None
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
@@ -197,109 +204,105 @@ html_static_path = []
 # Add any extra paths that contain custom files (such as robots.txt or
 # .htaccess) here, relative to this directory. These files are copied
 # directly to the root of the documentation.
-#html_extra_path = []
+# html_extra_path = []
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+# html_last_updated_fmt = '%b %d, %Y'
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
-#html_use_smartypants = True
+# html_use_smartypants = True
 
 # Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# html_sidebars = {}
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
 
 # If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
 
 # If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
 
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
 
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
 
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
 
 # Language to be used for generating the HTML full-text search index.
 # Sphinx supports the following languages:
 #   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
 #   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
-#html_search_language = 'en'
+# html_search_language = 'en'
 
 # A dictionary with options for the search language support, empty by default.
 # Now only 'ja' uses this config value
-#html_search_options = {'type': 'default'}
+# html_search_options = {'type': 'default'}
 
 # The name of a javascript file (relative to the configuration directory) that
 # implements a search results scorer. If empty, the default will be used.
-#html_search_scorer = 'scorer.js'
+# html_search_scorer = 'scorer.js'
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'FRRdoc'
+htmlhelp_basename = "FRRdoc"
 
 # -- Options for LaTeX output ---------------------------------------------
 
 latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-
-# Latex figure (float) alignment
-#'figure_align': 'htbp',
+    # The paper size ('letterpaper' or 'a4paper').
+    #'papersize': 'letterpaper',
+    # The font size ('10pt', '11pt' or '12pt').
+    #'pointsize': '10pt',
+    # Additional stuff for the LaTeX preamble.
+    #'preamble': '',
+    # Latex figure (float) alignment
+    #'figure_align': 'htbp',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'FRR.tex', u'FRR User Manual',
-     u'FRR', 'manual'),
+    (master_doc, "FRR.tex", u"FRR User Manual", u"FRR", "manual"),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
-#latex_logo = None
+# latex_logo = None
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
 
 # If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
 
 # If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
 
 # Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
 
 # If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
 
 
 # -- Options for manual page output ---------------------------------------
@@ -308,33 +311,45 @@ latex_documents = [
 # (source start file, name, description, authors, manual section).
 
 # If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
 
 fwfrr = "{0} routing engine for use with FRRouting."
 
 man_pages = [
-    ('frr-bfdd',       'frr-bfdd', fwfrr.format("a bfd"), [], 8),
-    ('frr-bgpd',       'frr-bgpd', fwfrr.format("a BGPv4, BGPv4+, BGPv4-"), [], 8),
-    ('frr-eigrpd',     'frr-eigrpd', fwfrr.format("an EIGRP"), [], 8),
-    ('frr-fabricd',    'frr-fabricd', fwfrr.format("an OpenFabric"), [], 8),
-    ('frr-isisd',      'frr-isisd', fwfrr.format("an IS-IS"), [], 8),
-    ('frr-ldpd',       'frr-ldpd', fwfrr.format("an LDP"), [], 8),
-    ('frr-nhrpd',      'frr-nhrpd', fwfrr.format("a Next Hop Routing Protocol"), [], 8),
-    ('frr-ospf6d',     'frr-ospf6d', fwfrr.format("an OSPFv3"), [], 8),
-    ('frr-ospfclient', 'frr-ospfclient', 'an example ospf-api client', [], 8),
-    ('frr-ospfd',      'frr-ospfd', fwfrr.format("an OSPFv2"), [], 8),
-    ('frr-pbrd',       'frr-pbrd', fwfrr.format("a PBR"), [], 8),
-    ('frr-pimd',       'frr-pimd', fwfrr.format("a PIM"), [], 8),
-    ('frr-ripd',       'frr-ripd', fwfrr.format("a RIP"), [], 8),
-    ('frr-ripngd',     'frr-ripngd', fwfrr.format("a RIPNG"), [], 8),
-    ('frr-sharpd',     'frr-sharpd', fwfrr.format("a SHARP"), [], 8),
-    ('frr-staticd',    'frr-staticd', fwfrr.format("a static route manager"), [], 8),
-    ('frr-vrrpd',      'frr-vrrpd', fwfrr.format("a VRRP"), [], 8),
-    ('frr-watchfrr',   'frr-watchfrr', 'a program to monitor the status of FRRouting daemons', [], 8),
-    ('frr-zebra',      'frr-zebra', 'a routing manager for use with associated FRRouting components.', [], 8),
-    ('frr', 'frr', 'a systemd interaction script', [], 1),
-    ('mtracebis',  'mtracebis', "a multicast trace client", [], 8),
-    ('vtysh', 'vtysh', 'an integrated shell for FRRouting.', [], 1),
+    ("frr-bfdd", "frr-bfdd", fwfrr.format("a bfd"), [], 8),
+    ("frr-bgpd", "frr-bgpd", fwfrr.format("a BGPv4, BGPv4+, BGPv4-"), [], 8),
+    ("frr-eigrpd", "frr-eigrpd", fwfrr.format("an EIGRP"), [], 8),
+    ("frr-fabricd", "frr-fabricd", fwfrr.format("an OpenFabric"), [], 8),
+    ("frr-isisd", "frr-isisd", fwfrr.format("an IS-IS"), [], 8),
+    ("frr-ldpd", "frr-ldpd", fwfrr.format("an LDP"), [], 8),
+    ("frr-nhrpd", "frr-nhrpd", fwfrr.format("a Next Hop Routing Protocol"), [], 8),
+    ("frr-ospf6d", "frr-ospf6d", fwfrr.format("an OSPFv3"), [], 8),
+    ("frr-ospfclient", "frr-ospfclient", "an example ospf-api client", [], 8),
+    ("frr-ospfd", "frr-ospfd", fwfrr.format("an OSPFv2"), [], 8),
+    ("frr-pbrd", "frr-pbrd", fwfrr.format("a PBR"), [], 8),
+    ("frr-pimd", "frr-pimd", fwfrr.format("a PIM"), [], 8),
+    ("frr-ripd", "frr-ripd", fwfrr.format("a RIP"), [], 8),
+    ("frr-ripngd", "frr-ripngd", fwfrr.format("a RIPNG"), [], 8),
+    ("frr-sharpd", "frr-sharpd", fwfrr.format("a SHARP"), [], 8),
+    ("frr-staticd", "frr-staticd", fwfrr.format("a static route manager"), [], 8),
+    ("frr-vrrpd", "frr-vrrpd", fwfrr.format("a VRRP"), [], 8),
+    (
+        "frr-watchfrr",
+        "frr-watchfrr",
+        "a program to monitor the status of FRRouting daemons",
+        [],
+        8,
+    ),
+    (
+        "frr-zebra",
+        "frr-zebra",
+        "a routing manager for use with associated FRRouting components.",
+        [],
+        8,
+    ),
+    ("frr", "frr", "a systemd interaction script", [], 1),
+    ("mtracebis", "mtracebis", "a multicast trace client", [], 8),
+    ("vtysh", "vtysh", "an integrated shell for FRRouting.", [], 1),
 ]
 
 # -- Options for Texinfo output -------------------------------------------
@@ -344,15 +359,15 @@ man_pages = [
 #  dir menu entry, description, category)
 
 # Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
+# texinfo_appendices = []
 
 # If false, no module index is generated.
-#texinfo_domain_indices = True
+# texinfo_domain_indices = True
 
 # How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
+# texinfo_show_urls = 'footnote'
 
 # If true, do not generate a @detailmenu in the "Top" node's menu.
-#texinfo_no_detailmenu = False
+# texinfo_no_detailmenu = False
 
 # custom extensions here
index cfb368bf4455ae8f588b6b12383a4a6125084025..722b011ecd1991b125c0118aaaef394e0a2b6c53 100644 (file)
@@ -25,10 +25,6 @@ OPTIONS available for the |DAEMON| command:
 
    Runs in batch mode, zebra parses its config and exits.
 
-.. option:: -k, --keep_kernel
-
-   On startup, don't delete self inserted routes.
-
 .. option:: -s, --nl-bufsize <netlink-buffer-size>
 
    Set netlink receive buffer size. There are cases where zebra daemon can't handle flood of netlink messages from kernel. If you ever see "recvmsg overrun" messages in zebra log, you are in trouble.
index 10eaaee9fb456e0acbbd67a1690536289f6a8faa..3572734ba95b249c9dd0e832e4e02cbee0df306b 100644 (file)
@@ -999,6 +999,18 @@ Route Aggregation-IPv4 Address Family
    This command specifies an aggregate address. Aggregated routes will
    not be announced.
 
+.. index:: aggregate-address A.B.C.D/M matching-MED-only
+.. clicmd:: aggregate-address A.B.C.D/M matching-MED-only
+
+   Configure the aggregated address to only be created when the routes MED
+   match, otherwise no aggregated route will be created.
+
+.. index:: aggregate-address A.B.C.D/M suppress-map NAME
+.. clicmd:: aggregate-address A.B.C.D/M suppress-map NAME
+
+   Similar to `summary-only`, but will only suppress more specific routes that
+   are matched by the selected route-map.
+
 .. index:: no aggregate-address A.B.C.D/M
 .. clicmd:: no aggregate-address A.B.C.D/M
 
@@ -1051,6 +1063,18 @@ Route Aggregation-IPv6 Address Family
    This command specifies an aggregate address. Aggregated routes will
    not be announced.
 
+.. index:: aggregate-address X:X::X:X/M matching-MED-only
+.. clicmd:: aggregate-address X:X::X:X/M matching-MED-only
+
+   Configure the aggregated address to only be created when the routes MED
+   match, otherwise no aggregated route will be created.
+
+.. index:: aggregate-address X:X::X:X/M suppress-map NAME
+.. clicmd:: aggregate-address X:X::X:X/M suppress-map NAME
+
+   Similar to `summary-only`, but will only suppress more specific routes that
+   are matched by the selected route-map.
+
 .. index:: no aggregate-address X:X::X:X/M
 .. clicmd:: no aggregate-address X:X::X:X/M
 
@@ -2550,6 +2574,113 @@ the same behavior of using same next-hop and RMAC values.
 Enables or disables advertise-pip feature, specifiy system-IP and/or system-MAC
 parameters.
 
+EVPN Multihoming
+^^^^^^^^^^^^^^^^
+
+All-Active Multihoming is used for redundancy and load sharing. Servers
+are attached to two or more PEs and the links are bonded (link-aggregation).
+This group of server links is referred to as an Ethernet Segment.
+
+Ethernet Segments
+"""""""""""""""""
+An Ethernet Segment can be configured by specifying a system-MAC and a
+local discriminatior against the bond interface on the PE (via zebra) -
+
+.. index:: [no] evpn mh es-id [(1-16777215)$es_lid]
+.. clicmd:: [no] evpn mh es-id [(1-16777215)$es_lid]
+
+.. index:: [no$no] evpn mh es-sys-mac [X:X:X:X:X:X$mac]
+.. clicmd:: [no$no] evpn mh es-sys-mac [X:X:X:X:X:X$mac]
+
+The sys-mac and local discriminator are used for generating a 10-byte,
+Type-3 Ethernet Segment ID.
+
+Type-1 (EAS-per-ES and EAD-per-EVI) routes are used to advertise the locally
+attached ESs and to learn off remote ESs in the network. Local Type-2/MAC-IP
+routes are also advertised with a destination ESI allowing for MAC-IP syncing
+between Ethernet Segment peers.
+Reference: RFC 7432, RFC 8365
+
+EVPN-MH is intended as a replacement for MLAG or Anycast VTEPs. In
+multihoming each PE has an unique VTEP address which requires the introduction
+of a new dataplane construct, MAC-ECMP. Here a MAC/FDB entry can point to a
+list of remote PEs/VTEPs.
+
+BUM handling
+""""""""""""
+Type-4 (ESR) routes are used for Designated Forwarder (DF) election. DFs
+forward BUM traffic received via the overlay network. This implementation
+uses a preference based DF election specified by draft-ietf-bess-evpn-pref-df.
+The DF preference is configurable per-ES (via zebra) -
+
+.. index:: [no] evpn mh es-df-pref [(1-16777215)$df_pref]
+.. clicmd:: [no] evpn mh es-df-pref [(1-16777215)$df_pref]
+
+BUM traffic is rxed via the overlay by all PEs attached to a server but
+only the DF can forward the de-capsulated traffic to the access port. To
+accomodate that non-DF filters are installed in the dataplane to drop
+the traffic.
+
+Similarly traffic received from ES peers via the overlay cannot be forwarded
+to the server. This is split-horizon-filtering with local bias.
+
+Fast failover
+"""""""""""""
+As the primary purpose of EVPN-MH is redundancy keeping the failover efficient
+is a recurring theme in the implementation. Following sub-features have
+been introduced for the express purpose of efficient ES failovers.
+
+- Layer-2 Nexthop Groups and MAC-ECMP via L2NHG.
+
+- Host routes (for symmetric IRB) via L3NHG.
+  On dataplanes that support layer3 nexthop groups the feature can be turned
+  on via the following BGP config -
+
+.. index:: [no$no] use-es-l3nhg
+.. clicmd:: [no$no] use-es-l3nhg
+
+- Local ES (MAC/Neigh) failover via ES-redirect.
+  On dataplanes that do not have support for ES-redirect the feature can be
+  turned off via the following zebra config -
+
+.. index:: [no$no] evpn mh redirect-off
+.. clicmd:: [no$no] evpn mh redirect-off
+
+Uplink/Core tracking
+""""""""""""""""""""
+When all the underlay links go down the PE no longer has access to the VxLAN
++overlay. To prevent blackholing of traffic the server/ES links are
+protodowned on the PE. A link can be setup for uplink tracking via the
+following zebra configuration -
+
+.. index:: [no] evpn mh uplink
+.. clicmd:: [no] evpn mh uplink
+
+Proxy advertisements
+""""""""""""""""""""
+To handle hitless upgrades support for proxy advertisement has been added
+as specified by draft-rbickhart-evpn-ip-mac-proxy-adv. This allows a PE
+(say PE1) to proxy advertise a MAC-IP rxed from an ES peer (say PE2). When
+the ES peer (PE2) goes down PE1 continues to advertise hosts learnt from PE2
+for a holdtime during which it attempts to establish local reachability of
+the host. This holdtime is configurable via the following zebra commands -
+
+.. index:: [no$no] evpn mh neigh-holdtime (0-86400)$duration
+.. clicmd:: [no$no] evpn mh neigh-holdtime (0-86400)$duration
+
+.. index:: [no$no] evpn mh mac-holdtime (0-86400)$duration
+.. clicmd:: [no$no] evpn mh mac-holdtime (0-86400)$duration
+
+Startup delay
+"""""""""""""
+When a switch is rebooted we wait for a brief period to allow the underlay
+and EVPN network to converge before enabling the ESs. For this duration the
+ES bonds are held protodown. The startup delay is configurable via the
+following zebra command -
+
+.. index:: [no] evpn mh startup-delay(0-3600)$duration
+.. clicmd:: [no] evpn mh startup-delay(0-3600)$duration
+
 +Support with VRF network namespace backend
 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 It is possible to separate overlay networks contained in VXLAN interfaces from
@@ -2571,6 +2702,194 @@ This makes it possible to separate not only layer 3 networks like VRF-lite netwo
 Also, VRF netns based make possible to separate layer 2 networks on separate VRF
 instances.
 
+.. _bgp-conditional-advertisement:
+
+BGP Conditional Advertisement
+-----------------------------
+The BGP conditional advertisement feature uses the ``non-exist-map`` or the
+``exist-map`` and the ``advertise-map`` keywords of the neighbor advertise-map
+command in order to track routes by the route prefix.
+
+``non-exist-map``
+   1. If a route prefix is not present in the output of non-exist-map command,
+      then advertise the route specified by the advertise-map command.
+
+   2. If a route prefix is present in the output of non-exist-map command,
+      then do not advertise the route specified by the addvertise-map command.
+
+``exist-map``
+   1. If a route prefix is present in the output of exist-map command,
+      then advertise the route specified by the advertise-map command.
+
+   2. If a route prefix is not present in the output of exist-map command,
+      then do not advertise the route specified by the advertise-map command.
+
+This feature is useful when some prefixes are advertised to one of its peers
+only if the information from the other peer is not present (due to failure in
+peering session or partial reachability etc).
+
+The conditional BGP announcements are sent in addition to the normal
+announcements that a BGP router sends to its peer.
+
+The conditional advertisement process is triggered by the BGP scanner process,
+which runs every 60 seconds. This means that the maximum time for the conditional
+advertisement to take effect is 60 seconds. The conditional advertisement can take
+effect depending on when the tracked route is removed from the BGP table and
+when the next instance of the BGP scanner occurs.
+
+.. index:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME
+.. clicmd:: [no] neighbor A.B.C.D advertise-map NAME [exist-map|non-exist-map] NAME
+
+   This command enables BGP scanner process to monitor routes specified by
+   exist-map or non-exist-map command in BGP table and conditionally advertises
+   the routes specified by advertise-map command.
+
+Sample Configuration
+^^^^^^^^^^^^^^^^^^^^^
+.. code-block:: frr
+
+   interface enp0s9
+    ip address 10.10.10.2/24
+   !
+   interface enp0s10
+    ip address 10.10.20.2/24
+   !
+   interface lo
+    ip address 203.0.113.1/32
+   !
+   router bgp 2
+    bgp log-neighbor-changes
+    no bgp ebgp-requires-policy
+    neighbor 10.10.10.1 remote-as 1
+    neighbor 10.10.20.3 remote-as 3
+    !
+    address-family ipv4 unicast
+     neighbor 10.10.10.1 soft-reconfiguration inbound
+     neighbor 10.10.20.3 soft-reconfiguration inbound
+     neighbor 10.10.20.3 advertise-map ADV-MAP non-exist-map EXIST-MAP
+    exit-address-family
+   !
+   ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32
+   ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32
+   ip prefix-list EXIST seq 5 permit 10.10.10.10/32
+   ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0
+   ip prefix-list IP1 seq 5 permit 10.139.224.0/20
+   !
+   bgp community-list standard DC-ROUTES seq 5 permit 64952:3008
+   bgp community-list standard DC-ROUTES seq 10 permit 64671:501
+   bgp community-list standard DC-ROUTES seq 15 permit 64950:3009
+   bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200
+   !
+   route-map ADV-MAP permit 10
+    match ip address prefix-list IP1
+   !
+   route-map ADV-MAP permit 20
+    match community DC-ROUTES
+   !
+   route-map EXIST-MAP permit 10
+    match community DEFAULT-ROUTE
+    match ip address prefix-list DEFAULT-ROUTE
+   !
+
+Sample Output
+^^^^^^^^^^^^^
+
+When default route is present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are not advertised to R3.
+
+.. code-block:: frr
+
+   Router2# show ip bgp
+   BGP table version is 20, local router ID is 203.0.113.1, vrf id 0
+   Default local pref 100, local AS 2
+   Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+                  i internal, r RIB-failure, S Stale, R Removed
+   Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+   Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+      Network          Next Hop            Metric LocPrf Weight Path
+   *> 0.0.0.0/0        10.10.10.1               0             0 1 i
+   *> 10.139.224.0/20  10.10.10.1               0             0 1 ?
+   *> 192.0.2.1/32     10.10.10.1               0             0 1 i
+   *> 192.0.2.5/32     10.10.10.1               0             0 1 i
+
+   Displayed  4 routes and 4 total paths
+   Router2# show ip bgp neighbors 10.10.20.3
+
+   !--- Output suppressed.
+
+   For address family: IPv4 Unicast
+   Update group 7, subgroup 7
+   Packet Queue length 0
+   Inbound soft reconfiguration allowed
+   Community attribute sent to this neighbor(all)
+   Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Withdraw
+   0 accepted prefixes
+
+   !--- Output suppressed.
+
+   Router2# show ip bgp neighbors 10.10.20.3 advertised-routes
+   BGP table version is 20, local router ID is 203.0.113.1, vrf id 0
+   Default local pref 100, local AS 2
+   Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+               i internal, r RIB-failure, S Stale, R Removed
+   Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+   Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+      Network          Next Hop            Metric LocPrf Weight Path
+   *> 0.0.0.0/0        0.0.0.0                                0 1 i
+   *> 192.0.2.5/32     0.0.0.0                                0 1 i
+
+   Total number of prefixes 2
+
+When default route is not present in R2'2 BGP table, 10.139.224.0/20 and 192.0.2.1/32 are advertised to R3.
+
+.. code-block:: frr
+
+   Router2# show ip bgp
+   BGP table version is 21, local router ID is 203.0.113.1, vrf id 0
+   Default local pref 100, local AS 2
+   Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+                  i internal, r RIB-failure, S Stale, R Removed
+   Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+   Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+      Network          Next Hop            Metric LocPrf Weight Path
+   *> 10.139.224.0/20  10.10.10.1               0             0 1 ?
+   *> 192.0.2.1/32     10.10.10.1               0             0 1 i
+   *> 192.0.2.5/32     10.10.10.1               0             0 1 i
+
+   Displayed  3 routes and 3 total paths
+
+   Router2# show ip bgp neighbors 10.10.20.3
+
+   !--- Output suppressed.
+
+   For address family: IPv4 Unicast
+   Update group 7, subgroup 7
+   Packet Queue length 0
+   Inbound soft reconfiguration allowed
+   Community attribute sent to this neighbor(all)
+   Condition NON_EXIST, Condition-map *EXIST-MAP, Advertise-map *ADV-MAP, status: Advertise
+   0 accepted prefixes
+
+   !--- Output suppressed.
+
+   Router2# show ip bgp neighbors 10.10.20.3 advertised-routes
+   BGP table version is 21, local router ID is 203.0.113.1, vrf id 0
+   Default local pref 100, local AS 2
+   Status codes:  s suppressed, d damped, h history, * valid, > best, = multipath,
+                  i internal, r RIB-failure, S Stale, R Removed
+   Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self
+   Origin codes:  i - IGP, e - EGP, ? - incomplete
+
+      Network          Next Hop            Metric LocPrf Weight Path
+   *> 10.139.224.0/20  0.0.0.0                                0 1 ?
+   *> 192.0.2.1/32     0.0.0.0                                0 1 i
+   *> 192.0.2.5/32     0.0.0.0                                0 1 i
+
+   Total number of prefixes 3
+   Router2#
+
 .. _bgp-debugging:
 
 Debugging
index 1f6f050bcf67afb2622bb8494678fe31337eace3..79b37e785074ede4cc514cbacc201439af092cc6 100644 (file)
@@ -22,48 +22,48 @@ from sphinx.highlighting import lexers
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
 # documentation root, use os.path.abspath to make it absolute, like shown here.
-#sys.path.insert(0, os.path.abspath('.'))
+# sys.path.insert(0, os.path.abspath('.'))
 
 # -- General configuration ------------------------------------------------
 
 # If your documentation needs a minimal Sphinx version, state it here.
-needs_sphinx = '1.0'
+needs_sphinx = "1.0"
 
 # prolog for various variable substitutions
-rst_prolog = ''
+rst_prolog = ""
 
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['sphinx.ext.todo']
+extensions = ["sphinx.ext.todo"]
 
 # Add any paths that contain templates here, relative to this directory.
-templates_path = ['_templates']
+templates_path = ["_templates"]
 
 # The suffix(es) of source filenames.
 # You can specify multiple suffix as a list of string:
 # source_suffix = ['.rst']
-source_suffix = '.rst'
+source_suffix = ".rst"
 
 # The encoding of source files.
-#source_encoding = 'utf-8-sig'
+# source_encoding = 'utf-8-sig'
 
 # The master toctree document.
-master_doc = 'index'
+master_doc = "index"
 
 # General information about the project.
-project = u'FRR'
-copyright = u'2017, FRR'
-author = u'FRR authors'
+project = u"FRR"
+copyright = u"2017, FRR"
+author = u"FRR authors"
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 
 # The short X.Y version.
-version = u'?.?'
+version = u"?.?"
 # The full version, including alpha/beta/rc tags.
-release = u'?.?-?'
+release = u"?.?-?"
 
 
 # -----------------------------------------------------------------------------
@@ -73,48 +73,49 @@ release = u'?.?-?'
 # Various installation prefixes. Values are extracted from config.status.
 # Reasonable defaults are set in case that file does not exist.
 replace_vars = {
-    'AUTHORS': author,
-    'COPYRIGHT_YEAR': '1999-2005',
-    'COPYRIGHT_STR': 'Copyright (c) 1999-2005',
-    'PACKAGE_NAME': project.lower(),
-    'PACKAGE_TARNAME': project.lower(),
-    'PACKAGE_STRING': project.lower() + ' latest',
-    'PACKAGE_URL': 'https://frrouting.org/',
-    'PACKAGE_VERSION': 'latest',
-    'INSTALL_PREFIX_ETC': '/etc/frr',
-    'INSTALL_PREFIX_SBIN': '/usr/lib/frr',
-    'INSTALL_PREFIX_STATE': '/var/run/frr',
-    'INSTALL_PREFIX_MODULES': '/usr/lib/frr/modules',
-    'INSTALL_USER': 'frr',
-    'INSTALL_GROUP': 'frr',
-    'INSTALL_VTY_GROUP': 'frrvty',
-    'GROUP': 'frr',
-    'USER': 'frr',
+    "AUTHORS": author,
+    "COPYRIGHT_YEAR": "1999-2005",
+    "COPYRIGHT_STR": "Copyright (c) 1999-2005",
+    "PACKAGE_NAME": project.lower(),
+    "PACKAGE_TARNAME": project.lower(),
+    "PACKAGE_STRING": project.lower() + " latest",
+    "PACKAGE_URL": "https://frrouting.org/",
+    "PACKAGE_VERSION": "latest",
+    "INSTALL_PREFIX_ETC": "/etc/frr",
+    "INSTALL_PREFIX_SBIN": "/usr/lib/frr",
+    "INSTALL_PREFIX_STATE": "/var/run/frr",
+    "INSTALL_PREFIX_MODULES": "/usr/lib/frr/modules",
+    "INSTALL_USER": "frr",
+    "INSTALL_GROUP": "frr",
+    "INSTALL_VTY_GROUP": "frrvty",
+    "GROUP": "frr",
+    "USER": "frr",
 }
 
 # extract version information, installation location, other stuff we need to
 # use when building final documents
 val = re.compile('^S\["([^"]+)"\]="(.*)"$')
 try:
-    with open('../../config.status', 'r') as cfgstatus:
+    with open("../../config.status", "r") as cfgstatus:
         for ln in cfgstatus.readlines():
             m = val.match(ln)
-            if not m or m.group(1) not in replace_vars.keys(): continue
+            if not m or m.group(1) not in replace_vars.keys():
+                continue
             replace_vars[m.group(1)] = m.group(2)
 except IOError:
     # if config.status doesn't exist, just ignore it
     pass
 
 # manually fill out some of these we can't get from config.status
-replace_vars['COPYRIGHT_STR'] = "Copyright (c)"
-replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['COPYRIGHT_YEAR'])
-replace_vars['COPYRIGHT_STR'] += ' {0}'.format(replace_vars['AUTHORS'])
-release = replace_vars['PACKAGE_VERSION']
-version = release.split('-')[0]
+replace_vars["COPYRIGHT_STR"] = "Copyright (c)"
+replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["COPYRIGHT_YEAR"])
+replace_vars["COPYRIGHT_STR"] += " {0}".format(replace_vars["AUTHORS"])
+release = replace_vars["PACKAGE_VERSION"]
+version = release.split("-")[0]
 
 # add substitutions to prolog
 for key, value in replace_vars.items():
-    rst_prolog += '.. |{0}| replace:: {1}\n'.format(key, value)
+    rst_prolog += ".. |{0}| replace:: {1}\n".format(key, value)
 
 
 # The language for content autogenerated by Sphinx. Refer to documentation
@@ -126,39 +127,45 @@ language = None
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
-#today = ''
+# today = ''
 # Else, today_fmt is used as the format for a strftime call.
-#today_fmt = '%B %d, %Y'
+# today_fmt = '%B %d, %Y'
 
 # List of patterns, relative to source directory, that match files and
 # directories to ignore when looking for source files.
-exclude_patterns = ['_build', 'rpki.rst', 'routeserver.rst',
-                    'ospf_fundamentals.rst', 'flowspec.rst', 'snmptrap.rst',
-                    'wecmp_linkbw.rst']
+exclude_patterns = [
+    "_build",
+    "rpki.rst",
+    "routeserver.rst",
+    "ospf_fundamentals.rst",
+    "flowspec.rst",
+    "snmptrap.rst",
+    "wecmp_linkbw.rst",
+]
 
 # The reST default role (used for this markup: `text`) to use for all
 # documents.
-#default_role = None
+# default_role = None
 
 # If true, '()' will be appended to :func: etc. cross-reference text.
-#add_function_parentheses = True
+# add_function_parentheses = True
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#add_module_names = True
+# add_module_names = True
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#show_authors = False
+# show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
+pygments_style = "sphinx"
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+# modindex_common_prefix = []
 
 # If true, keep warnings as "system message" paragraphs in the built documents.
-#keep_warnings = False
+# keep_warnings = False
 
 # If true, `todo` and `todoList` produce output, else they produce nothing.
 todo_include_todos = True
@@ -168,165 +175,158 @@ todo_include_todos = True
 
 # The theme to use for HTML and HTML Help pages.  See the documentation for
 # a list of builtin themes.
-html_theme = 'default'
+html_theme = "default"
 
 try:
     import sphinx_rtd_theme
 
-    html_theme = 'sphinx_rtd_theme'
+    html_theme = "sphinx_rtd_theme"
 except ImportError:
     pass
 
 # Theme options are theme-specific and customize the look and feel of a theme
 # further.  For a list of options available for each theme, see the
 # documentation.
-#html_theme_options = {
+# html_theme_options = {
 #    'sidebarbgcolor': '#374249'
-#}
+# }
 
 # Add any paths that contain custom themes here, relative to this directory.
-#html_theme_path = []
+# html_theme_path = []
 
 # The name for this set of Sphinx documents.  If None, it defaults to
 # "<project> v<release> documentation".
-#html_title = None
+# html_title = None
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
-#html_short_title = None
+# html_short_title = None
 
 # The name of an image file (relative to this directory) to place at the top
 # of the sidebar.
-html_logo = '../figures/frr-icon.svg'
+html_logo = "../figures/frr-icon.svg"
 
 # The name of an image file (within the static path) to use as favicon of the
 # docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
 # pixels large.
-html_favicon = '../figures/frr-logo-icon.png'
+html_favicon = "../figures/frr-logo-icon.png"
 
 # Add any paths that contain custom static files (such as style sheets) here,
 # relative to this directory. They are copied after the builtin static files,
 # so a file named "default.css" will overwrite the builtin "default.css".
-html_static_path = ['_static']
+html_static_path = ["_static"]
 
 # Add any extra paths that contain custom files (such as robots.txt or
 # .htaccess) here, relative to this directory. These files are copied
 # directly to the root of the documentation.
-#html_extra_path = []
+# html_extra_path = []
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+# html_last_updated_fmt = '%b %d, %Y'
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
-#html_use_smartypants = True
+# html_use_smartypants = True
 
 # Custom sidebar templates, maps document names to template names.
-#html_sidebars = {}
+# html_sidebars = {}
 
 # Additional templates that should be rendered to pages, maps page names to
 # template names.
-#html_additional_pages = {}
+# html_additional_pages = {}
 
 # If false, no module index is generated.
-#html_domain_indices = True
+# html_domain_indices = True
 
 # If false, no index is generated.
-#html_use_index = True
+# html_use_index = True
 
 # If true, the index is split into individual pages for each letter.
-#html_split_index = False
+# html_split_index = False
 
 # If true, links to the reST sources are added to the pages.
-#html_show_sourcelink = True
+# html_show_sourcelink = True
 
 # If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
-#html_show_sphinx = True
+# html_show_sphinx = True
 
 # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
-#html_show_copyright = True
+# html_show_copyright = True
 
 # If true, an OpenSearch description file will be output, and all pages will
 # contain a <link> tag referring to it.  The value of this option must be the
 # base URL from which the finished HTML is served.
-#html_use_opensearch = ''
+# html_use_opensearch = ''
 
 # This is the file name suffix for HTML files (e.g. ".xhtml").
-#html_file_suffix = None
+# html_file_suffix = None
 
 # Language to be used for generating the HTML full-text search index.
 # Sphinx supports the following languages:
 #   'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
 #   'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
-#html_search_language = 'en'
+# html_search_language = 'en'
 
 # A dictionary with options for the search language support, empty by default.
 # Now only 'ja' uses this config value
-#html_search_options = {'type': 'default'}
+# html_search_options = {'type': 'default'}
 
 # The name of a javascript file (relative to the configuration directory) that
 # implements a search results scorer. If empty, the default will be used.
-#html_search_scorer = 'scorer.js'
+# html_search_scorer = 'scorer.js'
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'FRRdoc'
+htmlhelp_basename = "FRRdoc"
 
 # -- Options for LaTeX output ---------------------------------------------
 
 latex_elements = {
-# The paper size ('letterpaper' or 'a4paper').
-#'papersize': 'letterpaper',
-
-# The font size ('10pt', '11pt' or '12pt').
-#'pointsize': '10pt',
-
-# Additional stuff for the LaTeX preamble.
-#'preamble': '',
-
-# Latex figure (float) alignment
-#'figure_align': 'htbp',
+    # The paper size ('letterpaper' or 'a4paper').
+    #'papersize': 'letterpaper',
+    # The font size ('10pt', '11pt' or '12pt').
+    #'pointsize': '10pt',
+    # Additional stuff for the LaTeX preamble.
+    #'preamble': '',
+    # Latex figure (float) alignment
+    #'figure_align': 'htbp',
 }
 
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'FRR.tex', u'FRR User Manual',
-     u'FRR', 'manual'),
+    (master_doc, "FRR.tex", u"FRR User Manual", u"FRR", "manual"),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
 # the title page.
-latex_logo = '../figures/frr-logo-medium.png'
+latex_logo = "../figures/frr-logo-medium.png"
 
 # For "manual" documents, if this is true, then toplevel headings are parts,
 # not chapters.
-#latex_use_parts = False
+# latex_use_parts = False
 
 # If true, show page references after internal links.
-#latex_show_pagerefs = False
+# latex_show_pagerefs = False
 
 # If true, show URL addresses after external links.
-#latex_show_urls = False
+# latex_show_urls = False
 
 # Documents to append as an appendix to all manuals.
-#latex_appendices = []
+# latex_appendices = []
 
 # If false, no module index is generated.
-#latex_domain_indices = True
+# latex_domain_indices = True
 
 
 # -- Options for manual page output ---------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    (master_doc, 'frr', u'FRR User Manual',
-     [author], 1)
-]
+man_pages = [(master_doc, "frr", u"FRR User Manual", [author], 1)]
 
 # If true, show URL addresses after external links.
-#man_show_urls = False
+# man_show_urls = False
 
 
 # -- Options for Texinfo output -------------------------------------------
@@ -335,29 +335,35 @@ man_pages = [
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'frr', u'FRR User Manual',
-     author, 'FRR', 'One line description of project.',
-     'Miscellaneous'),
+    (
+        master_doc,
+        "frr",
+        u"FRR User Manual",
+        author,
+        "FRR",
+        "One line description of project.",
+        "Miscellaneous",
+    ),
 ]
 
 # Documents to append as an appendix to all manuals.
-#texinfo_appendices = []
+# texinfo_appendices = []
 
 # If false, no module index is generated.
-#texinfo_domain_indices = True
+# texinfo_domain_indices = True
 
 # How to display URL addresses: 'footnote', 'no', or 'inline'.
-#texinfo_show_urls = 'footnote'
+# texinfo_show_urls = 'footnote'
 
 # If true, do not generate a @detailmenu in the "Top" node's menu.
-#texinfo_no_detailmenu = False
+# texinfo_no_detailmenu = False
 
 # contents of ../extra/frrlexer.py.
 # This is read here to support VPATH build. Since this section is execfile()'d
 # with the file location, we can safely use a relative path here to save the
 # contents of the lexer file for later use even if our relative path changes
 # due to VPATH.
-with open('../extra/frrlexer.py', 'rb') as lex:
+with open("../extra/frrlexer.py", "rb") as lex:
     frrlexerpy = lex.read()
 
 # Parse version string into int array
@@ -365,7 +371,7 @@ def vparse(s):
     a = []
 
     for c in s:
-        if c != '.':
+        if c != ".":
             a.append(int(c))
 
     while len(a) < 3:
@@ -373,22 +379,23 @@ def vparse(s):
 
     return a[:3]
 
+
 # custom extensions here
 def setup(app):
     # object type for FRR CLI commands, can be extended to document parent CLI
     # node later on
-    app.add_object_type('clicmd', 'clicmd')
+    app.add_object_type("clicmd", "clicmd")
 
     # css overrides for HTML theme
     # Note sphinx version differences
     sver = vparse(sphinx.__version__)
 
-    if sver < vparse('1.8.0') :
-        app.add_stylesheet('overrides.css')
-        app.add_javascript('overrides.js')
+    if sver < vparse("1.8.0"):
+        app.add_stylesheet("overrides.css")
+        app.add_javascript("overrides.js")
     else:
-        app.add_css_file('overrides.css')
-        app.add_js_file('overrides.js')
+        app.add_css_file("overrides.css")
+        app.add_js_file("overrides.js")
 
     # load Pygments lexer for FRR config syntax
     #
@@ -399,4 +406,4 @@ def setup(app):
     # frrlexer = pygments.lexers.load_lexer_from_file('../extra/frrlexer.py', lexername="FRRLexer")
     custom_namespace = {}
     exec(frrlexerpy, custom_namespace)
-    lexers['frr'] = custom_namespace['FRRLexer']()
+    lexers["frr"] = custom_namespace["FRRLexer"]()
index 0fd33eace82f1453454b972a1768c4965de79b75..5d5dfa5cc5de8ab76f1ffda3ecc6655cf268727e 100644 (file)
@@ -273,15 +273,15 @@ options from the list below.
    With this option, we provide a way to strip out these characters for APK dev
    package builds.
 
-..option:: --disable-version-build-config
+.. option:: --disable-version-build-config
 
    Remove the "configuerd with" field that has all of the build configuration
    arguments when reporting the version string in `show version` command.
 
-..option:: --with-pkg-extra-version=VER
+.. option:: --with-pkg-extra-version=VER
    Add extra version field, for packagers/distributions
 
-..option::  --with-pkg-git-version
+.. option::  --with-pkg-git-version
 
    Add git information to MOTD and build version string
 
@@ -355,6 +355,10 @@ options from the list below.
 
    Turn on the usage of PCRE Posix libs for regex functionality.
 
+.. option:: --enable-rpath
+
+   Set hardcoded rpaths in the executable [default=yes].
+
 You may specify any combination of the above options to the configure
 script. By default, the executables are placed in :file:`/usr/local/sbin`
 and the configuration files in :file:`/usr/local/etc`. The :file:`/usr/local/`
@@ -380,6 +384,10 @@ options to the configuration script.
    Look for YANG modules in `dir` [`prefix`/share/yang]. Note that the FRR
    YANG modules will be installed here.
 
+.. option:: --with-vici-socket <path>
+
+   Set StrongSWAN vici interface socket path [/var/run/charon.vici].
+
 Python dependency, documentation and tests
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
index 8cbbe0809fa35c1f0291e6ce539f16d5967d201d..98f5aff7dbdb759c6c527a92252243cb782bbbb5 100644 (file)
@@ -355,6 +355,11 @@ ISIS interface
    Enable or disable :rfc:`5303` Three-Way Handshake for P2P adjacencies.
    Three-Way Handshake is enabled by default.
 
+.. index:: [no] isis fast-reroute ti-lfa [level-1|level-2] [node-protection]
+.. clicmd:: [no] isis fast-reroute ti-lfa [level-1|level-2] [node-protection]
+
+   Enable per-prefix TI-LFA fast reroute link or node protection.
+
 .. _showing-isis-information:
 
 Showing ISIS information
@@ -418,8 +423,8 @@ Showing ISIS information
    Show topology IS-IS paths to Intermediate Systems, globally, in area
    (level-1) or domain (level-2).
 
-.. index:: show isis route [level-1|level-2]
-.. clicmd:: show isis route [level-1|level-2]
+.. index:: show isis route [level-1|level-2] [prefix-sid|backup]
+.. clicmd:: show isis route [level-1|level-2] [prefix-sid|backup]
 
    Show the ISIS routing table, as determined by the most recent SPF
    calculation.
@@ -510,14 +515,16 @@ Known limitations:
    MPLS dataplane. E.g. for Linux kernel, since version 4.13 the maximum value
    is 32.
 
-.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null]
-.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null]
+.. index:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535)> [no-php-flag|explicit-null] [n-flag-clear]
+.. clicmd:: [no] segment-routing prefix <A.B.C.D/M|X:X::X:X/M> <absolute (16-1048575)|index (0-65535) [no-php-flag|explicit-null] [n-flag-clear]
 
    Set the Segment Routing index or absolute label value for the specified
    prefix. The 'no-php-flag' means NO Penultimate Hop Popping that allows SR
    node to request to its neighbor to not pop the label. The 'explicit-null'
    flag allows SR node to request to its neighbor to send IP packet with the
-   EXPLICIT-NULL label.
+   EXPLICIT-NULL label. The 'n-flag-clear' option can be used to explicitly
+   clear the Node flag that is set by default for Prefix-SIDs associated to
+   loopback addresses. This option is necessary to configure Anycast-SIDs.
 
 .. index:: show isis segment-routing prefix-sids
 .. clicmd:: show isis segment-routing prefix-sids
@@ -633,6 +640,14 @@ Debugging ISIS
 
    IS-IS Segment Routing events.
 
+.. index:: debug isis ti-lfa
+.. clicmd:: debug isis ti-lfa
+
+.. index:: no debug isis ti-lfa
+.. clicmd:: no debug isis ti-lfa
+
+   IS-IS TI-LFA events.
+
 .. index:: show debugging isis
 .. clicmd:: show debugging isis
 
index 010526b637b721fdd6d010ec71affc93bf936e51..31b0df70ae892db6cf4f8f0d8d9f4f40d1c60241 100644 (file)
@@ -853,6 +853,50 @@ Redistribution
 .. index:: no router zebra
 .. clicmd:: no router zebra
 
+Graceful Restart Helper
+=======================
+
+.. index:: graceful-restart helper-only [A.B.C.D]
+.. clicmd:: graceful-restart helper-only [A.B.C.D]
+
+.. index:: no graceful-restart helper-only [A.B.C.D]
+.. clicmd:: no graceful-restart helper-only [A.B.C.D]
+
+   Configure Graceful Restart (RFC 3623) helper support.
+   By default, helper support is disabled for all neighbours.
+   This config enables/disables helper support on this router
+   for all neighbours.
+   To enable/disable helper support for a specific
+   neighbour, the router-id (A.B.C.D) has to be specified.
+
+.. index:: graceful-restart helper strict-lsa-checking
+.. clicmd:: graceful-restart helper strict-lsa-checking
+
+.. index:: no graceful-restart helper strict-lsa-checking
+.. clicmd:: no graceful-restart helper strict-lsa-checking
+
+   If 'strict-lsa-checking' is configured then the helper will
+   abort the Graceful Restart when a LSA change occurs which
+   affects the restarting router.
+   By default 'strict-lsa-checking' is enabled"
+
+.. index:: graceful-restart helper supported-grace-time
+.. clicmd:: graceful-restart helper supported-grace-time
+
+.. index:: no graceful-restart helper supported-grace-time
+.. clicmd:: no graceful-restart helper supported-grace-time
+
+   Supports as HELPER for configured grace period.
+
+.. index:: graceful-restart helper planned-only
+.. clicmd:: graceful-restart helper planned-only
+
+.. index:: no graceful-restart helper planned-only
+.. clicmd:: no graceful-restart helper planned-only
+
+   It helps to support as HELPER only for planned
+   restarts. By default, it supports both planned and
+   unplanned outages.
 
 .. _showing-ospf-information:
 
@@ -861,63 +905,73 @@ Showing Information
 
 .. _show-ip-ospf:
 
-.. index:: show ip ospf
-.. clicmd:: show ip ospf
+.. index:: show ip ospf [json]
+.. clicmd:: show ip ospf [json]
 
    Show information on a variety of general OSPF and area state and
    configuration information.
 
-.. index:: show ip ospf interface [INTERFACE]
-.. clicmd:: show ip ospf interface [INTERFACE]
+.. index:: show ip ospf interface [INTERFACE] [json]
+.. clicmd:: show ip ospf interface [INTERFACE] [json]
 
    Show state and configuration of OSPF the specified interface, or all
    interfaces if no interface is given.
 
-.. index:: show ip ospf neighbor
-.. clicmd:: show ip ospf neighbor
+.. index:: show ip ospf neighbor [json]
+.. clicmd:: show ip ospf neighbor [json]
 
-.. index:: show ip ospf neighbor INTERFACE
-.. clicmd:: show ip ospf neighbor INTERFACE
+.. index:: show ip ospf neighbor INTERFACE [json]
+.. clicmd:: show ip ospf neighbor INTERFACE [json]
 
-.. index:: show ip ospf neighbor detail
-.. clicmd:: show ip ospf neighbor detail
+.. index:: show ip ospf neighbor detail [json]
+.. clicmd:: show ip ospf neighbor detail [json]
 
-.. index:: show ip ospf neighbor INTERFACE detail
-.. clicmd:: show ip ospf neighbor INTERFACE detail
+.. index:: show ip ospf neighbor INTERFACE detail [json]
+.. clicmd:: show ip ospf neighbor INTERFACE detail [json]
 
-.. index:: show ip ospf database
-.. clicmd:: show ip ospf database
+   Display lsa information of LSDB.
+   Json o/p of this command covers base route information
+   i.e all LSAs except opaque lsa info.
 
-.. index:: show ip ospf database (asbr-summary|external|network|router|summary)
-.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary)
+.. index:: show ip ospf database [json]
+.. clicmd:: show ip ospf database [json]
 
-.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID
-.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID
+.. index:: show ip ospf database (asbr-summary|external|network|router|summary) [json]
+.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) [json]
 
-.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER
-.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER
+.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json]
+.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID [json]
 
-.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER
-.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER
+.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json]
+.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID adv-router ADV-ROUTER [json]
 
-.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate
-.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate
+.. index:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json]
+.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) adv-router ADV-ROUTER [json]
 
-.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate
-.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate
+.. index:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json]
+.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) LINK-STATE-ID self-originate [json]
 
-.. index:: show ip ospf database max-age
-.. clicmd:: show ip ospf database max-age
+.. index:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json]
+.. clicmd:: show ip ospf database (asbr-summary|external|network|router|summary) self-originate [json]
 
-.. index:: show ip ospf database self-originate
-.. clicmd:: show ip ospf database self-originate
+.. index:: show ip ospf database max-age [json]
+.. clicmd:: show ip ospf database max-age [json]
 
-.. index:: show ip ospf route
-.. clicmd:: show ip ospf route
+.. index:: show ip ospf database self-originate [json]
+.. clicmd:: show ip ospf database self-originate [json]
+
+.. index:: show ip ospf route [json]
+.. clicmd:: show ip ospf route [json]
 
    Show the OSPF routing table, as determined by the most recent SPF
    calculation.
 
+.. index:: show ip ospf graceful-restart helper [detail] [json]
+.. clicmd:: show ip ospf graceful-restart helper [detail] [json]
+
+   Displays the Grcaeful Restart Helper details including helper
+   config changes.
+
 .. _opaque-lsa:
 
 Opaque LSA
@@ -1127,6 +1181,41 @@ dataplane.
    self router. Optional JSON output can be obtained by appending 'json' to the
    end of the command.
 
+External Route Summarisation
+============================
+This feature summarises originated external LSAs(Type-5 and Type-7).
+Summary Route will be originated on-behalf of all matched external LSAs.
+
+.. index:: [no] summary-address A.B.C.D/M [tag (1-4294967295)]
+.. clicmd:: [no] summary-address A.B.C.D/M [tag (1-4294967295)]
+
+   This command enable/disables summarisation for the configured address
+   range. Tag is the optional parameter. If tag configured Summary route
+   will be originated with the configured tag.
+
+.. index:: [no] summary-address A.B.C.D/M no-advertise
+.. clicmd:: [no] summary-address A.B.C.D/M no-advertise
+
+   This command to ensure not advertise the summary lsa for the matched
+   external LSAs.
+
+.. index:: aggregation timer (5-1800)
+.. clicmd:: aggregation timer (5-1800)
+
+   Configure aggregation delay timer interval. Summarisation starts only after
+   this delay timer expiry. By default, delay interval is 5 secs.
+
+.. index:: no aggregation timer
+.. clicmd:: no aggregation timer
+
+   Resetting the aggregation delay interval to default value.
+
+.. index:: show ip ospf [vrf <NAME|all>] summary-address [detail] [json]
+.. clicmd:: show ip ospf [vrf <NAME|all>] summary-address [detail] [json]
+
+   Show configuration for display all configured summary routes with
+   matching external LSA information.
+
 Debugging OSPF
 ==============
 
@@ -1218,9 +1307,21 @@ Debugging OSPF
 
    Show debug information of ZEBRA API
 
+.. index:: debug ospf graceful-restart helper
+.. clicmd:: debug ospf graceful-restart helper
+
+.. index:: no debug ospf graceful-restart helper
+.. clicmd:: no debug ospf graceful-restart helper
+
+   Enable/disable debug information for OSPF Graceful Restart Helper
+
 .. index:: show debugging ospf
 .. clicmd:: show debugging ospf
 
+.. index:: [no] debug ospf lsa aggregate
+.. clicmd:: [no] debug ospf lsa aggregate
+
+   Debug commnd to enable/disable external route summarisation specific debugs.
 
 OSPF Configuration Examples
 ===========================
index d5899ab4555b8d5d6eed8842dd6592f896bd7a81..b0a90bfc48fc3c42fd4b3cdc50b9569328f10e38 100644 (file)
@@ -337,6 +337,42 @@ caution. Most of the time this will not be necessary.
    Insert into the Multicast Rib Route A.B.C.D/M using the specified INTERFACE.
    The distance can be specified as well if desired.
 
+.. _msdp-configuration:
+
+Multicast Source Discovery Protocol (MSDP) Configuration
+========================================================
+
+.. index:: ip msdp mesh-group [WORD] member A.B.C.D
+.. clicmd:: ip msdp mesh-group [WORD] member A.B.C.D
+
+   Include a MSDP peer as a member of a MSDP mesh-group.
+
+.. index:: ip msdp mesh-group [WORD] source A.B.C.D
+.. clicmd:: ip msdp mesh-group [WORD] source A.B.C.D
+
+   Create a MSDP mesh-group, defining a name for it and an associated local source
+   address.
+
+.. index:: ip msdp peer A.B.C.D source A.B.C.D
+.. clicmd:: ip msdp peer A.B.C.D source A.B.C.D
+
+   Establish a MSDP connection with a peer.
+
+.. index:: no ip msdp mesh-group [WORD] member A.B.C.D
+.. clicmd:: no ip msdp mesh-group [WORD] member A.B.C.D
+
+   Remove a MSDP peer member from a MSDP mesh-group.
+
+.. index:: no ip msdp mesh-group [WORD] source A.B.C.D
+.. clicmd:: no ip msdp mesh-group [WORD] source A.B.C.D
+
+   Delete a MSDP mesh-group.
+
+.. index:: no ip msdp peer A.B.C.D
+.. clicmd:: no ip msdp peer A.B.C.D
+
+   Delete a MSDP peer connection.
+
 .. _show-pim-information:
 
 Show PIM Information
@@ -422,6 +458,19 @@ cause great confusion.
    Display total number of S,G mroutes and number of S,G mroutes
    installed into the kernel for all vrfs.
 
+.. index:: show ip msdp mesh-group
+.. clicmd:: show ip msdp mesh-group
+
+   Display the configured mesh-groups, the local address associated with each
+   mesh-group, the peer members included in each mesh-group, and their status.
+
+.. index:: show ip msdp peer
+.. clicmd:: show ip msdp peer
+
+   Display information about the MSDP peers. That includes the peer address,
+   the local address used to establish the connection to the peer, the
+   connection status, and the number of active sources.
+
 .. index:: show ip pim assert
 .. clicmd:: show ip pim assert
 
index d21492624579a0542ee5054252e004997f10034a..0087d41a2345cc298a613eb4ab61d3c95e2c54af 100644 (file)
@@ -39,6 +39,7 @@ can be achieved by amending the default view from SNMP
 :file:`/etc/snmp/snmpd.conf`:
 
 ::
+
    # This is the default view
    view all    included  .1 80
    # Remove ipRouteTable from view
index 98655e6cbaf3e883883531275b4abfadac3557be..624e3cfe1a3ac4c1cf64253683160cbd4023cf94 100644 (file)
@@ -1033,14 +1033,15 @@ zebra Terminal Mode Commands
    total number of route nodes in the table.  Which will be higher than
    the actual number of routes that are held.
 
-.. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]]
-.. clicmd:: show nexthop-group rib [ID] [vrf NAME]
+.. index:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] [type]
+.. clicmd:: show nexthop-group rib [ID] [vrf NAME] [singleton [ip|ip6]] [type]
 
    Display nexthop groups created by zebra.  The [vrf NAME] option
    is only meaningful if you have started zebra with the --vrfwnetns
    option as that nexthop groups are per namespace in linux.
    If you specify singleton you would like to see the singleton
-   nexthop groups that do have an afi.
+   nexthop groups that do have an afi. [type] allows you to filter those
+   only coming from a specific NHG type (protocol).
 
 
 Router-id
index 97de73116b3cfc3738c944de5b18a77285267d47..dfce2acad4885ed7462f447222a42a2bc4a7cbc5 100644 (file)
@@ -122,8 +122,8 @@ void eigrp_ip_header_dump(struct ip *iph)
        zlog_debug("ip_ttl %u", iph->ip_ttl);
        zlog_debug("ip_p %u", iph->ip_p);
        zlog_debug("ip_sum 0x%x", (uint32_t)iph->ip_sum);
-       zlog_debug("ip_src %s", inet_ntoa(iph->ip_src));
-       zlog_debug("ip_dst %s", inet_ntoa(iph->ip_dst));
+       zlog_debug("ip_src %pI4", &iph->ip_src);
+       zlog_debug("ip_dst %pI4", &iph->ip_dst);
 }
 
 /*
@@ -204,8 +204,7 @@ void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr,
                                int detail)
 {
 
-       vty_out(vty, "%-3u %-17s %-21s", 0, eigrp_neigh_ip_string(nbr),
-               IF_NAME(nbr->ei));
+       vty_out(vty, "%-3u %-17pI4 %-21s", 0, &nbr->src, IF_NAME(nbr->ei));
        if (nbr->t_holddown)
                vty_out(vty, "%-7lu",
                        thread_timer_remain_second(nbr->t_holddown));
@@ -231,8 +230,8 @@ void show_ip_eigrp_neighbor_sub(struct vty *vty, struct eigrp_neighbor *nbr,
  */
 void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp)
 {
-       vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%s)\n\n", eigrp->AS,
-               inet_ntoa(eigrp->router_id));
+       vty_out(vty, "\nEIGRP Topology Table for AS(%d)/ID(%pI4)\n\n",
+               eigrp->AS, &eigrp->router_id);
        vty_out(vty,
                "Codes: P - Passive, A - Active, U - Update, Q - Query, R - Reply\n       r - reply Status, s - sia Status\n\n");
 }
@@ -240,12 +239,10 @@ void show_ip_eigrp_topology_header(struct vty *vty, struct eigrp *eigrp)
 void show_ip_eigrp_prefix_entry(struct vty *vty, struct eigrp_prefix_entry *tn)
 {
        struct list *successors = eigrp_topology_get_successor(tn);
-       char buffer[PREFIX_STRLEN];
 
        vty_out(vty, "%-3c", (tn->state > 0) ? 'A' : 'P');
 
-       vty_out(vty, "%s, ",
-               prefix2str(tn->destination, buffer, PREFIX_STRLEN));
+       vty_out(vty, "%pFX, ", tn->destination);
        vty_out(vty, "%u successors, ", (successors) ? successors->count : 0);
        vty_out(vty, "FD is %u, serno: %" PRIu64 " \n", tn->fdistance,
                tn->serno);
@@ -269,8 +266,8 @@ void show_ip_eigrp_nexthop_entry(struct vty *vty, struct eigrp *eigrp,
                vty_out(vty, "%-7s%s, %s\n", " ", "via Connected",
                        IF_NAME(te->ei));
        else {
-               vty_out(vty, "%-7s%s%s (%u/%u), %s\n", " ", "via ",
-                       inet_ntoa(te->adv_router->src), te->distance,
+               vty_out(vty, "%-7s%s%pI4 (%u/%u), %s\n", " ", "via ",
+                       &te->adv_router->src, te->distance,
                        te->reported_distance, IF_NAME(te->ei));
        }
 }
index f141f3cbc65f7662a0ff5421ebda0613e6704721..348356bb3c74bff2fa7939acdbd97f581bbdfefc 100644 (file)
@@ -138,21 +138,6 @@ extern unsigned long term_debug_eigrp_zebra;
 
 /* Prototypes. */
 extern const char *eigrp_if_name_string(struct eigrp_interface *);
-static inline const char
-*eigrp_topology_ip_string(struct eigrp_prefix_entry *tn)
-{
-       return inet_ntoa(tn->destination->u.prefix4);
-}
-
-static inline const char *eigrp_if_ip_string(struct eigrp_interface *ei)
-{
-       return ei ? inet_ntoa(ei->address.u.prefix4) : "inactive";
-}
-
-static inline const char *eigrp_neigh_ip_string(struct eigrp_neighbor *nbr)
-{
-       return inet_ntoa(nbr->src);
-}
 
 extern void eigrp_ip_header_dump(struct ip *);
 extern void eigrp_header_dump(struct eigrp_header *);
index 9d5d45ca50f044582119b713ce67d04c5958b1d1..009b57e05f51d4d37e7e9500aa52ac0b6ddf43de 100644 (file)
@@ -159,13 +159,10 @@ void eigrp_distribute_update(struct distribute_ctx *ctx,
 #endif
                // TODO: check Graceful restart after 10sec
 
-               /* check if there is already GR scheduled */
-               if (e->t_distribute != NULL) {
-                       /* if is, cancel schedule */
-                       thread_cancel(e->t_distribute);
-               }
+               /* cancel GR scheduled */
+               thread_cancel(&(e->t_distribute));
+
                /* schedule Graceful restart for whole process in 10sec */
-               e->t_distribute = NULL;
                thread_add_timer(master, eigrp_distribute_timer_process, e,
                                 (10), &e->t_distribute);
 
@@ -267,11 +264,8 @@ void eigrp_distribute_update(struct distribute_ctx *ctx,
 #endif
        // TODO: check Graceful restart after 10sec
 
-       /* check if there is already GR scheduled */
-       if (ei->t_distribute != NULL) {
-               /* if is, cancel schedule */
-               thread_cancel(ei->t_distribute);
-       }
+       /* Cancel GR scheduled */
+       thread_cancel(&(ei->t_distribute));
        /* schedule Graceful restart for interface in 10sec */
        e->t_distribute = NULL;
        thread_add_timer(master, eigrp_distribute_timer_interface, ei, 10,
index e43eca0e0dc68be1370179c6ad435b757a972ee2..a69a3eec0a214535e098f70cf209f0f5359182d4 100644 (file)
@@ -417,9 +417,9 @@ int eigrp_fsm_event(struct eigrp_fsm_action_message *msg)
        enum eigrp_fsm_events event = eigrp_get_fsm_event(msg);
 
        zlog_info(
-               "EIGRP AS: %d State: %s Event: %s Network: %s Packet Type: %s Reply RIJ Count: %d change: %s",
+               "EIGRP AS: %d State: %s Event: %s Network: %pI4 Packet Type: %s Reply RIJ Count: %d change: %s",
                msg->eigrp->AS, prefix_state2str(msg->prefix->state),
-               fsm_state2str(event), eigrp_topology_ip_string(msg->prefix),
+               fsm_state2str(event), &msg->prefix->destination->u.prefix4,
                packet_type2str(msg->packet_type), msg->prefix->rij->count,
                change2str(msg->change));
        (*(NSM[msg->prefix->state][event].func))(msg);
index 6f93cd7b3ef3b76e397857eb853110d6fab133c6..f512833e0a3ab467cfc9792ac01de42d9235eb96 100644 (file)
@@ -144,10 +144,11 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
            && (eigrp->k_values[4] == nbr->K5)) {
 
                if (eigrp_nbr_state_get(nbr) == EIGRP_NEIGHBOR_DOWN) {
-                       zlog_info("Neighbor %s (%s) is pending: new adjacency",
-                                 inet_ntoa(nbr->src),
-                                 ifindex2ifname(nbr->ei->ifp->ifindex,
-                                                eigrp->vrf_id));
+                       zlog_info(
+                               "Neighbor %pI4 (%s) is pending: new adjacency",
+                               &nbr->src,
+                               ifindex2ifname(nbr->ei->ifp->ifindex,
+                                              eigrp->vrf_id));
 
                        /* Expedited hello sent */
                        eigrp_hello_send(nbr->ei, EIGRP_HELLO_NORMAL, NULL);
@@ -164,16 +165,16 @@ eigrp_hello_parameter_decode(struct eigrp_neighbor *nbr,
                             & param->K5)
                            == 255) {
                                zlog_info(
-                                       "Neighbor %s (%s) is down: Interface PEER-TERMINATION received",
-                                       inet_ntoa(nbr->src),
+                                       "Neighbor %pI4 (%s) is down: Interface PEER-TERMINATION received",
+                                       &nbr->src,
                                        ifindex2ifname(nbr->ei->ifp->ifindex,
                                                       eigrp->vrf_id));
                                eigrp_nbr_delete(nbr);
                                return NULL;
                        } else {
                                zlog_info(
-                                       "Neighbor %s (%s) going down: Kvalue mismatch",
-                                       inet_ntoa(nbr->src),
+                                       "Neighbor %pI4 (%s) going down: Kvalue mismatch",
+                                       &nbr->src,
                                        ifindex2ifname(nbr->ei->ifp->ifindex,
                                                       eigrp->vrf_id));
                                eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
@@ -253,9 +254,10 @@ static void eigrp_peer_termination_decode(struct eigrp_neighbor *nbr,
        uint32_t received_ip = param->neighbor_ip;
 
        if (my_ip == received_ip) {
-               zlog_info("Neighbor %s (%s) is down: Peer Termination received",
-                         inet_ntoa(nbr->src),
-                         ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
+               zlog_info(
+                       "Neighbor %pI4 (%s) is down: Peer Termination received",
+                       &nbr->src,
+                       ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
                /* set neighbor to DOWN */
                nbr->state = EIGRP_NEIGHBOR_DOWN;
                /* delete neighbor */
@@ -330,9 +332,9 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
        assert(nbr);
 
        if (IS_DEBUG_EIGRP_PACKET(eigrph->opcode - 1, RECV))
-               zlog_debug("Processing Hello size[%u] int(%s) nbr(%s)", size,
+               zlog_debug("Processing Hello size[%u] int(%s) nbr(%pI4)", size,
                           ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id),
-                          inet_ntoa(nbr->src));
+                          &nbr->src);
 
        size -= EIGRP_HEADER_LEN;
        if (size < 0)
@@ -403,8 +405,7 @@ void eigrp_hello_receive(struct eigrp *eigrp, struct ip *iph,
        }
 
        if (IS_DEBUG_EIGRP_PACKET(0, RECV))
-               zlog_debug("Hello Packet received from %s",
-                          inet_ntoa(nbr->src));
+               zlog_debug("Hello Packet received from %pI4", &nbr->src);
 }
 
 uint32_t FRR_MAJOR;
@@ -708,9 +709,8 @@ void eigrp_hello_send_ack(struct eigrp_neighbor *nbr)
 
        if (ep) {
                if (IS_DEBUG_EIGRP_PACKET(0, SEND))
-                       zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%s]",
-                                  nbr->recv_sequence_number,
-                                  inet_ntoa(nbr->src));
+                       zlog_debug("Queueing [Hello] Ack Seq [%u] nbr [%pI4]",
+                                  nbr->recv_sequence_number, &nbr->src);
 
                /* Add packet to the top of the interface output queue*/
                eigrp_fifo_push(nbr->ei->obuf, ep);
index 9ef4e8623702ca3e46d92e5862711d51c9aeecef..dd43dd047857612d88b2f5e5b749557309dcfa46 100644 (file)
@@ -331,8 +331,7 @@ int eigrp_if_down(struct eigrp_interface *ei)
                return 0;
 
        /* Shutdown packet reception and sending */
-       if (ei->t_hello)
-               THREAD_OFF(ei->t_hello);
+       THREAD_OFF(ei->t_hello);
 
        eigrp_if_stream_unset(ei);
 
@@ -359,7 +358,7 @@ void eigrp_if_stream_unset(struct eigrp_interface *ei)
        if (ei->on_write_q) {
                listnode_delete(eigrp->oi_write_q, ei);
                if (list_isempty(eigrp->oi_write_q))
-                       thread_cancel(eigrp->t_write);
+                       thread_cancel(&(eigrp->t_write));
                ei->on_write_q = 0;
        }
 }
@@ -421,7 +420,7 @@ void eigrp_if_free(struct eigrp_interface *ei, int source)
        struct eigrp *eigrp = ei->eigrp;
 
        if (source == INTERFACE_DOWN_BY_VTY) {
-               THREAD_OFF(ei->t_hello);
+               thread_cancel(&ei->t_hello);
                eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
        }
 
index 2ae3997fae2fde9ffa4fba782d62b807facfac1c..2d5bb0a7d13e9969ff089abf2f0ead200086931e 100644 (file)
@@ -87,10 +87,6 @@ static struct eigrp_neighbor *eigrp_nbr_add(struct eigrp_interface *ei,
        nbr = eigrp_nbr_new(ei);
        nbr->src = iph->ip_src;
 
-       //  if (IS_DEBUG_EIGRP_EVENT)
-       //    zlog_debug("NSM[%s:%s]: start", IF_NAME (nbr->oi),
-       //               inet_ntoa (nbr->router_id));
-
        return nbr;
 }
 
@@ -197,8 +193,7 @@ int holddown_timer_expired(struct thread *thread)
        struct eigrp_neighbor *nbr = THREAD_ARG(thread);
        struct eigrp *eigrp = nbr->ei->eigrp;
 
-       zlog_info("Neighbor %s (%s) is down: holding time expired",
-                 inet_ntoa(nbr->src),
+       zlog_info("Neighbor %pI4 (%s) is down: holding time expired", &nbr->src,
                  ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
        nbr->state = EIGRP_NEIGHBOR_DOWN;
        eigrp_nbr_delete(nbr);
@@ -330,13 +325,12 @@ void eigrp_nbr_hard_restart(struct eigrp_neighbor *nbr, struct vty *vty)
 {
        struct eigrp *eigrp = nbr->ei->eigrp;
 
-       zlog_debug("Neighbor %s (%s) is down: manually cleared",
-                  inet_ntoa(nbr->src),
+       zlog_debug("Neighbor %pI4 (%s) is down: manually cleared", &nbr->src,
                   ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
        if (vty != NULL) {
                vty_time_print(vty, 0);
-               vty_out(vty, "Neighbor %s (%s) is down: manually cleared\n",
-                       inet_ntoa(nbr->src),
+               vty_out(vty, "Neighbor %pI4 (%s) is down: manually cleared\n",
+                       &nbr->src,
                        ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
        }
 
index 92b5ce34826470120f92d57a71ce20a058ee73e6..bd8ec2f879251fefd064806682a0e141b93ea68a 100644 (file)
@@ -160,9 +160,8 @@ int eigrp_if_ipmulticast(struct eigrp *top, struct prefix *p,
        ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
        if (ret < 0)
                zlog_warn(
-                       "can't setsockopt IP_MULTICAST_IF (fd %d, addr %s, ifindex %u): %s",
-                       top->fd, inet_ntoa(p->u.prefix4), ifindex,
-                       safe_strerror(errno));
+                       "can't setsockopt IP_MULTICAST_IF (fd %d, addr %pI4, ifindex %u): %s",
+                       top->fd, &p->u.prefix4, ifindex, safe_strerror(errno));
 
        return ret;
 }
@@ -178,12 +177,11 @@ int eigrp_if_add_allspfrouters(struct eigrp *top, struct prefix *p,
                htonl(EIGRP_MULTICAST_ADDRESS), ifindex);
        if (ret < 0)
                zlog_warn(
-                       "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?",
-                       top->fd, inet_ntoa(p->u.prefix4), ifindex,
-                       safe_strerror(errno));
+                       "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?",
+                       top->fd, &p->u.prefix4, ifindex, safe_strerror(errno));
        else
-               zlog_debug("interface %s [%u] join EIGRP Multicast group.",
-                          inet_ntoa(p->u.prefix4), ifindex);
+               zlog_debug("interface %pI4 [%u] join EIGRP Multicast group.",
+                          &p->u.prefix4, ifindex);
 
        return ret;
 }
@@ -198,12 +196,11 @@ int eigrp_if_drop_allspfrouters(struct eigrp *top, struct prefix *p,
                htonl(EIGRP_MULTICAST_ADDRESS), ifindex);
        if (ret < 0)
                zlog_warn(
-                       "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s",
-                       top->fd, inet_ntoa(p->u.prefix4), ifindex,
-                       safe_strerror(errno));
+                       "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s",
+                       top->fd, &p->u.prefix4, ifindex, safe_strerror(errno));
        else
-               zlog_debug("interface %s [%u] leave EIGRP Multicast group.",
-                          inet_ntoa(p->u.prefix4), ifindex);
+               zlog_debug("interface %pI4 [%u] leave EIGRP Multicast group.",
+                          &p->u.prefix4, ifindex);
 
        return ret;
 }
index 13887368f72c6ed09f325af2443b063efe803ab1..5b87f7264016c37d382c4a6cb328a12d4f69e5c1 100644 (file)
@@ -243,10 +243,12 @@ static int eigrpd_instance_active_time_modify(struct nb_cb_modify_args *args)
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
+               snprintf(args->errmsg, args->errmsg_len,
+                        "active time not implemented yet");
                /* NOTHING */
                break;
        }
@@ -677,11 +679,12 @@ static int eigrpd_instance_neighbor_create(struct nb_cb_create_args *args)
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* NOTHING */
+               snprintf(args->errmsg, args->errmsg_len,
+                        "neighbor Command is not implemented yet");
                break;
        }
 
@@ -693,11 +696,12 @@ static int eigrpd_instance_neighbor_destroy(struct nb_cb_destroy_args *args)
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* NOTHING */
+               snprintf(args->errmsg, args->errmsg_len,
+                        "no neighbor Command is not implemented yet");
                break;
        }
 
@@ -768,11 +772,13 @@ eigrpd_instance_redistribute_route_map_modify(struct nb_cb_modify_args *args)
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* NOTHING */
+               snprintf(
+                       args->errmsg, args->errmsg_len,
+                       "'redistribute X route-map FOO' command not implemented yet");
                break;
        }
 
@@ -785,11 +791,13 @@ eigrpd_instance_redistribute_route_map_destroy(struct nb_cb_destroy_args *args)
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* NOTHING */
+               snprintf(
+                       args->errmsg, args->errmsg_len,
+                       "'no redistribute X route-map FOO' command not implemented yet");
                break;
        }
 
@@ -1079,10 +1087,12 @@ lib_interface_eigrp_split_horizon_modify(struct nb_cb_modify_args *args)
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
+               snprintf(args->errmsg, args->errmsg_len,
+                        "split-horizon command not implemented yet");
                /* NOTHING */
                break;
        }
@@ -1161,11 +1171,12 @@ static int lib_interface_eigrp_instance_summarize_addresses_create(
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* NOTHING */
+               snprintf(args->errmsg, args->errmsg_len,
+                        "summary command not implemented yet");
                break;
        }
 
@@ -1178,10 +1189,12 @@ static int lib_interface_eigrp_instance_summarize_addresses_destroy(
        switch (args->event) {
        case NB_EV_VALIDATE:
                /* TODO: Not implemented. */
-               return NB_ERR_INCONSISTENCY;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
+               snprintf(args->errmsg, args->errmsg_len,
+                        "no summary command not implemented yet");
                /* NOTHING */
                break;
        }
index cfff63f839da8b89ac67cdaf68d51daf8d5d76e6..f5f6ab5dffe55bdcfc394e0513b4bb7340bdda0a 100644 (file)
@@ -442,17 +442,16 @@ int eigrp_write(struct thread *thread)
        if (IS_DEBUG_EIGRP_TRANSMIT(0, SEND)) {
                eigrph = (struct eigrp_header *)STREAM_DATA(ep->s);
                zlog_debug(
-                       "Sending [%s][%d/%d] to [%s] via [%s] ret [%d].",
+                       "Sending [%s][%d/%d] to [%pI4] via [%s] ret [%d].",
                        lookup_msg(eigrp_packet_type_str, eigrph->opcode, NULL),
-                       seqno, ack, inet_ntoa(ep->dst), IF_NAME(ei), ret);
+                       seqno, ack, &ep->dst, IF_NAME(ei), ret);
        }
 
        if (ret < 0)
                zlog_warn(
-                       "*** sendmsg in eigrp_write failed to %s, id %d, off %d, len %d, interface %s, mtu %u: %s",
-                       inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off,
-                       iph.ip_len, ei->ifp->name, ei->ifp->mtu,
-                       safe_strerror(errno));
+                       "*** sendmsg in eigrp_write failed to %pI4, id %d, off %d, len %d, interface %s, mtu %u: %s",
+                       &iph.ip_dst, iph.ip_id, iph.ip_off, iph.ip_len,
+                       ei->ifp->name, ei->ifp->mtu, safe_strerror(errno));
 
        /* Now delete packet from queue. */
        eigrp_packet_delete(ei);
@@ -552,8 +551,8 @@ int eigrp_read(struct thread *thread)
            || (IPV4_ADDR_SAME(&srcaddr, &ei->address.u.prefix4))) {
                if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
                        zlog_debug(
-                               "eigrp_read[%s]: Dropping self-originated packet",
-                               inet_ntoa(srcaddr));
+                               "eigrp_read[%pI4]: Dropping self-originated packet",
+                               &srcaddr);
                return 0;
        }
 
@@ -596,8 +595,9 @@ int eigrp_read(struct thread *thread)
         */
        else if (ei->ifp != ifp) {
                if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
-                       zlog_warn("Packet from [%s] received on wrong link %s",
-                                 inet_ntoa(iph->ip_src), ifp->name);
+                       zlog_warn(
+                               "Packet from [%pI4] received on wrong link %s",
+                               &iph->ip_src, ifp->name);
                return 0;
        }
 
@@ -606,8 +606,8 @@ int eigrp_read(struct thread *thread)
        if (ret < 0) {
                if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
                        zlog_debug(
-                               "eigrp_read[%s]: Header check failed, dropping.",
-                               inet_ntoa(iph->ip_src));
+                               "eigrp_read[%pI4]: Header check failed, dropping.",
+                               &iph->ip_src);
                return ret;
        }
 
@@ -615,17 +615,12 @@ int eigrp_read(struct thread *thread)
           start of the eigrp TLVs */
        opcode = eigrph->opcode;
 
-       if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV)) {
-               char src[PREFIX_STRLEN], dst[PREFIX_STRLEN];
-
-               strlcpy(src, inet_ntoa(iph->ip_src), sizeof(src));
-               strlcpy(dst, inet_ntoa(iph->ip_dst), sizeof(dst));
+       if (IS_DEBUG_EIGRP_TRANSMIT(0, RECV))
                zlog_debug(
-                       "Received [%s][%d/%d] length [%u] via [%s] src [%s] dst [%s]",
+                       "Received [%s][%d/%d] length [%u] via [%s] src [%pI4] dst [%pI4]",
                        lookup_msg(eigrp_packet_type_str, opcode, NULL),
                        ntohl(eigrph->sequence), ntohl(eigrph->ack), length,
-                       IF_NAME(ei), src, dst);
-       }
+                       IF_NAME(ei), &iph->ip_src, &iph->ip_dst);
 
        /* Read rest of the packet and call each sort of packet routine. */
        stream_forward_getp(ibuf, EIGRP_HEADER_LEN);
@@ -648,8 +643,9 @@ int eigrp_read(struct thread *thread)
                            && (ntohl(eigrph->ack)
                                == nbr->init_sequence_number)) {
                                eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_UP);
-                               zlog_info("Neighbor(%s) adjacency became full",
-                                         inet_ntoa(nbr->src));
+                               zlog_info(
+                                       "Neighbor(%pI4) adjacency became full",
+                                       &nbr->src);
                                nbr->init_sequence_number = 0;
                                nbr->recv_sequence_number =
                                        ntohl(eigrph->sequence);
@@ -957,8 +953,8 @@ static int eigrp_verify_header(struct stream *ibuf, struct eigrp_interface *ei,
        /* Check network mask, Silently discarded. */
        if (!eigrp_check_network_mask(ei, iph->ip_src)) {
                zlog_warn(
-                       "interface %s: eigrp_read network address is not same [%s]",
-                       IF_NAME(ei), inet_ntoa(iph->ip_src));
+                       "interface %s: eigrp_read network address is not same [%pI4]",
+                       IF_NAME(ei), &iph->ip_src);
                return -1;
        }
        //
index 79405efbbf935a99f59039b09f6413586ed9a104..26bb27d7ac6e9b30ca898211912d6f196ff09909 100644 (file)
@@ -168,13 +168,10 @@ void eigrp_reply_receive(struct eigrp *eigrp, struct ip *iph,
                 * Destination must exists
                 */
                if (!dest) {
-                       char buf[PREFIX_STRLEN];
-
                        flog_err(
                                EC_EIGRP_PACKET,
-                               "%s: Received prefix %s which we do not know about",
-                               __func__,
-                               prefix2str(&dest_addr, buf, sizeof(buf)));
+                               "%s: Received prefix %pFX which we do not know about",
+                               __func__, &dest_addr);
                        eigrp_IPv4_InternalTLV_free(tlv);
                        continue;
                }
index 7676af15f283e4d8b941c5ef1005a86f5c151a8c..2dbee166946f6003f238ea87de71d5ad0e6fd04f 100644 (file)
@@ -133,14 +133,10 @@ void eigrp_prefix_entry_add(struct route_table *topology,
 
        rn = route_node_get(topology, pe->destination);
        if (rn->info) {
-               if (IS_DEBUG_EIGRP_EVENT) {
-                       char buf[PREFIX_STRLEN];
-
+               if (IS_DEBUG_EIGRP_EVENT)
                        zlog_debug(
-                               "%s: %s Should we have found this entry in the topo table?",
-                               __func__,
-                               prefix2str(pe->destination, buf, sizeof(buf)));
-               }
+                               "%s: %pFX Should we have found this entry in the topo table?",
+                               __func__, pe->destination);
                route_unlock_node(rn);
        }
 
index 6e2a81e32a07ce94be8a461040cec07a7bf779d2..cd30eb5ab5f60fe0d4110ecfaed468aa70ae73bb 100644 (file)
@@ -141,10 +141,8 @@ static void eigrp_update_receive_GR_ask(struct eigrp *eigrp,
 
        /* iterate over all prefixes which weren't advertised by neighbor */
        for (ALL_LIST_ELEMENTS_RO(nbr_prefixes, node1, prefix)) {
-               char buffer[PREFIX_STRLEN];
-               zlog_debug(
-                       "GR receive: Neighbor not advertised %s",
-                       prefix2str(prefix->destination, buffer, PREFIX_STRLEN));
+               zlog_debug("GR receive: Neighbor not advertised %pFX",
+                          prefix->destination);
 
                fsm_msg.metrics = prefix->reported_metric;
                /* set delay to MAX */
@@ -209,18 +207,18 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
        nbr->recv_sequence_number = ntohl(eigrph->sequence);
        if (IS_DEBUG_EIGRP_PACKET(0, RECV))
                zlog_debug(
-                       "Processing Update size[%u] int(%s) nbr(%s) seq [%u] flags [%0x]",
+                       "Processing Update size[%u] int(%s) nbr(%pI4) seq [%u] flags [%0x]",
                        size,
                        ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id),
-                       inet_ntoa(nbr->src), nbr->recv_sequence_number, flags);
+                       &nbr->src, nbr->recv_sequence_number, flags);
 
 
        if ((flags == (EIGRP_INIT_FLAG + EIGRP_RS_FLAG + EIGRP_EOT_FLAG))
            && (!same)) {
                /* Graceful restart Update received with all routes */
 
-               zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
-                         inet_ntoa(nbr->src),
+               zlog_info("Neighbor %pI4 (%s) is resync: peer graceful-restart",
+                         &nbr->src,
                          ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
 
                /* get all prefixes from neighbor from topology table */
@@ -231,8 +229,8 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
                /* Graceful restart Update received, routes also in next packet
                 */
 
-               zlog_info("Neighbor %s (%s) is resync: peer graceful-restart",
-                         inet_ntoa(nbr->src),
+               zlog_info("Neighbor %pI4 (%s) is resync: peer graceful-restart",
+                         &nbr->src,
                          ifindex2ifname(nbr->ei->ifp->ifindex, eigrp->vrf_id));
 
                /* get all prefixes from neighbor from topology table */
@@ -279,15 +277,16 @@ void eigrp_update_receive(struct eigrp *eigrp, struct ip *iph,
                        eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_DOWN);
                        eigrp_topology_neighbor_down(nbr->ei->eigrp, nbr);
                        nbr->recv_sequence_number = ntohl(eigrph->sequence);
-                       zlog_info("Neighbor %s (%s) is down: peer restarted",
-                                 inet_ntoa(nbr->src),
+                       zlog_info("Neighbor %pI4 (%s) is down: peer restarted",
+                                 &nbr->src,
                                  ifindex2ifname(nbr->ei->ifp->ifindex,
                                                 eigrp->vrf_id));
                        eigrp_nbr_state_set(nbr, EIGRP_NEIGHBOR_PENDING);
-                       zlog_info("Neighbor %s (%s) is pending: new adjacency",
-                                 inet_ntoa(nbr->src),
-                                 ifindex2ifname(nbr->ei->ifp->ifindex,
-                                                eigrp->vrf_id));
+                       zlog_info(
+                               "Neighbor %pI4 (%s) is pending: new adjacency",
+                               &nbr->src,
+                               ifindex2ifname(nbr->ei->ifp->ifindex,
+                                              eigrp->vrf_id));
                        eigrp_update_send_init(nbr);
                }
        }
@@ -450,8 +449,9 @@ void eigrp_update_send_init(struct eigrp_neighbor *nbr)
        nbr->init_sequence_number = nbr->ei->eigrp->sequence_number;
        ep->sequence_number = nbr->ei->eigrp->sequence_number;
        if (IS_DEBUG_EIGRP_PACKET(0, RECV))
-               zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]",
-                          ep->length, ep->sequence_number, inet_ntoa(ep->dst));
+               zlog_debug(
+                       "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]",
+                       ep->length, ep->sequence_number, &ep->dst);
 
        /*Put packet to retransmission queue*/
        eigrp_fifo_push(nbr->retrans_queue, ep);
@@ -480,8 +480,9 @@ static void eigrp_update_place_on_nbr_queue(struct eigrp_neighbor *nbr,
        ep->sequence_number = seq_no;
 
        if (IS_DEBUG_EIGRP_PACKET(0, RECV))
-               zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]",
-                          ep->length, ep->sequence_number, inet_ntoa(ep->dst));
+               zlog_debug(
+                       "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]",
+                       ep->length, ep->sequence_number, &ep->dst);
 
        /*Put packet to retransmission queue*/
        eigrp_fifo_push(nbr->retrans_queue, ep);
@@ -815,8 +816,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
                if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_OUT,
                                              dest_addr)) {
                        /* do not send filtered route */
-                       zlog_info("Filtered prefix %s won't be sent out.",
-                                 inet_ntoa(dest_addr->u.prefix4));
+                       zlog_info("Filtered prefix %pI4 won't be sent out.",
+                                 &dest_addr->u.prefix4);
                } else {
                        /* sending route which wasn't filtered */
                        length += eigrp_add_internalTLV_to_stream(ep->s, pe);
@@ -830,8 +831,8 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
                if (eigrp_update_prefix_apply(eigrp, ei, EIGRP_FILTER_IN,
                                              dest_addr)) {
                        /* do not send filtered route */
-                       zlog_info("Filtered prefix %s will be removed.",
-                                 inet_ntoa(dest_addr->u.prefix4));
+                       zlog_info("Filtered prefix %pI4 will be removed.",
+                                 &dest_addr->u.prefix4);
 
                        /* prepare message for FSM */
                        struct eigrp_fsm_action_message fsm_msg;
@@ -880,8 +881,9 @@ static void eigrp_update_send_GR_part(struct eigrp_neighbor *nbr)
        ep->sequence_number = eigrp->sequence_number;
 
        if (IS_DEBUG_EIGRP_PACKET(0, RECV))
-               zlog_debug("Enqueuing Update Init Len [%u] Seq [%u] Dest [%s]",
-                          ep->length, ep->sequence_number, inet_ntoa(ep->dst));
+               zlog_debug(
+                       "Enqueuing Update Init Len [%u] Seq [%u] Dest [%pI4]",
+                       ep->length, ep->sequence_number, &ep->dst);
 
        /*Put packet to retransmission queue*/
        eigrp_fifo_push(nbr->retrans_queue, ep);
@@ -963,20 +965,20 @@ void eigrp_update_send_GR(struct eigrp_neighbor *nbr, enum GR_type gr_type,
        if (gr_type == EIGRP_GR_FILTER) {
                /* function was called after applying filtration */
                zlog_info(
-                       "Neighbor %s (%s) is resync: route configuration changed",
-                       inet_ntoa(nbr->src),
+                       "Neighbor %pI4 (%s) is resync: route configuration changed",
+                       &nbr->src,
                        ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id));
        } else if (gr_type == EIGRP_GR_MANUAL) {
                /* Graceful restart was called manually */
-               zlog_info("Neighbor %s (%s) is resync: manually cleared",
-                         inet_ntoa(nbr->src),
+               zlog_info("Neighbor %pI4 (%s) is resync: manually cleared",
+                         &nbr->src,
                          ifindex2ifname(ei->ifp->ifindex, eigrp->vrf_id));
 
                if (vty != NULL) {
                        vty_time_print(vty, 0);
                        vty_out(vty,
-                               "Neighbor %s (%s) is resync: manually cleared\n",
-                               inet_ntoa(nbr->src),
+                               "Neighbor %pI4 (%s) is resync: manually cleared\n",
+                               &nbr->src,
                                ifindex2ifname(ei->ifp->ifindex,
                                               eigrp->vrf_id));
                }
index 4426cf67e96b6ae1bdd01606bf8802ee123b069b..66dfbaa5385dc5dc98050d35bff73c4c11b6ebf7 100644 (file)
@@ -360,14 +360,14 @@ DEFPY (clear_ip_eigrp_neighbors,
                for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
                        if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
                                zlog_debug(
-                                       "Neighbor %s (%s) is down: manually cleared",
-                                       inet_ntoa(nbr->src),
+                                       "Neighbor %pI4 (%s) is down: manually cleared",
+                                       &nbr->src,
                                        ifindex2ifname(nbr->ei->ifp->ifindex,
                                                       eigrp->vrf_id));
                                vty_time_print(vty, 0);
                                vty_out(vty,
-                                       "Neighbor %s (%s) is down: manually cleared\n",
-                                       inet_ntoa(nbr->src),
+                                       "Neighbor %pI4 (%s) is down: manually cleared\n",
+                                       &nbr->src,
                                        ifindex2ifname(nbr->ei->ifp->ifindex,
                                                       eigrp->vrf_id));
 
@@ -420,14 +420,15 @@ DEFPY (clear_ip_eigrp_neighbors_int,
        /* iterate over all neighbors on eigrp interface */
        for (ALL_LIST_ELEMENTS(ei->nbrs, node2, nnode2, nbr)) {
                if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
-                       zlog_debug("Neighbor %s (%s) is down: manually cleared",
-                                  inet_ntoa(nbr->src),
-                                  ifindex2ifname(nbr->ei->ifp->ifindex,
-                                                 eigrp->vrf_id));
+                       zlog_debug(
+                               "Neighbor %pI4 (%s) is down: manually cleared",
+                               &nbr->src,
+                               ifindex2ifname(nbr->ei->ifp->ifindex,
+                                              eigrp->vrf_id));
                        vty_time_print(vty, 0);
                        vty_out(vty,
-                               "Neighbor %s (%s) is down: manually cleared\n",
-                               inet_ntoa(nbr->src),
+                               "Neighbor %pI4 (%s) is down: manually cleared\n",
+                               &nbr->src,
                                ifindex2ifname(nbr->ei->ifp->ifindex,
                                               eigrp->vrf_id));
 
index 3205f13922a85e6305c8d253be932c007bd0ac17..473cc75a2a4f9d634911540a067adad252930f79 100644 (file)
@@ -150,12 +150,9 @@ static int eigrp_interface_address_add(ZAPI_CALLBACK_ARGS)
        if (c == NULL)
                return 0;
 
-       if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) {
-               char buf[128];
-               prefix2str(c->address, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s address add %s", c->ifp->name,
-                          buf);
-       }
+       if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: interface %s address add %pFX", c->ifp->name,
+                          c->address);
 
        eigrp_if_update(c->ifp);
 
@@ -173,12 +170,9 @@ static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS)
        if (c == NULL)
                return 0;
 
-       if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE)) {
-               char buf[128];
-               prefix2str(c->address, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s address delete %s",
-                          c->ifp->name, buf);
-       }
+       if (IS_DEBUG_EIGRP(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: interface %s address delete %pFX",
+                          c->ifp->name, c->address);
 
        ifp = c->ifp;
        ei = ifp->info;
@@ -234,10 +228,9 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
        api.nexthop_num = count;
 
        if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) {
-               char buf[2][PREFIX_STRLEN];
-               zlog_debug("Zebra: Route add %s nexthop %s",
-                          prefix2str(p, buf[0], PREFIX_STRLEN),
-                          inet_ntop(AF_INET, 0, buf[1], PREFIX_STRLEN));
+               char buf[PREFIX_STRLEN];
+               zlog_debug("Zebra: Route add %pFX nexthop %s", p,
+                          inet_ntop(AF_INET, 0, buf, PREFIX_STRLEN));
        }
 
        zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
@@ -257,11 +250,8 @@ void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p)
        memcpy(&api.prefix, p, sizeof(*p));
        zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 
-       if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE)) {
-               char buf[PREFIX_STRLEN];
-               zlog_debug("Zebra: Route del %s",
-                          prefix2str(p, buf, PREFIX_STRLEN));
-       }
+       if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE))
+               zlog_debug("Zebra: Route del %pFX", p);
 
        return;
 }
index 820f015b5711e6889913840a5410680e1d3a321b..5002630796c9feec76b3761467f45fa5e135e00d 100644 (file)
@@ -110,10 +110,6 @@ void eigrp_router_id_update(struct eigrp *eigrp)
 
        eigrp->router_id = router_id;
        if (router_id_old.s_addr != router_id.s_addr) {
-               //      if (IS_DEBUG_EIGRP_EVENT)
-               //        zlog_debug("Router-ID[NEW:%s]: Update",
-               //        inet_ntoa(eigrp->router_id));
-
                /* update eigrp_interface's */
                FOR_ALL_INTERFACES (vrf, ifp)
                        eigrp_if_update(ifp);
index 1a081bbea669e4a8526b472b977af6d3c2e802cb..57e9e91c1510c1fa8eb44299ae3dbea9db22e346 100644 (file)
@@ -239,14 +239,11 @@ struct fabricd *fabricd_new(struct isis_area *area)
 
 void fabricd_finish(struct fabricd *f)
 {
-       if (f->initial_sync_timeout)
-               thread_cancel(f->initial_sync_timeout);
+       thread_cancel(&(f->initial_sync_timeout));
 
-       if (f->tier_calculation_timer)
-               thread_cancel(f->tier_calculation_timer);
+       thread_cancel(&(f->tier_calculation_timer));
 
-       if (f->tier_set_timer)
-               thread_cancel(f->tier_set_timer);
+       thread_cancel(&(f->tier_set_timer));
 
        isis_spftree_del(f->spftree);
        neighbor_lists_clear(f);
@@ -340,8 +337,7 @@ void fabricd_initial_sync_finish(struct isis_area *area)
                  f->initial_sync_circuit->interface->name);
        f->initial_sync_state = FABRICD_SYNC_COMPLETE;
        f->initial_sync_circuit = NULL;
-       thread_cancel(f->initial_sync_timeout);
-       f->initial_sync_timeout = NULL;
+       thread_cancel(&(f->initial_sync_timeout));
 }
 
 static void fabricd_bump_tier_calculation_timer(struct fabricd *f);
@@ -437,22 +433,15 @@ static int fabricd_tier_calculation_cb(struct thread *thread)
 static void fabricd_bump_tier_calculation_timer(struct fabricd *f)
 {
        /* Cancel timer if we already know our tier */
-       if (f->tier != ISIS_TIER_UNDEFINED
-           || f->tier_set_timer) {
-               if (f->tier_calculation_timer) {
-                       thread_cancel(f->tier_calculation_timer);
-                       f->tier_calculation_timer = NULL;
-               }
+       if (f->tier != ISIS_TIER_UNDEFINED || f->tier_set_timer) {
+               thread_cancel(&(f->tier_calculation_timer));
                return;
        }
 
        /* If we need to calculate the tier, wait some
         * time for the topology to settle before running
         * the calculation */
-       if (f->tier_calculation_timer) {
-               thread_cancel(f->tier_calculation_timer);
-               f->tier_calculation_timer = NULL;
-       }
+       thread_cancel(&(f->tier_calculation_timer));
 
        thread_add_timer(master, fabricd_tier_calculation_cb, f,
                         2 * f->area->lsp_gen_interval[ISIS_LEVEL2 - 1],
@@ -737,7 +726,7 @@ void fabricd_trigger_csnp(struct isis_area *area, bool circuit_scoped)
                if (!circuit->t_send_csnp[1])
                        continue;
 
-               thread_cancel(circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
+               thread_cancel(&(circuit->t_send_csnp[ISIS_LEVEL2 - 1]));
                thread_add_timer_msec(master, send_l2_csnp, circuit,
                                      isis_jitter(f->csnp_delay, CSNP_JITTER),
                                      &circuit->t_send_csnp[ISIS_LEVEL2 - 1]);
index 5bfbb2cf7e66fc5ca9a4564802ae3c7edae92054..71d4758163b3755adfe05838b0d88ec9e5070955 100644 (file)
@@ -147,7 +147,7 @@ void isis_delete_adj(void *arg)
        if (!adj)
                return;
 
-       THREAD_TIMER_OFF(adj->t_expire);
+       thread_cancel(&adj->t_expire);
        if (adj->adj_state != ISIS_ADJ_DOWN)
                adj->adj_state = ISIS_ADJ_DOWN;
 
@@ -393,7 +393,7 @@ void isis_adj_print(struct isis_adjacency *adj)
        if (adj->ipv4_address_count) {
                zlog_debug("IPv4 Address(es):");
                for (unsigned int i = 0; i < adj->ipv4_address_count; i++)
-                       zlog_debug("%s", inet_ntoa(adj->ipv4_addresses[i]));
+                       zlog_debug("%pI4", &adj->ipv4_addresses[i]);
        }
 
        if (adj->ipv6_address_count) {
@@ -562,8 +562,8 @@ void isis_adj_print_vty(struct isis_adjacency *adj, struct vty *vty,
                        vty_out(vty, "    IPv4 Address(es):\n");
                        for (unsigned int i = 0; i < adj->ipv4_address_count;
                             i++)
-                               vty_out(vty, "      %s\n",
-                                       inet_ntoa(adj->ipv4_addresses[i]));
+                               vty_out(vty, "      %pI4\n",
+                                       &adj->ipv4_addresses[i]);
                }
                if (adj->ipv6_address_count) {
                        vty_out(vty, "    IPv6 Address(es):\n");
index d6988095e536c5f032683b59aa819e08de209b3b..e3c70264f8089a1e6b544291cfe7fb00cff0a46e 100644 (file)
@@ -71,13 +71,14 @@ DEFINE_HOOK(isis_if_new_hook, (struct interface *ifp), (ifp))
 int isis_if_new_hook(struct interface *);
 int isis_if_delete_hook(struct interface *);
 
-struct isis_circuit *isis_circuit_new(void)
+struct isis_circuit *isis_circuit_new(struct isis *isis)
 {
        struct isis_circuit *circuit;
        int i;
 
        circuit = XCALLOC(MTYPE_ISIS_CIRCUIT, sizeof(struct isis_circuit));
 
+       circuit->isis = isis;
        /*
         * Default values
         */
@@ -252,9 +253,6 @@ void isis_circuit_add_addr(struct isis_circuit *circuit,
 {
        struct listnode *node;
        struct prefix_ipv4 *ipv4;
-#if defined(EXTREME_DEBUG)
-       char buf[PREFIX2STR_BUFFER];
-#endif
        struct prefix_ipv6 *ipv6;
 
        if (connected->address->family == AF_INET) {
@@ -286,9 +284,8 @@ void isis_circuit_add_addr(struct isis_circuit *circuit,
                                                0);
 
 #ifdef EXTREME_DEBUG
-               prefix2str(connected->address, buf, sizeof(buf));
-               zlog_debug("Added IP address %s to circuit %s", buf,
-                          circuit->interface->name);
+               zlog_debug("Added IP address %pFX to circuit %s",
+                          connected->address, circuit->interface->name);
 #endif /* EXTREME_DEBUG */
        }
        if (connected->address->family == AF_INET6) {
@@ -317,9 +314,8 @@ void isis_circuit_add_addr(struct isis_circuit *circuit,
                                                0);
 
 #ifdef EXTREME_DEBUG
-               prefix2str(connected->address, buf, sizeof(buf));
-               zlog_debug("Added IPv6 address %s to circuit %s", buf,
-                          circuit->interface->name);
+               zlog_debug("Added IPv6 address %pFX to circuit %s",
+                          connected->address, circuit->interface->name);
 #endif /* EXTREME_DEBUG */
        }
        return;
@@ -330,7 +326,6 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
 {
        struct prefix_ipv4 *ipv4, *ip = NULL;
        struct listnode *node;
-       char buf[PREFIX2STR_BUFFER];
        struct prefix_ipv6 *ipv6, *ip6 = NULL;
        int found = 0;
 
@@ -351,16 +346,14 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
                                lsp_regenerate_schedule(circuit->area,
                                                        circuit->is_type, 0);
                } else {
-                       prefix2str(connected->address, buf, sizeof(buf));
                        zlog_warn(
-                               "Nonexistent ip address %s removal attempt from circuit %s",
-                               buf, circuit->interface->name);
+                               "Nonexistent ip address %pFX removal attempt from circuit %s",
+                               connected->address, circuit->interface->name);
                        zlog_warn("Current ip addresses on %s:",
                                  circuit->interface->name);
                        for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
                                                  ip)) {
-                               prefix2str(ip, buf, sizeof(buf));
-                               zlog_warn("  %s", buf);
+                               zlog_warn("  %pFX", ip);
                        }
                        zlog_warn("End of addresses");
                }
@@ -399,25 +392,18 @@ void isis_circuit_del_addr(struct isis_circuit *circuit,
                }
 
                if (!found) {
-                       prefix2str(connected->address, buf, sizeof(buf));
                        zlog_warn(
-                               "Nonexistent ip address %s removal attempt from circuit %s",
-                               buf, circuit->interface->name);
+                               "Nonexistent ip address %pFX removal attempt from circuit %s",
+                               connected->address, circuit->interface->name);
                        zlog_warn("Current ip addresses on %s:",
                                  circuit->interface->name);
                        for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
-                                                 ip6)) {
-                               prefix2str((struct prefix *)ip6, (char *)buf,
-                                          sizeof(buf));
-                               zlog_warn("  %s", buf);
-                       }
+                                                 ip6))
+                               zlog_warn("  %pFX", (struct prefix *)ip6);
                        zlog_warn(" -----");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
-                                                 ip6)) {
-                               prefix2str((struct prefix *)ip6, (char *)buf,
-                                          sizeof(buf));
-                               zlog_warn("  %s", buf);
-                       }
+                                                 ip6))
+                               zlog_warn("  %pFX", (struct prefix *)ip6);
                        zlog_warn("End of addresses");
                } else if (circuit->area)
                        lsp_regenerate_schedule(circuit->area, circuit->is_type,
@@ -612,8 +598,20 @@ int isis_circuit_up(struct isis_circuit *circuit)
        if (circuit->state == C_STATE_UP)
                return ISIS_OK;
 
-       if (circuit->is_passive)
+       if (circuit->is_passive) {
+               /* make sure the union fields are initialized, else we
+                * could end with garbage values from a previous circuit
+                * type, which would then cause a segfault when building
+                * LSPs or computing the SPF tree
+                */
+               if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
+                       circuit->u.bc.adjdb[0] = list_new();
+                       circuit->u.bc.adjdb[1] = list_new();
+               } else if (circuit->circ_type == CIRCUIT_T_P2P) {
+                       circuit->u.p2p.neighbor = NULL;
+               }
                return ISIS_OK;
+       }
 
        if (circuit->area->lsp_mtu > isis_circuit_pdu_size(circuit)) {
                flog_err(
@@ -626,8 +624,8 @@ int isis_circuit_up(struct isis_circuit *circuit)
        }
 
        if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
-               circuit->circuit_id = isis_circuit_id_gen(circuit->area->isis,
-                                                         circuit->interface);
+               circuit->circuit_id =
+                       isis_circuit_id_gen(circuit->isis, circuit->interface);
                if (!circuit->circuit_id) {
                        flog_err(
                                EC_ISIS_CONFIG,
@@ -802,30 +800,30 @@ void isis_circuit_down(struct isis_circuit *circuit)
                memset(circuit->u.bc.l2_desig_is, 0, ISIS_SYS_ID_LEN + 1);
                memset(circuit->u.bc.snpa, 0, ETH_ALEN);
 
-               THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[0]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[1]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[0]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[1]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[0]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[1]);
+               thread_cancel(&circuit->u.bc.t_send_lan_hello[0]);
+               thread_cancel(&circuit->u.bc.t_send_lan_hello[1]);
+               thread_cancel(&circuit->u.bc.t_run_dr[0]);
+               thread_cancel(&circuit->u.bc.t_run_dr[1]);
+               thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[0]);
+               thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[1]);
                circuit->lsp_regenerate_pending[0] = 0;
                circuit->lsp_regenerate_pending[1] = 0;
 
-               _ISIS_CLEAR_FLAG(circuit->area->isis->circuit_ids_used,
+               _ISIS_CLEAR_FLAG(circuit->isis->circuit_ids_used,
                                 circuit->circuit_id);
                circuit->circuit_id = 0;
        } else if (circuit->circ_type == CIRCUIT_T_P2P) {
                isis_delete_adj(circuit->u.p2p.neighbor);
                circuit->u.p2p.neighbor = NULL;
-               THREAD_TIMER_OFF(circuit->u.p2p.t_send_p2p_hello);
+               thread_cancel(&circuit->u.p2p.t_send_p2p_hello);
        }
 
        /* Cancel all active threads */
-       THREAD_TIMER_OFF(circuit->t_send_csnp[0]);
-       THREAD_TIMER_OFF(circuit->t_send_csnp[1]);
-       THREAD_TIMER_OFF(circuit->t_send_psnp[0]);
-       THREAD_TIMER_OFF(circuit->t_send_psnp[1]);
-       THREAD_OFF(circuit->t_read);
+       thread_cancel(&circuit->t_send_csnp[0]);
+       thread_cancel(&circuit->t_send_csnp[1]);
+       thread_cancel(&circuit->t_send_psnp[0]);
+       thread_cancel(&circuit->t_send_psnp[1]);
+       thread_cancel(&circuit->t_read);
 
        if (circuit->tx_queue) {
                isis_tx_queue_free(circuit->tx_queue);
@@ -894,7 +892,6 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
        if (detail == ISIS_UI_LEVEL_DETAIL) {
                struct listnode *node;
                struct prefix *ip_addr;
-               char buf[BUFSIZ];
 
                vty_out(vty, "  Interface: %s", circuit->interface->name);
                vty_out(vty, ", State: %s",
@@ -979,27 +976,21 @@ void isis_circuit_print_vty(struct isis_circuit *circuit, struct vty *vty,
                if (circuit->ip_addrs && listcount(circuit->ip_addrs) > 0) {
                        vty_out(vty, "    IP Prefix(es):\n");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ip_addrs, node,
-                                                 ip_addr)) {
-                               prefix2str(ip_addr, buf, sizeof(buf));
-                               vty_out(vty, "      %s\n", buf);
-                       }
+                                                 ip_addr))
+                               vty_out(vty, "      %pFX\n", ip_addr);
                }
                if (circuit->ipv6_link && listcount(circuit->ipv6_link) > 0) {
                        vty_out(vty, "    IPv6 Link-Locals:\n");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_link, node,
-                                                 ip_addr)) {
-                               prefix2str(ip_addr, (char *)buf, BUFSIZ);
-                               vty_out(vty, "      %s\n", buf);
-                       }
+                                                 ip_addr))
+                               vty_out(vty, "      %pFX\n", ip_addr);
                }
                if (circuit->ipv6_non_link
                    && listcount(circuit->ipv6_non_link) > 0) {
                        vty_out(vty, "    IPv6 Prefixes:\n");
                        for (ALL_LIST_ELEMENTS_RO(circuit->ipv6_non_link, node,
-                                                 ip_addr)) {
-                               prefix2str(ip_addr, (char *)buf, BUFSIZ);
-                               vty_out(vty, "      %s\n", buf);
-                       }
+                                                 ip_addr))
+                               vty_out(vty, "      %pFX\n", ip_addr);
                }
 
                vty_out(vty, "\n");
index 5766d1962f277eba5000601c4f2581647ff4b182..b4b03bf6b902271c997d85adc77a78751aa4a797 100644 (file)
@@ -79,6 +79,7 @@ struct isis_circuit_arg {
 struct isis_circuit {
        int state;
        uint8_t circuit_id;       /* l1/l2 bcast CircuitID */
+       struct isis *isis;
        struct isis_area *area;      /* back pointer to the area */
        struct interface *interface; /* interface info from z */
        int fd;                      /* IS-IS l1/2 socket */
@@ -140,6 +141,8 @@ struct isis_circuit {
        bool disable_threeway_adj;
        struct bfd_info *bfd_info;
        struct ldp_sync_info *ldp_sync_info;
+       bool tilfa_protection[ISIS_LEVELS];
+       bool tilfa_node_protection[ISIS_LEVELS];
        /*
         * Counters as in 10589--11.2.5.9
         */
@@ -163,7 +166,7 @@ struct isis_circuit {
 DECLARE_QOBJ_TYPE(isis_circuit)
 
 void isis_circuit_init(void);
-struct isis_circuit *isis_circuit_new(void);
+struct isis_circuit *isis_circuit_new(struct isis *isis);
 void isis_circuit_del(struct isis_circuit *circuit);
 struct isis_circuit *circuit_lookup_by_ifp(struct interface *ifp,
                                           struct list *list);
index d303cbe98d03d94f18473194e6e6a42c794dd313..203fa8eb8d6465e66d0e6b729c336f03a5e563d9 100644 (file)
@@ -1628,17 +1628,18 @@ DEFPY_YANG (isis_sr_prefix_sid,
        "segment-routing prefix\
           <A.B.C.D/M|X:X::X:X/M>$prefix\
          <absolute$sid_type (16-1048575)$sid_value|index$sid_type (0-65535)$sid_value>\
-         [<no-php-flag|explicit-null>$lh_behavior]",
+         [<no-php-flag|explicit-null>$lh_behavior] [n-flag-clear$n_flag_clear]",
        SR_STR
        "Prefix SID\n"
        "IPv4 Prefix\n"
        "IPv6 Prefix\n"
-       "Specify the absolute value of Prefix Segement ID\n"
+       "Specify the absolute value of Prefix Segment ID\n"
        "The Prefix Segment ID value\n"
-       "Specify the index of Prefix Segement ID\n"
+       "Specify the index of Prefix Segment ID\n"
        "The Prefix Segment ID index\n"
        "Don't request Penultimate Hop Popping (PHP)\n"
-       "Upstream neighbor must replace prefix-sid with explicit null label\n")
+       "Upstream neighbor must replace prefix-sid with explicit null label\n"
+       "Not a node SID\n")
 {
        nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
        nb_cli_enqueue_change(vty, "./sid-value-type", NB_OP_MODIFY, sid_type);
@@ -1656,6 +1657,8 @@ DEFPY_YANG (isis_sr_prefix_sid,
        } else
                nb_cli_enqueue_change(vty, "./last-hop-behavior", NB_OP_MODIFY,
                                      NULL);
+       nb_cli_enqueue_change(vty, "./n-flag-clear", NB_OP_MODIFY,
+                             n_flag_clear ? "true" : "false");
 
        return nb_cli_apply_changes(
                vty, "./segment-routing/prefix-sid-map/prefix-sid[prefix='%s']",
@@ -1665,18 +1668,20 @@ DEFPY_YANG (isis_sr_prefix_sid,
 DEFPY_YANG (no_isis_sr_prefix_sid,
        no_isis_sr_prefix_sid_cmd,
        "no segment-routing prefix <A.B.C.D/M|X:X::X:X/M>$prefix\
-         [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]",
+         [<absolute$sid_type (16-1048575)|index (0-65535)> [<no-php-flag|explicit-null>]]\
+        [n-flag-clear]",
        NO_STR
        SR_STR
        "Prefix SID\n"
        "IPv4 Prefix\n"
        "IPv6 Prefix\n"
-       "Specify the absolute value of Prefix Segement ID\n"
+       "Specify the absolute value of Prefix Segment ID\n"
        "The Prefix Segment ID value\n"
-       "Specify the index of Prefix Segement ID\n"
+       "Specify the index of Prefix Segment ID\n"
        "The Prefix Segment ID index\n"
        "Don't request Penultimate Hop Popping (PHP)\n"
-       "Upstream neighbor must replace prefix-sid with explicit null label\n")
+       "Upstream neighbor must replace prefix-sid with explicit null label\n"
+       "Not a node SID\n")
 {
        nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
 
@@ -1692,11 +1697,13 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode,
        const char *lh_behavior;
        const char *sid_value_type;
        const char *sid_value;
+       bool n_flag_clear;
 
        prefix = yang_dnode_get_string(dnode, "./prefix");
        lh_behavior = yang_dnode_get_string(dnode, "./last-hop-behavior");
        sid_value_type = yang_dnode_get_string(dnode, "./sid-value-type");
        sid_value = yang_dnode_get_string(dnode, "./sid-value");
+       n_flag_clear = yang_dnode_get_bool(dnode, "./n-flag-clear");
 
        vty_out(vty, " segment-routing prefix %s", prefix);
        if (strmatch(sid_value_type, "absolute"))
@@ -1708,6 +1715,8 @@ void cli_show_isis_prefix_sid(struct vty *vty, struct lyd_node *dnode,
                vty_out(vty, " no-php-flag");
        else if (strmatch(lh_behavior, "explicit-null"))
                vty_out(vty, " explicit-null");
+       if (n_flag_clear)
+               vty_out(vty, " n-flag-clear");
        vty_out(vty, "\n");
 }
 
@@ -2367,6 +2376,102 @@ void cli_show_ip_isis_priority(struct vty *vty, struct lyd_node *dnode,
        }
 }
 
+/*
+ * XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/ti-lfa/enable
+ */
+DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
+      "[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection]",
+      NO_STR
+      "IS-IS routing protocol\n"
+      "Interface IP Fast-reroute configuration\n"
+      "Enable TI-LFA computation\n"
+      "Enable TI-LFA computation for Level 1 only\n"
+      "Enable TI-LFA computation for Level 2 only\n"
+      "Protect against node failures\n")
+{
+       if (!level || strmatch(level, "level-1")) {
+               if (no) {
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable",
+                               NB_OP_MODIFY, "false");
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
+                               NB_OP_MODIFY, "false");
+               } else {
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable",
+                               NB_OP_MODIFY, "true");
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
+                               NB_OP_MODIFY,
+                               node_protection ? "true" : "false");
+               }
+       }
+       if (!level || strmatch(level, "level-2")) {
+               if (no) {
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable",
+                               NB_OP_MODIFY, "false");
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
+                               NB_OP_MODIFY, "false");
+               } else {
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable",
+                               NB_OP_MODIFY, "true");
+                       nb_cli_enqueue_change(
+                               vty,
+                               "./frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
+                               NB_OP_MODIFY,
+                               node_protection ? "true" : "false");
+               }
+       }
+
+       return nb_cli_apply_changes(vty, NULL);
+}
+
+void cli_show_ip_isis_ti_lfa(struct vty *vty, struct lyd_node *dnode,
+                            bool show_defaults)
+{
+       bool l1_enabled, l2_enabled;
+       bool l1_node_protection, l2_node_protection;
+
+       l1_enabled = yang_dnode_get_bool(dnode, "./level-1/ti-lfa/enable");
+       l2_enabled = yang_dnode_get_bool(dnode, "./level-2/ti-lfa/enable");
+       l1_node_protection =
+               yang_dnode_get_bool(dnode, "./level-1/ti-lfa/node-protection");
+       l2_node_protection =
+               yang_dnode_get_bool(dnode, "./level-2/ti-lfa/node-protection");
+
+       if (l1_enabled == l2_enabled
+           && l1_node_protection == l2_node_protection) {
+               vty_out(vty, " isis fast-reroute ti-lfa");
+               if (l1_node_protection)
+                       vty_out(vty, " node-protection");
+               vty_out(vty, "\n");
+       } else {
+               if (l1_enabled) {
+                       vty_out(vty, " isis fast-reroute ti-lfa level-1");
+                       if (l1_node_protection)
+                               vty_out(vty, " node-protection");
+                       vty_out(vty, "\n");
+               }
+               if (l2_enabled) {
+                       vty_out(vty, " isis fast-reroute ti-lfa level-2");
+                       if (l2_node_protection)
+                               vty_out(vty, " node-protection");
+                       vty_out(vty, "\n");
+               }
+       }
+}
+
 /*
  * XPath: /frr-isisd:isis/instance/log-adjacency-changes
  */
@@ -2661,6 +2766,8 @@ void isis_cli_init(void)
        install_element(INTERFACE_NODE, &isis_priority_cmd);
        install_element(INTERFACE_NODE, &no_isis_priority_cmd);
 
+       install_element(INTERFACE_NODE, &isis_ti_lfa_cmd);
+
        install_element(ISIS_NODE, &log_adj_changes_cmd);
 
        install_element(ISIS_NODE, &isis_mpls_ldp_sync_cmd);
index 929b4c26e8dd9caf8e4730b6eaf8c4ac4b7b8814..736d8d63f93c34efc0b58662740fb91d245bcffe 100644 (file)
@@ -65,6 +65,7 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
 {
        int old_state;
        struct isis *isis = NULL;
+       struct isis_area *area = NULL;
 
        old_state = circuit ? circuit->state : C_STATE_NA;
        if (IS_DEBUG_EVENTS)
@@ -77,21 +78,22 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
                assert(circuit == NULL);
                switch (event) {
                case ISIS_ENABLE:
-                       circuit = isis_circuit_new();
-                       isis_circuit_configure(circuit,
-                                              (struct isis_area *)arg);
+                       area = arg;
+
+                       circuit = isis_circuit_new(area->isis);
+                       isis_circuit_configure(circuit, area);
                        circuit->state = C_STATE_CONF;
                        break;
                case IF_UP_FROM_Z:
-                       circuit = isis_circuit_new();
-                       isis_circuit_if_add(circuit, (struct interface *)arg);
-                       isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
+                       isis = isis_lookup_by_vrfid(((struct interface *)arg)->vrf_id);
                        if (isis == NULL) {
                                zlog_warn(
                                        " %s : ISIS routing instance not found",
                                        __func__);
                                break;
                        }
+                       circuit = isis_circuit_new(isis);
+                       isis_circuit_if_add(circuit, (struct interface *)arg);
                        listnode_add(isis->init_circ_list, circuit);
                        circuit->state = C_STATE_INIT;
                        break;
@@ -117,7 +119,7 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
                        circuit->state = C_STATE_UP;
                        isis_event_circuit_state_change(circuit, circuit->area,
                                                        1);
-                       listnode_delete(circuit->area->isis->init_circ_list,
+                       listnode_delete(circuit->isis->init_circ_list,
                                        circuit);
                        break;
                case IF_UP_FROM_Z:
@@ -129,15 +131,8 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
                        break;
                case IF_DOWN_FROM_Z:
                        isis_circuit_if_del(circuit, (struct interface *)arg);
-                       isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
-                       if (isis == NULL) {
-                               zlog_warn(
-                                       "%s : ISIS routing instance not found",
-                                       __func__);
-                               break;
-                       }
-
-                       listnode_delete(isis->init_circ_list, circuit);
+                       listnode_delete(circuit->isis->init_circ_list,
+                                       circuit);
                        isis_circuit_del(circuit);
                        circuit = NULL;
                        break;
@@ -152,6 +147,7 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
                case IF_UP_FROM_Z:
                        isis_circuit_if_add(circuit, (struct interface *)arg);
                        if (isis_circuit_up(circuit) != ISIS_OK) {
+                               isis_circuit_if_del(circuit, (struct interface *)arg);
                                flog_err(
                                        EC_ISIS_CONFIG,
                                        "Could not bring up %s because of invalid config.",
@@ -183,21 +179,13 @@ isis_csm_state_change(int event, struct isis_circuit *circuit, void *arg)
                        zlog_warn("circuit already connected");
                        break;
                case ISIS_DISABLE:
+                       isis = circuit->isis;
                        isis_circuit_down(circuit);
                        isis_circuit_deconfigure(circuit,
                                                 (struct isis_area *)arg);
                        circuit->state = C_STATE_INIT;
                        isis_event_circuit_state_change(
                                circuit, (struct isis_area *)arg, 0);
-
-                       isis = isis_lookup_by_vrfid(circuit->interface->vrf_id);
-                       if (isis == NULL) {
-                               zlog_warn(
-                                       "%s : ISIS routing instance not found",
-                                       __func__);
-                               break;
-                       }
-
                        listnode_add(isis->init_circ_list, circuit);
                        break;
                case IF_DOWN_FROM_Z:
index 318fb9fab8b43a2a6ecc2e203f7fc04c43c1ab64..d03f857a0c9d7e0193e0fdd4dc0d87f84d432553 100644 (file)
@@ -221,11 +221,11 @@ int isis_dr_resign(struct isis_circuit *circuit, int level)
 
        circuit->u.bc.is_dr[level - 1] = 0;
        circuit->u.bc.run_dr_elect[level - 1] = 0;
-       THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[level - 1]);
-       THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+       thread_cancel(&circuit->u.bc.t_run_dr[level - 1]);
+       thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
        circuit->lsp_regenerate_pending[level - 1] = 0;
 
-       memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
+       memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN);
        LSP_PSEUDO_ID(id) = circuit->circuit_id;
        LSP_FRAGMENT(id) = 0;
        lsp_purge_pseudo(id, circuit, level);
@@ -246,7 +246,7 @@ int isis_dr_resign(struct isis_circuit *circuit, int level)
                                 &circuit->t_send_psnp[1]);
        }
 
-       THREAD_TIMER_OFF(circuit->t_send_csnp[level - 1]);
+       thread_cancel(&circuit->t_send_csnp[level - 1]);
 
        thread_add_timer(master, isis_run_dr,
                         &circuit->level_arg[level - 1],
@@ -278,7 +278,7 @@ int isis_dr_commence(struct isis_circuit *circuit, int level)
                        /* there was a dr elected, purge its LSPs from the db */
                        lsp_purge_pseudo(old_dr, circuit, level);
                }
-               memcpy(circuit->u.bc.l1_desig_is, circuit->area->isis->sysid,
+               memcpy(circuit->u.bc.l1_desig_is, circuit->isis->sysid,
                       ISIS_SYS_ID_LEN);
                *(circuit->u.bc.l1_desig_is + ISIS_SYS_ID_LEN) =
                        circuit->circuit_id;
@@ -300,7 +300,7 @@ int isis_dr_commence(struct isis_circuit *circuit, int level)
                        /* there was a dr elected, purge its LSPs from the db */
                        lsp_purge_pseudo(old_dr, circuit, level);
                }
-               memcpy(circuit->u.bc.l2_desig_is, circuit->area->isis->sysid,
+               memcpy(circuit->u.bc.l2_desig_is, circuit->isis->sysid,
                       ISIS_SYS_ID_LEN);
                *(circuit->u.bc.l2_desig_is + ISIS_SYS_ID_LEN) =
                        circuit->circuit_id;
index 717a5fd0468c99508a366c81adeefea34adc8ff8..0b987fc5cf50e2886c40ed94b371869f41ebbeee 100644 (file)
 #include "isisd/isis_spf.h"
 #include "isisd/isis_errors.h"
 
-/* debug isis-spf spf-events
- 4w4d: ISIS-Spf (tlt): L2 SPF needed, new adjacency, from 0x609229F4
- 4w4d: ISIS-Spf (tlt): L2, 0000.0000.0042.01-00 TLV contents changed, code 0x2
- 4w4d: ISIS-Spf (tlt): L2, new LSP 0 DEAD.BEEF.0043.00-00
- 4w5d: ISIS-Spf (tlt): L1 SPF needed, periodic SPF, from 0x6091C844
- 4w5d: ISIS-Spf (tlt): L2 SPF needed, periodic SPF, from 0x6091C844
-*/
-
 void isis_event_circuit_state_change(struct isis_circuit *circuit,
                                     struct isis_area *area, int up)
 {
@@ -117,13 +109,13 @@ static void circuit_resign_level(struct isis_circuit *circuit, int level)
                        circuit->area->area_tag, circuit->circuit_id,
                        circuit->interface->name, level);
 
-       THREAD_TIMER_OFF(circuit->t_send_csnp[idx]);
-       THREAD_TIMER_OFF(circuit->t_send_psnp[idx]);
+       thread_cancel(&circuit->t_send_csnp[idx]);
+       thread_cancel(&circuit->t_send_psnp[idx]);
 
        if (circuit->circ_type == CIRCUIT_T_BROADCAST) {
-               THREAD_TIMER_OFF(circuit->u.bc.t_send_lan_hello[idx]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_run_dr[idx]);
-               THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[idx]);
+               thread_cancel(&circuit->u.bc.t_send_lan_hello[idx]);
+               thread_cancel(&circuit->u.bc.t_run_dr[idx]);
+               thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[idx]);
                circuit->lsp_regenerate_pending[idx] = 0;
                circuit->u.bc.run_dr_elect[idx] = 0;
                circuit->u.bc.is_dr[idx] = 0;
index c15b59a8cf51b08329d2631b388656d17d52af30..988af64c488d779c276b0486a99f17a545215b00 100644 (file)
@@ -135,8 +135,8 @@ int isis_ldp_sync_announce_update(struct ldp_igp_sync_announce announce)
                }
        }
 
-       THREAD_TIMER_OFF(isis->ldp_sync_cmd.t_hello);
-       isis->ldp_sync_cmd.t_hello = NULL;
+       THREAD_OFF(isis->ldp_sync_cmd.t_hello);
+
        isis->ldp_sync_cmd.sequence = 0;
        isis_ldp_sync_hello_timer_add();
 
@@ -186,7 +186,7 @@ int isis_ldp_sync_hello_update(struct ldp_igp_sync_hello hello)
                        }
                }
        } else {
-               THREAD_TIMER_OFF(isis->ldp_sync_cmd.t_hello);
+               THREAD_OFF(isis->ldp_sync_cmd.t_hello);
                isis_ldp_sync_hello_timer_add();
        }
        isis->ldp_sync_cmd.sequence = hello.sequence;
@@ -280,8 +280,9 @@ void isis_ldp_sync_if_complete(struct isis_circuit *circuit)
        if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
                if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP)
                        ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP;
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-               ldp_sync_info->t_holddown = NULL;
+
+               THREAD_OFF(ldp_sync_info->t_holddown);
+
                isis_ldp_sync_set_if_metric(circuit, true);
        }
 }
@@ -300,10 +301,7 @@ void isis_ldp_sync_ldp_fail(struct isis_circuit *circuit)
        if (ldp_sync_info &&
            ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED &&
            ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) {
-               if (ldp_sync_info->t_holddown != NULL) {
-                       THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-                       ldp_sync_info->t_holddown = NULL;
-               }
+               THREAD_OFF(ldp_sync_info->t_holddown);
                ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
                isis_ldp_sync_set_if_metric(circuit, true);
        }
@@ -326,8 +324,7 @@ void isis_ldp_sync_if_remove(struct isis_circuit *circuit, bool remove)
        ils_debug("ldp_sync: remove if %s", circuit->interface
                  ? circuit->interface->name : "");
 
-       if (ldp_sync_info->t_holddown)
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+       THREAD_OFF(ldp_sync_info->t_holddown);
        ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
        isis_ldp_sync_set_if_metric(circuit, true);
        if (remove) {
@@ -666,8 +663,7 @@ void isis_ldp_sync_gbl_exit(bool remove)
                UNSET_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE);
                UNSET_FLAG(isis->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN);
                isis->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
-               THREAD_TIMER_OFF(isis->ldp_sync_cmd.t_hello);
-               isis->ldp_sync_cmd.t_hello = NULL;
+               THREAD_OFF(isis->ldp_sync_cmd.t_hello);
 
                /* remove LDP-SYNC on all ISIS interfaces */
                FOR_ALL_INTERFACES (vrf, ifp) {
diff --git a/isisd/isis_lfa.c b/isisd/isis_lfa.c
new file mode 100644 (file)
index 0000000..f22e4a7
--- /dev/null
@@ -0,0 +1,1112 @@
+/*
+ * Copyright (C) 2020  NetDEF, Inc.
+ *                     Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "linklist.h"
+#include "log.h"
+#include "memory.h"
+#include "vrf.h"
+#include "table.h"
+#include "srcdest_table.h"
+
+#include "isis_common.h"
+#include "isisd.h"
+#include "isis_misc.h"
+#include "isis_adjacency.h"
+#include "isis_circuit.h"
+#include "isis_lsp.h"
+#include "isis_spf.h"
+#include "isis_route.h"
+#include "isis_mt.h"
+#include "isis_tlvs.h"
+#include "isis_spf_private.h"
+#include "isisd/isis_errors.h"
+
+DEFINE_MTYPE_STATIC(ISISD, ISIS_SPF_NODE, "ISIS SPF Node");
+
+static inline int isis_spf_node_compare(const struct isis_spf_node *a,
+                                       const struct isis_spf_node *b)
+{
+       return memcmp(a->sysid, b->sysid, sizeof(a->sysid));
+}
+RB_GENERATE(isis_spf_nodes, isis_spf_node, entry, isis_spf_node_compare)
+
+/**
+ * Initialize list of SPF nodes.
+ *
+ * @param nodes                List of SPF nodes
+ */
+void isis_spf_node_list_init(struct isis_spf_nodes *nodes)
+{
+       RB_INIT(isis_spf_nodes, nodes);
+}
+
+/**
+ * Clear list of SPF nodes, releasing all allocated memory.
+ *
+ * @param nodes                List of SPF nodes
+ */
+void isis_spf_node_list_clear(struct isis_spf_nodes *nodes)
+{
+       while (!RB_EMPTY(isis_spf_nodes, nodes)) {
+               struct isis_spf_node *node = RB_ROOT(isis_spf_nodes, nodes);
+
+               if (node->adjacencies)
+                       list_delete(&node->adjacencies);
+               if (node->lfa.spftree)
+                       isis_spftree_del(node->lfa.spftree);
+               if (node->lfa.spftree_reverse)
+                       isis_spftree_del(node->lfa.spftree_reverse);
+               isis_spf_node_list_clear(&node->lfa.p_space);
+               RB_REMOVE(isis_spf_nodes, nodes, node);
+               XFREE(MTYPE_ISIS_SPF_NODE, node);
+       }
+}
+
+/**
+ * Add new node to list of SPF nodes.
+ *
+ * @param nodes                List of SPF nodes
+ * @param sysid                Node System ID
+ *
+ * @return             Pointer to new IS-IS SPF node structure.
+ */
+struct isis_spf_node *isis_spf_node_new(struct isis_spf_nodes *nodes,
+                                       const uint8_t *sysid)
+{
+       struct isis_spf_node *node;
+
+       node = XCALLOC(MTYPE_ISIS_SPF_NODE, sizeof(*node));
+       memcpy(node->sysid, sysid, sizeof(node->sysid));
+       node->adjacencies = list_new();
+       isis_spf_node_list_init(&node->lfa.p_space);
+       RB_INSERT(isis_spf_nodes, nodes, node);
+
+       return node;
+}
+
+/**
+ * Lookup SPF node by its System ID on the given list.
+ *
+ * @param nodes                List of SPF nodes
+ * @param sysid                Node System ID
+ *
+ * @return             Pointer to SPF node if found, NULL otherwise
+ */
+struct isis_spf_node *isis_spf_node_find(const struct isis_spf_nodes *nodes,
+                                        const uint8_t *sysid)
+{
+       struct isis_spf_node node = {};
+
+       memcpy(node.sysid, sysid, sizeof(node.sysid));
+       return RB_FIND(isis_spf_nodes, nodes, &node);
+}
+
+/**
+ * Check if a given IS-IS adjacency needs to be excised when computing the SPF
+ * post-convergence tree.
+ *
+ * @param spftree      IS-IS SPF tree
+ * @param id           Adjacency System ID (or LAN ID of the designated router
+ *                     for broadcast interfaces)
+ *
+ * @return             true if the adjacency needs to be excised, false
+ *                     otherwise
+ */
+bool isis_lfa_excise_adj_check(const struct isis_spftree *spftree,
+                              const uint8_t *id)
+{
+       const struct lfa_protected_resource *resource;
+
+       if (spftree->type != SPF_TYPE_TI_LFA)
+               return false;
+
+       /*
+        * Adjacencies formed over the failed interface should be excised both
+        * when using link and node protection.
+        */
+       resource = &spftree->lfa.protected_resource;
+       if (!memcmp(resource->adjacency, id, ISIS_SYS_ID_LEN + 1))
+               return true;
+
+       return false;
+}
+
+/**
+ * Check if a given IS-IS node needs to be excised when computing the SPF
+ * post-convergence tree.
+ *
+ * @param spftree      IS-IS SPF tree
+ * @param id           Node System ID
+ *
+ * @return             true if the node needs to be excised, false otherwise
+ */
+bool isis_lfa_excise_node_check(const struct isis_spftree *spftree,
+                               const uint8_t *id)
+{
+       const struct lfa_protected_resource *resource;
+
+       if (spftree->type != SPF_TYPE_TI_LFA)
+               return false;
+
+       /*
+        * When using node protection, nodes reachable over the failed interface
+        * must be excised.
+        */
+       resource = &spftree->lfa.protected_resource;
+       if (resource->type == LFA_LINK_PROTECTION)
+               return false;
+
+       if (isis_spf_node_find(&resource->nodes, id))
+               return true;
+
+       return false;
+}
+
+struct tilfa_find_pnode_prefix_sid_args {
+       uint32_t sid_index;
+};
+
+static int tilfa_find_pnode_prefix_sid_cb(const struct prefix *prefix,
+                                         uint32_t metric, bool external,
+                                         struct isis_subtlvs *subtlvs,
+                                         void *arg)
+{
+       struct tilfa_find_pnode_prefix_sid_args *args = arg;
+       struct isis_prefix_sid *psid;
+
+       if (!subtlvs || subtlvs->prefix_sids.count == 0)
+               return LSP_ITER_CONTINUE;
+
+       psid = (struct isis_prefix_sid *)subtlvs->prefix_sids.head;
+
+       /* Require the node flag to be set. */
+       if (!CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_NODE))
+               return LSP_ITER_CONTINUE;
+
+       args->sid_index = psid->value;
+
+       return LSP_ITER_STOP;
+}
+
+/* Find Prefix-SID associated to a System ID. */
+static uint32_t tilfa_find_pnode_prefix_sid(struct isis_spftree *spftree,
+                                           const uint8_t *sysid)
+{
+       struct isis_lsp *lsp;
+       struct tilfa_find_pnode_prefix_sid_args args;
+
+       lsp = isis_root_system_lsp(spftree->lspdb, sysid);
+       if (!lsp)
+               return UINT32_MAX;
+
+       args.sid_index = UINT32_MAX;
+       isis_lsp_iterate_ip_reach(lsp, spftree->family, spftree->mtid,
+                                 tilfa_find_pnode_prefix_sid_cb, &args);
+
+       return args.sid_index;
+}
+
+struct tilfa_find_qnode_adj_sid_args {
+       const uint8_t *qnode_sysid;
+       mpls_label_t label;
+};
+
+static int tilfa_find_qnode_adj_sid_cb(const uint8_t *id, uint32_t metric,
+                                      bool oldmetric,
+                                      struct isis_ext_subtlvs *subtlvs,
+                                      void *arg)
+{
+       struct tilfa_find_qnode_adj_sid_args *args = arg;
+       struct isis_adj_sid *adj_sid;
+
+       if (memcmp(id, args->qnode_sysid, ISIS_SYS_ID_LEN))
+               return LSP_ITER_CONTINUE;
+       if (!subtlvs || subtlvs->adj_sid.count == 0)
+               return LSP_ITER_CONTINUE;
+
+       adj_sid = (struct isis_adj_sid *)subtlvs->adj_sid.head;
+       args->label = adj_sid->sid;
+
+       return LSP_ITER_STOP;
+}
+
+/* Find Adj-SID associated to a pair of System IDs. */
+static mpls_label_t tilfa_find_qnode_adj_sid(struct isis_spftree *spftree,
+                                            const uint8_t *source_sysid,
+                                            const uint8_t *qnode_sysid)
+{
+       struct isis_lsp *lsp;
+       struct tilfa_find_qnode_adj_sid_args args;
+
+       lsp = isis_root_system_lsp(spftree->lspdb, source_sysid);
+       if (!lsp)
+               return MPLS_INVALID_LABEL;
+
+       args.qnode_sysid = qnode_sysid;
+       args.label = MPLS_INVALID_LABEL;
+       isis_lsp_iterate_is_reach(lsp, spftree->mtid,
+                                 tilfa_find_qnode_adj_sid_cb, &args);
+
+       return args.label;
+}
+
+/*
+ * Compute the MPLS label stack associated to a TI-LFA repair list. This
+ * needs to be computed separately for each adjacency since different
+ * neighbors can have different SRGBs.
+ */
+static struct mpls_label_stack *
+tilfa_compute_label_stack(struct lspdb_head *lspdb,
+                         const struct isis_spf_adj *sadj,
+                         const struct list *repair_list)
+{
+       struct mpls_label_stack *label_stack;
+       struct isis_tilfa_sid *sid;
+       struct listnode *node;
+       size_t i = 0;
+
+       /* Allocate label stack. */
+       label_stack = XCALLOC(MTYPE_ISIS_NEXTHOP_LABELS,
+                             sizeof(struct mpls_label_stack)
+                                     + listcount(repair_list)
+                                               * sizeof(mpls_label_t));
+       label_stack->num_labels = listcount(repair_list);
+
+       for (ALL_LIST_ELEMENTS_RO(repair_list, node, sid)) {
+               const uint8_t *target_node;
+               struct isis_sr_block *srgb;
+               mpls_label_t label;
+
+               switch (sid->type) {
+               case TILFA_SID_PREFIX:
+                       if (sid->value.index.remote)
+                               target_node = sid->value.index.remote_sysid;
+                       else
+                               target_node = sadj->id;
+                       srgb = isis_sr_find_srgb(lspdb, target_node);
+                       if (!srgb) {
+                               zlog_warn("%s: SRGB not found for node %s",
+                                         __func__,
+                                         print_sys_hostname(target_node));
+                               goto error;
+                       }
+
+                       /* Check if the SID index falls inside the SRGB. */
+                       if (sid->value.index.value >= srgb->range_size) {
+                               flog_warn(
+                                       EC_ISIS_SID_OVERFLOW,
+                                       "%s: SID index %u falls outside remote SRGB range",
+                                       __func__, sid->value.index.value);
+                               goto error;
+                       }
+
+                       /*
+                        * Prefix-SID: map SID index to label value within the
+                        * SRGB.
+                        */
+                       label = srgb->lower_bound + sid->value.index.value;
+                       break;
+               case TILFA_SID_ADJ:
+                       /* Adj-SID: absolute label value can be used directly */
+                       label = sid->value.label;
+                       break;
+               default:
+                       flog_err(EC_LIB_DEVELOPMENT,
+                                "%s: unknown TI-LFA SID type [%u]", __func__,
+                                sid->type);
+                       exit(1);
+               }
+               label_stack->label[i++] = label;
+       }
+
+       return label_stack;
+
+error:
+       XFREE(MTYPE_ISIS_NEXTHOP_LABELS, label_stack);
+       return NULL;
+}
+
+static int tilfa_repair_list_apply(struct isis_spftree *spftree,
+                                  struct isis_vertex *vertex_dest,
+                                  const struct isis_vertex *vertex_pnode,
+                                  const struct list *repair_list)
+{
+       struct isis_vertex_adj *vadj;
+       struct listnode *node;
+
+       for (ALL_LIST_ELEMENTS_RO(vertex_dest->Adj_N, node, vadj)) {
+               struct isis_spf_adj *sadj = vadj->sadj;
+               struct mpls_label_stack *label_stack;
+
+               if (!isis_vertex_adj_exists(spftree, vertex_pnode, sadj))
+                       continue;
+
+               assert(!vadj->label_stack);
+               label_stack = tilfa_compute_label_stack(spftree->lspdb, sadj,
+                                                       repair_list);
+               if (!label_stack) {
+                       char buf[VID2STR_BUFFER];
+
+                       vid2string(vertex_dest, buf, sizeof(buf));
+                       zlog_warn(
+                               "%s: %s %s adjacency %s: failed to compute label stack",
+                               __func__, vtype2string(vertex_dest->type), buf,
+                               print_sys_hostname(sadj->id));
+                       return -1;
+               }
+
+               vadj->label_stack = label_stack;
+       }
+
+       return 0;
+}
+
+/*
+ * Check if a node belongs to the extended P-space corresponding to a given
+ * destination.
+ */
+static bool lfa_ext_p_space_check(const struct isis_spftree *spftree_pc,
+                                 const struct isis_vertex *vertex_dest,
+                                 const struct isis_vertex *vertex)
+{
+       struct isis_spftree *spftree_old = spftree_pc->lfa.old.spftree;
+       struct isis_vertex_adj *vadj;
+       struct listnode *node;
+
+       /* Check the local P-space first. */
+       if (isis_spf_node_find(&spftree_pc->lfa.p_space, vertex->N.id))
+               return true;
+
+       /*
+        * Check the P-space of the adjacent routers used to reach the
+        * destination.
+        */
+       for (ALL_LIST_ELEMENTS_RO(vertex_dest->Adj_N, node, vadj)) {
+               struct isis_spf_adj *sadj = vadj->sadj;
+               struct isis_spf_node *adj_node;
+
+               adj_node =
+                       isis_spf_node_find(&spftree_old->adj_nodes, sadj->id);
+               if (!adj_node)
+                       continue;
+
+               if (isis_spf_node_find(&adj_node->lfa.p_space, vertex->N.id))
+                       return true;
+       }
+
+       return false;
+}
+
+/* Check if a node belongs to the Q-space. */
+static bool lfa_q_space_check(const struct isis_spftree *spftree_pc,
+                             const struct isis_vertex *vertex)
+{
+       return isis_spf_node_find(&spftree_pc->lfa.q_space, vertex->N.id);
+}
+
+/* This is a recursive function. */
+static int tilfa_build_repair_list(struct isis_spftree *spftree_pc,
+                                  struct isis_vertex *vertex_dest,
+                                  const struct isis_vertex *vertex,
+                                  const struct isis_vertex *vertex_child,
+                                  struct isis_spf_nodes *used_pnodes,
+                                  struct list *repair_list)
+{
+       struct isis_vertex *pvertex;
+       struct listnode *node;
+       bool is_pnode, is_qnode;
+       char buf[VID2STR_BUFFER];
+       struct isis_tilfa_sid sid_dest = {}, sid_qnode = {}, sid_pnode = {};
+       uint32_t sid_index;
+       mpls_label_t label_qnode;
+
+       if (IS_DEBUG_TILFA) {
+               vid2string(vertex, buf, sizeof(buf));
+               zlog_debug("ISIS-TI-LFA: vertex %s %s",
+                          vtype2string(vertex->type), buf);
+       }
+
+       /* Push original Prefix-SID label when necessary. */
+       if (VTYPE_IP(vertex->type) && vertex->N.ip.sr.present) {
+               pvertex = listnode_head(vertex->parents);
+               assert(pvertex);
+
+               sid_index = vertex->N.ip.sr.sid.value;
+               if (IS_DEBUG_TILFA)
+                       zlog_debug(
+                               "ISIS-TI-LFA: pushing Prefix-SID to %pFX (index %u)",
+                               &vertex->N.ip.p.dest, sid_index);
+               sid_dest.type = TILFA_SID_PREFIX;
+               sid_dest.value.index.value = sid_index;
+               sid_dest.value.index.remote = true;
+               memcpy(sid_dest.value.index.remote_sysid, pvertex->N.id,
+                      sizeof(sid_dest.value.index.remote_sysid));
+               listnode_add_head(repair_list, &sid_dest);
+       }
+
+       if (!vertex_child)
+               goto parents;
+       if (vertex->type != VTYPE_NONPSEUDO_IS
+           && vertex->type != VTYPE_NONPSEUDO_TE_IS)
+               goto parents;
+       if (!VTYPE_IS(vertex_child->type))
+               vertex_child = NULL;
+
+       /* Check if node is part of the extended P-space and/or Q-space. */
+       is_pnode = lfa_ext_p_space_check(spftree_pc, vertex_dest, vertex);
+       is_qnode = lfa_q_space_check(spftree_pc, vertex);
+
+       /* Push Adj-SID label when necessary. */
+       if ((!is_qnode
+            || spftree_pc->lfa.protected_resource.type == LFA_NODE_PROTECTION)
+           && vertex_child) {
+               label_qnode = tilfa_find_qnode_adj_sid(spftree_pc, vertex->N.id,
+                                                      vertex_child->N.id);
+               if (label_qnode == MPLS_INVALID_LABEL) {
+                       zlog_warn("ISIS-TI-LFA: failed to find %s->%s Adj-SID",
+                                 print_sys_hostname(vertex->N.id),
+                                 print_sys_hostname(vertex_child->N.id));
+                       return -1;
+               }
+               if (IS_DEBUG_TILFA)
+                       zlog_debug(
+                               "ISIS-TI-LFA: pushing %s->%s Adj-SID (label %u)",
+                               print_sys_hostname(vertex->N.id),
+                               print_sys_hostname(vertex_child->N.id),
+                               label_qnode);
+               sid_qnode.type = TILFA_SID_ADJ;
+               sid_qnode.value.label = label_qnode;
+               listnode_add_head(repair_list, &sid_qnode);
+       }
+
+       /* Push Prefix-SID label when necessary. */
+       if (is_pnode) {
+               /* The same P-node can't be used more than once. */
+               if (isis_spf_node_find(used_pnodes, vertex->N.id)) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: skipping already used P-node");
+                       return 0;
+               }
+               isis_spf_node_new(used_pnodes, vertex->N.id);
+
+               if (!vertex_child) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: destination is within Ext-P-Space");
+                       return 0;
+               }
+
+               sid_index =
+                       tilfa_find_pnode_prefix_sid(spftree_pc, vertex->N.id);
+               if (sid_index == UINT32_MAX) {
+                       zlog_warn(
+                               "ISIS-TI-LFA: failed to find Prefix-SID corresponding to PQ-node %s",
+                               print_sys_hostname(vertex->N.id));
+                       return -1;
+               }
+
+               if (IS_DEBUG_TILFA)
+                       zlog_debug(
+                               "ISIS-TI-LFA: pushing Node-SID to %s (index %u)",
+                               print_sys_hostname(vertex->N.id), sid_index);
+               sid_pnode.type = TILFA_SID_PREFIX;
+               sid_pnode.value.index.value = sid_index;
+               listnode_add_head(repair_list, &sid_pnode);
+
+               /* Apply repair list. */
+               if (tilfa_repair_list_apply(spftree_pc, vertex_dest, vertex,
+                                           repair_list)
+                   != 0)
+                       return -1;
+               return 0;
+       }
+
+parents:
+       for (ALL_LIST_ELEMENTS_RO(vertex->parents, node, pvertex)) {
+               struct list *repair_list_parent;
+               bool ecmp;
+               int ret;
+
+               ecmp = (listcount(vertex->parents) > 1) ? true : false;
+               repair_list_parent = ecmp ? list_dup(repair_list) : repair_list;
+               ret = tilfa_build_repair_list(spftree_pc, vertex_dest, pvertex,
+                                             vertex, used_pnodes,
+                                             repair_list_parent);
+               if (ecmp)
+                       list_delete(&repair_list_parent);
+               if (ret != 0)
+                       return ret;
+       }
+
+       return 0;
+}
+
+static const char *lfa_protection_type2str(enum lfa_protection_type type)
+{
+       switch (type) {
+       case LFA_LINK_PROTECTION:
+               return "link protection";
+       case LFA_NODE_PROTECTION:
+               return "node protection";
+       default:
+               return "unknown protection type";
+       }
+}
+
+static const char *
+lfa_protected_resource2str(const struct lfa_protected_resource *resource)
+{
+       const uint8_t *fail_id;
+       static char buffer[128];
+
+       fail_id = resource->adjacency;
+       snprintf(buffer, sizeof(buffer), "%s.%u's failure (%s)",
+                print_sys_hostname(fail_id), LSP_PSEUDO_ID(fail_id),
+                lfa_protection_type2str(resource->type));
+
+       return buffer;
+}
+
+static bool
+spf_adj_check_is_affected(const struct isis_spf_adj *sadj,
+                         const struct lfa_protected_resource *resource,
+                         const uint8_t *root_sysid, bool reverse)
+{
+       if (!!CHECK_FLAG(sadj->flags, F_ISIS_SPF_ADJ_BROADCAST)
+           != !!LSP_PSEUDO_ID(resource->adjacency))
+               return false;
+
+       if (CHECK_FLAG(sadj->flags, F_ISIS_SPF_ADJ_BROADCAST)) {
+               if (!memcmp(sadj->lan.desig_is_id, resource->adjacency,
+                           ISIS_SYS_ID_LEN + 1))
+                       return true;
+       } else {
+               if (!reverse
+                   && !memcmp(sadj->id, resource->adjacency, ISIS_SYS_ID_LEN))
+                       return true;
+               if (reverse && !memcmp(sadj->id, root_sysid, ISIS_SYS_ID_LEN))
+                       return true;
+       }
+
+       return false;
+}
+
+/* Check if the given SPF vertex needs LFA protection. */
+static bool lfa_check_needs_protection(const struct isis_spftree *spftree_pc,
+                                      const struct isis_vertex *vertex)
+{
+       struct isis_vertex *vertex_old;
+       struct listnode *node;
+       size_t affected_nhs = 0;
+       struct isis_vertex_adj *vadj;
+
+       /* Local routes don't need protection. */
+       if (VTYPE_IP(vertex->type) && vertex->depth == 1)
+               return false;
+
+       /* Only local adjacencies need Adj-SID protection. */
+       if (VTYPE_IS(vertex->type)
+           && !isis_adj_find(spftree_pc->area, spftree_pc->level,
+                             vertex->N.id))
+               return false;
+
+       vertex_old = isis_find_vertex(&spftree_pc->lfa.old.spftree->paths,
+                                     &vertex->N, vertex->type);
+       if (!vertex_old)
+               return false;
+
+       for (ALL_LIST_ELEMENTS_RO(vertex_old->Adj_N, node, vadj)) {
+               struct isis_spf_adj *sadj = vadj->sadj;
+
+               if (spf_adj_check_is_affected(
+                           sadj, &spftree_pc->lfa.protected_resource,
+                           spftree_pc->sysid, false))
+                       affected_nhs++;
+       }
+
+       /*
+        * No need to compute backup paths for ECMP routes, except if all
+        * primary nexthops share the same broadcast interface.
+        */
+       if (listcount(vertex_old->Adj_N) == affected_nhs)
+               return true;
+
+       return false;
+}
+
+/**
+ * Check if the given SPF vertex needs protection and, if so, compute and
+ * install the corresponding repair paths.
+ *
+ * @param spftree_pc   The post-convergence SPF tree
+ * @param vertex       IS-IS SPF vertex to check
+ *
+ * @return             0 if the vertex needs to be protected, -1 otherwise
+ */
+int isis_lfa_check(struct isis_spftree *spftree_pc, struct isis_vertex *vertex)
+{
+       struct isis_spf_nodes used_pnodes;
+       char buf[VID2STR_BUFFER];
+       struct list *repair_list;
+       int ret;
+
+       if (!spftree_pc->area->srdb.enabled)
+               return -1;
+
+       if (IS_DEBUG_TILFA)
+               vid2string(vertex, buf, sizeof(buf));
+
+       if (!lfa_check_needs_protection(spftree_pc, vertex)) {
+               if (IS_DEBUG_TILFA)
+                       zlog_debug(
+                               "ISIS-TI-LFA: %s %s unaffected by %s",
+                               vtype2string(vertex->type), buf,
+                               lfa_protected_resource2str(
+                                       &spftree_pc->lfa.protected_resource));
+
+               return -1;
+       }
+
+       /*
+        * Check if the route/adjacency was already covered by node protection.
+        */
+       if (VTYPE_IS(vertex->type)) {
+               struct isis_adjacency *adj;
+
+               adj = isis_adj_find(spftree_pc->area, spftree_pc->level,
+                                   vertex->N.id);
+               if (adj
+                   && isis_sr_adj_sid_find(adj, spftree_pc->family,
+                                           ISIS_SR_LAN_BACKUP)) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: %s %s already covered by node protection",
+                                       vtype2string(vertex->type), buf);
+
+                       return -1;
+               }
+       }
+       if (VTYPE_IP(vertex->type)) {
+               struct route_table *route_table;
+
+               route_table = spftree_pc->lfa.old.spftree->route_table_backup;
+               if (route_node_lookup(route_table, &vertex->N.ip.p.dest)) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: %s %s already covered by node protection",
+                                       vtype2string(vertex->type), buf);
+
+                       return -1;
+               }
+       }
+
+       if (IS_DEBUG_TILFA)
+               zlog_debug(
+                       "ISIS-TI-LFA: computing repair path(s) of %s %s w.r.t %s",
+                       vtype2string(vertex->type), buf,
+                       lfa_protected_resource2str(
+                               &spftree_pc->lfa.protected_resource));
+
+       /* Create base repair list. */
+       repair_list = list_new();
+
+       isis_spf_node_list_init(&used_pnodes);
+       ret = tilfa_build_repair_list(spftree_pc, vertex, vertex, NULL,
+                                     &used_pnodes, repair_list);
+       isis_spf_node_list_clear(&used_pnodes);
+       list_delete(&repair_list);
+       if (ret != 0)
+               zlog_warn("ISIS-TI-LFA: failed to compute repair path(s)");
+
+       return ret;
+}
+
+static bool
+spf_adj_node_is_affected(struct isis_spf_node *adj_node,
+                        const struct lfa_protected_resource *resource,
+                        const uint8_t *root_sysid)
+{
+       struct isis_spf_adj *sadj;
+       struct listnode *node;
+
+       for (ALL_LIST_ELEMENTS_RO(adj_node->adjacencies, node, sadj)) {
+               if (sadj->metric != adj_node->best_metric)
+                       continue;
+               if (spf_adj_check_is_affected(sadj, resource, root_sysid,
+                                             false))
+                       return true;
+       }
+
+       return false;
+}
+
+static bool vertex_is_affected(struct isis_spftree *spftree_root,
+                              const struct isis_spf_nodes *adj_nodes,
+                              bool p_space, const struct isis_vertex *vertex,
+                              const struct lfa_protected_resource *resource)
+{
+       struct isis_vertex *pvertex;
+       struct listnode *node, *vnode;
+
+       for (ALL_LIST_ELEMENTS_RO(vertex->parents, node, pvertex)) {
+               struct isis_spftree *spftree_parent;
+               struct isis_vertex *vertex_child;
+               struct isis_vertex_adj *vadj;
+               bool reverse = false;
+               char buf1[VID2STR_BUFFER];
+               char buf2[VID2STR_BUFFER];
+
+               if (IS_DEBUG_TILFA)
+                       zlog_debug("ISIS-TI-LFA: vertex %s parent %s",
+                                  vid2string(vertex, buf1, sizeof(buf1)),
+                                  vid2string(pvertex, buf2, sizeof(buf2)));
+
+               if (p_space && resource->type == LFA_NODE_PROTECTION) {
+                       if (isis_spf_node_find(&resource->nodes, vertex->N.id))
+                               return true;
+                       goto parents;
+               }
+
+               /* Check if either the vertex or its parent is the root node. */
+               if (memcmp(vertex->N.id, spftree_root->sysid, ISIS_SYS_ID_LEN)
+                   && memcmp(pvertex->N.id, spftree_root->sysid,
+                             ISIS_SYS_ID_LEN))
+                       goto parents;
+
+               /* Get SPT of the parent vertex. */
+               if (!memcmp(pvertex->N.id, spftree_root->sysid,
+                           ISIS_SYS_ID_LEN))
+                       spftree_parent = spftree_root;
+               else {
+                       struct isis_spf_node *adj_node;
+
+                       adj_node = isis_spf_node_find(adj_nodes, pvertex->N.id);
+                       assert(adj_node);
+                       spftree_parent = adj_node->lfa.spftree;
+                       assert(spftree_parent);
+                       reverse = true;
+               }
+
+               /* Get paths pvertex uses to reach vertex. */
+               vertex_child = isis_find_vertex(&spftree_parent->paths,
+                                               &vertex->N, vertex->type);
+               if (!vertex_child)
+                       goto parents;
+
+               /* Check if any of these paths use the protected resource. */
+               for (ALL_LIST_ELEMENTS_RO(vertex_child->Adj_N, vnode, vadj))
+                       if (spf_adj_check_is_affected(vadj->sadj, resource,
+                                                     spftree_root->sysid,
+                                                     reverse))
+                               return true;
+
+       parents:
+               if (vertex_is_affected(spftree_root, adj_nodes, p_space,
+                                      pvertex, resource))
+                       return true;
+       }
+
+       return false;
+}
+
+/* Calculate set of nodes reachable without using the protected interface. */
+static void lfa_calc_reach_nodes(struct isis_spftree *spftree,
+                                struct isis_spftree *spftree_root,
+                                const struct isis_spf_nodes *adj_nodes,
+                                bool p_space,
+                                const struct lfa_protected_resource *resource,
+                                struct isis_spf_nodes *nodes)
+{
+       struct isis_vertex *vertex;
+       struct listnode *node;
+
+       for (ALL_QUEUE_ELEMENTS_RO(&spftree->paths, node, vertex)) {
+               char buf[VID2STR_BUFFER];
+
+               if (!VTYPE_IS(vertex->type))
+                       continue;
+
+               /* Skip root node. */
+               if (!memcmp(vertex->N.id, spftree_root->sysid, ISIS_SYS_ID_LEN))
+                       continue;
+
+               /* Don't add the same node twice. */
+               if (isis_spf_node_find(nodes, vertex->N.id))
+                       continue;
+
+               if (IS_DEBUG_TILFA)
+                       zlog_debug("ISIS-TI-LFA: checking %s",
+                                  vid2string(vertex, buf, sizeof(buf)));
+
+               if (!vertex_is_affected(spftree_root, adj_nodes, p_space,
+                                       vertex, resource)) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: adding %s",
+                                       vid2string(vertex, buf, sizeof(buf)));
+
+                       isis_spf_node_new(nodes, vertex->N.id);
+               }
+       }
+}
+
+/**
+ * Helper function used to create an SPF tree structure and run reverse SPF on
+ * it.
+ *
+ * @param spftree      IS-IS SPF tree
+ *
+ * @return             Pointer to new SPF tree structure. 
+ */
+struct isis_spftree *isis_spf_reverse_run(const struct isis_spftree *spftree)
+{
+       struct isis_spftree *spftree_reverse;
+
+       spftree_reverse = isis_spftree_new(
+               spftree->area, spftree->lspdb, spftree->sysid, spftree->level,
+               spftree->tree_id, SPF_TYPE_REVERSE,
+               F_SPFTREE_NO_ADJACENCIES | F_SPFTREE_NO_ROUTES);
+       isis_run_spf(spftree_reverse);
+
+       return spftree_reverse;
+}
+
+/*
+ * Calculate the Extended P-space and Q-space associated to a given link
+ * failure.
+ */
+static void lfa_calc_pq_spaces(struct isis_spftree *spftree_pc,
+                              const struct lfa_protected_resource *resource)
+{
+       struct isis_spftree *spftree;
+       struct isis_spftree *spftree_reverse;
+       struct isis_spf_nodes *adj_nodes;
+       struct isis_spf_node *adj_node;
+
+       /* Obtain pre-failure SPTs and list of adjacent nodes. */
+       spftree = spftree_pc->lfa.old.spftree;
+       spftree_reverse = spftree_pc->lfa.old.spftree_reverse;
+       adj_nodes = &spftree->adj_nodes;
+
+       if (IS_DEBUG_TILFA)
+               zlog_debug("ISIS-TI-LFA: computing P-space (self)");
+       lfa_calc_reach_nodes(spftree, spftree, adj_nodes, true, resource,
+                            &spftree_pc->lfa.p_space);
+
+       RB_FOREACH (adj_node, isis_spf_nodes, adj_nodes) {
+               if (spf_adj_node_is_affected(adj_node, resource,
+                                            spftree->sysid)) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: computing Q-space (%s)",
+                                       print_sys_hostname(adj_node->sysid));
+
+                       /*
+                        * Compute the reverse SPF in the behalf of the node
+                        * adjacent to the failure.
+                        */
+                       adj_node->lfa.spftree_reverse =
+                               isis_spf_reverse_run(adj_node->lfa.spftree);
+
+                       lfa_calc_reach_nodes(adj_node->lfa.spftree_reverse,
+                                            spftree_reverse, adj_nodes, false,
+                                            resource,
+                                            &spftree_pc->lfa.q_space);
+               } else {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug(
+                                       "ISIS-TI-LFA: computing P-space (%s)",
+                                       print_sys_hostname(adj_node->sysid));
+                       lfa_calc_reach_nodes(adj_node->lfa.spftree, spftree,
+                                            adj_nodes, true, resource,
+                                            &adj_node->lfa.p_space);
+               }
+       }
+}
+
+/**
+ * Compute the TI-LFA backup paths for a given protected interface.
+ *
+ * @param area           IS-IS area
+ * @param spftree        IS-IS SPF tree
+ * @param spftree_reverse IS-IS Reverse SPF tree
+ * @param resource       Protected resource
+ *
+ * @return               Pointer to the post-convergence SPF tree
+ */
+struct isis_spftree *isis_tilfa_compute(struct isis_area *area,
+                                       struct isis_spftree *spftree,
+                                       struct isis_spftree *spftree_reverse,
+                                       struct lfa_protected_resource *resource)
+{
+       struct isis_spftree *spftree_pc;
+       struct isis_spf_node *adj_node;
+
+       if (IS_DEBUG_TILFA)
+               zlog_debug("ISIS-TI-LFA: computing the P/Q spaces w.r.t. %s",
+                          lfa_protected_resource2str(resource));
+
+       /* Populate list of nodes affected by link failure. */
+       if (resource->type == LFA_NODE_PROTECTION) {
+               isis_spf_node_list_init(&resource->nodes);
+               RB_FOREACH (adj_node, isis_spf_nodes, &spftree->adj_nodes) {
+                       if (spf_adj_node_is_affected(adj_node, resource,
+                                                    spftree->sysid))
+                               isis_spf_node_new(&resource->nodes,
+                                                 adj_node->sysid);
+               }
+       }
+
+       /* Create post-convergence SPF tree. */
+       spftree_pc = isis_spftree_new(area, spftree->lspdb, spftree->sysid,
+                                     spftree->level, spftree->tree_id,
+                                     SPF_TYPE_TI_LFA, spftree->flags);
+       spftree_pc->lfa.old.spftree = spftree;
+       spftree_pc->lfa.old.spftree_reverse = spftree_reverse;
+       spftree_pc->lfa.protected_resource = *resource;
+
+       /* Compute the extended P-space and Q-space. */
+       lfa_calc_pq_spaces(spftree_pc, resource);
+
+       if (IS_DEBUG_TILFA)
+               zlog_debug(
+                       "ISIS-TI-LFA: computing the post convergence SPT w.r.t. %s",
+                       lfa_protected_resource2str(resource));
+
+       /* Re-run SPF in the local node to find the post-convergence paths. */
+       isis_run_spf(spftree_pc);
+
+       /* Clear list of nodes affeted by link failure. */
+       if (resource->type == LFA_NODE_PROTECTION)
+               isis_spf_node_list_clear(&resource->nodes);
+
+       return spftree_pc;
+}
+
+/**
+ * Run forward SPF on all adjacent routers.
+ *
+ * @param spftree      IS-IS SPF tree
+ *
+ * @return             0 on success, -1 otherwise
+ */
+int isis_spf_run_neighbors(struct isis_spftree *spftree)
+{
+       struct isis_lsp *lsp;
+       struct isis_spf_node *adj_node;
+
+       lsp = isis_root_system_lsp(spftree->lspdb, spftree->sysid);
+       if (!lsp)
+               return -1;
+
+       RB_FOREACH (adj_node, isis_spf_nodes, &spftree->adj_nodes) {
+               if (IS_DEBUG_TILFA)
+                       zlog_debug("ISIS-TI-LFA: running SPF on neighbor %s",
+                                  print_sys_hostname(adj_node->sysid));
+
+               /* Compute the SPT on behalf of the neighbor. */
+               adj_node->lfa.spftree = isis_spftree_new(
+                       spftree->area, spftree->lspdb, adj_node->sysid,
+                       spftree->level, spftree->tree_id, SPF_TYPE_FORWARD,
+                       F_SPFTREE_NO_ADJACENCIES | F_SPFTREE_NO_ROUTES);
+               isis_run_spf(adj_node->lfa.spftree);
+       }
+
+       return 0;
+}
+
+/**
+ * Run the TI-LFA algorithm for all proctected interfaces.
+ *
+ * @param area         IS-IS area
+ * @param spftree      IS-IS SPF tree
+ */
+void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree)
+{
+       struct isis_spftree *spftree_reverse;
+       struct isis_circuit *circuit;
+       struct listnode *node;
+
+       /* Run reverse SPF locally. */
+       spftree_reverse = isis_spf_reverse_run(spftree);
+
+       /* Run forward SPF on all adjacent routers. */
+       isis_spf_run_neighbors(spftree);
+
+       /* Check which interfaces are protected. */
+       for (ALL_LIST_ELEMENTS_RO(area->circuit_list, node, circuit)) {
+               struct lfa_protected_resource resource = {};
+               struct isis_adjacency *adj;
+               struct isis_spftree *spftree_pc_link;
+               struct isis_spftree *spftree_pc_node;
+               static uint8_t null_sysid[ISIS_SYS_ID_LEN + 1];
+
+               if (!(circuit->is_type & spftree->level))
+                       continue;
+
+               if (!circuit->tilfa_protection[spftree->level - 1])
+                       continue;
+
+               /* Fill in the protected resource. */
+               switch (circuit->circ_type) {
+               case CIRCUIT_T_BROADCAST:
+                       if (spftree->level == 1)
+                               memcpy(resource.adjacency,
+                                      circuit->u.bc.l1_desig_is,
+                                      ISIS_SYS_ID_LEN + 1);
+                       else
+                               memcpy(resource.adjacency,
+                                      circuit->u.bc.l2_desig_is,
+                                      ISIS_SYS_ID_LEN + 1);
+                       /* Do nothing if no DR was elected yet. */
+                       if (!memcmp(resource.adjacency, null_sysid,
+                                   ISIS_SYS_ID_LEN + 1))
+                               continue;
+                       break;
+               case CIRCUIT_T_P2P:
+                       adj = circuit->u.p2p.neighbor;
+                       if (!adj)
+                               continue;
+                       memcpy(resource.adjacency, adj->sysid, ISIS_SYS_ID_LEN);
+                       LSP_PSEUDO_ID(resource.adjacency) = 0;
+                       break;
+               default:
+                       continue;
+               }
+
+               /* Compute node protecting repair paths first (if necessary). */
+               if (circuit->tilfa_node_protection[spftree->level - 1]) {
+                       resource.type = LFA_NODE_PROTECTION;
+                       spftree_pc_node = isis_tilfa_compute(
+                               area, spftree, spftree_reverse, &resource);
+                       isis_spftree_del(spftree_pc_node);
+               }
+
+               /* Compute link protecting repair paths. */
+               resource.type = LFA_LINK_PROTECTION;
+               spftree_pc_link = isis_tilfa_compute(
+                       area, spftree, spftree_reverse, &resource);
+               isis_spftree_del(spftree_pc_link);
+       }
+
+       isis_spftree_del(spftree_reverse);
+}
diff --git a/isisd/isis_lfa.h b/isisd/isis_lfa.h
new file mode 100644 (file)
index 0000000..8356187
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2020  NetDEF, Inc.
+ *                     Renato Westphal
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _FRR_ISIS_LFA_H
+#define _FRR_ISIS_LFA_H
+
+enum isis_tilfa_sid_type {
+       TILFA_SID_PREFIX = 1,
+       TILFA_SID_ADJ,
+};
+
+struct isis_tilfa_sid {
+       enum isis_tilfa_sid_type type;
+       union {
+               struct {
+                       uint32_t value;
+                       bool remote;
+                       uint8_t remote_sysid[ISIS_SYS_ID_LEN];
+               } index;
+               mpls_label_t label;
+       } value;
+};
+
+RB_HEAD(isis_spf_nodes, isis_spf_node);
+RB_PROTOTYPE(isis_spf_nodes, isis_spf_node, entry, isis_spf_node_compare)
+struct isis_spf_node {
+       RB_ENTRY(isis_spf_node) entry;
+
+       /* Node's System ID. */
+       uint8_t sysid[ISIS_SYS_ID_LEN];
+
+       /* Local adjacencies over which this node is reachable. */
+       struct list *adjacencies;
+
+       /* Best metric of all adjacencies used to reach this node. */
+       uint32_t best_metric;
+
+       struct {
+               /* Node's forward SPT. */
+               struct isis_spftree *spftree;
+
+               /* Node's reverse SPT. */
+               struct isis_spftree *spftree_reverse;
+
+               /* Node's P-space. */
+               struct isis_spf_nodes p_space;
+       } lfa;
+};
+
+enum lfa_protection_type {
+       LFA_LINK_PROTECTION = 1,
+       LFA_NODE_PROTECTION,
+};
+
+struct lfa_protected_resource {
+       /* The protection type. */
+       enum lfa_protection_type type;
+
+       /* The protected adjacency (might be a pseudonode). */
+       uint8_t adjacency[ISIS_SYS_ID_LEN + 1];
+
+       /* List of nodes reachable over the protected interface. */
+       struct isis_spf_nodes nodes;
+};
+
+/* Forward declaration(s). */
+struct isis_vertex;
+
+/* Prototypes. */
+void isis_spf_node_list_init(struct isis_spf_nodes *nodes);
+void isis_spf_node_list_clear(struct isis_spf_nodes *nodes);
+struct isis_spf_node *isis_spf_node_new(struct isis_spf_nodes *nodes,
+                                       const uint8_t *sysid);
+struct isis_spf_node *isis_spf_node_find(const struct isis_spf_nodes *nodes,
+                                        const uint8_t *sysid);
+bool isis_lfa_excise_adj_check(const struct isis_spftree *spftree,
+                              const uint8_t *id);
+bool isis_lfa_excise_node_check(const struct isis_spftree *spftree,
+                               const uint8_t *id);
+struct isis_spftree *isis_spf_reverse_run(const struct isis_spftree *spftree);
+int isis_spf_run_neighbors(struct isis_spftree *spftree);
+void isis_spf_run_lfa(struct isis_area *area, struct isis_spftree *spftree);
+int isis_lfa_check(struct isis_spftree *spftree, struct isis_vertex *vertex);
+struct isis_spftree *
+isis_tilfa_compute(struct isis_area *area, struct isis_spftree *spftree,
+                  struct isis_spftree *spftree_reverse,
+                  struct lfa_protected_resource *protected_resource);
+
+#endif /* _FRR_ISIS_LFA_H */
index 1af6f417dc42bec1ea73722d07be4c3167d35c5c..d8ad4cd510ab2434c8713b5930a416fcd4fb30c0 100644 (file)
@@ -852,7 +852,6 @@ static struct isis_lsp *lsp_next_frag(uint8_t frag_num, struct isis_lsp *lsp0,
 static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
 {
        int level = lsp->level;
-       char buf[PREFIX2STR_BUFFER];
        struct listnode *node;
        struct isis_lsp *frag;
 
@@ -964,9 +963,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
         */
        if (area->isis->router_id != 0) {
                struct in_addr id = {.s_addr = area->isis->router_id};
-               inet_ntop(AF_INET, &id, buf, sizeof(buf));
-               lsp_debug("ISIS (%s): Adding router ID %s as IPv4 tlv.",
-                         area->area_tag, buf);
+               lsp_debug("ISIS (%s): Adding router ID %pI4 as IPv4 tlv.",
+                         area->area_tag, &id);
                isis_tlvs_add_ipv4_address(lsp->tlvs, &id);
 
                /* If new style TLV's are in use, add TE router ID TLV
@@ -1033,10 +1031,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
                                                  ipv4)) {
                                if (area->oldmetric) {
                                        lsp_debug(
-                                               "ISIS (%s): Adding old-style IP reachability for %s",
-                                               area->area_tag,
-                                               prefix2str(ipv4, buf,
-                                                          sizeof(buf)));
+                                               "ISIS (%s): Adding old-style IP reachability for %pFX",
+                                               area->area_tag, ipv4);
                                        isis_tlvs_add_oldstyle_ip_reach(
                                                lsp->tlvs, ipv4, metric);
                                }
@@ -1045,10 +1041,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
                                        struct sr_prefix_cfg *pcfg = NULL;
 
                                        lsp_debug(
-                                               "ISIS (%s): Adding te-style IP reachability for %s",
-                                               area->area_tag,
-                                               prefix2str(ipv4, buf,
-                                                          sizeof(buf)));
+                                               "ISIS (%s): Adding te-style IP reachability for %pFX",
+                                               area->area_tag, ipv4);
 
                                        if (area->srdb.enabled)
                                                pcfg = isis_sr_cfg_prefix_find(
@@ -1071,9 +1065,8 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
                                struct sr_prefix_cfg *pcfg = NULL;
 
                                lsp_debug(
-                                       "ISIS (%s): Adding IPv6 reachability for %s",
-                                       area->area_tag,
-                                       prefix2str(ipv6, buf, sizeof(buf)));
+                                       "ISIS (%s): Adding IPv6 reachability for %pFX",
+                                       area->area_tag, ipv6);
 
                                if (area->srdb.enabled)
                                        pcfg = isis_sr_cfg_prefix_find(area,
@@ -1248,7 +1241,7 @@ int lsp_generate(struct isis_area *area, int level)
 
        refresh_time = lsp_refresh_time(newlsp, rem_lifetime);
 
-       THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]);
+       thread_cancel(&area->t_lsp_refresh[level - 1]);
        area->lsp_regenerate_pending[level - 1] = 0;
        thread_add_timer(master, lsp_refresh,
                         &area->lsp_refresh_arg[level - 1], refresh_time,
@@ -1458,7 +1451,7 @@ int _lsp_regenerate_schedule(struct isis_area *area, int level,
                        "ISIS (%s): Will schedule regen timer. Last run was: %lld, Now is: %lld",
                        area->area_tag, (long long)lsp->last_generated,
                        (long long)now);
-               THREAD_TIMER_OFF(area->t_lsp_refresh[lvl - 1]);
+               thread_cancel(&area->t_lsp_refresh[lvl - 1]);
                diff = now - lsp->last_generated;
                if (diff < area->lsp_gen_interval[lvl - 1]
                    && !(area->bfd_signalled_down)) {
@@ -1611,7 +1604,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
            || (circuit->u.bc.is_dr[level - 1] == 0))
                return ISIS_ERROR;
 
-       memcpy(lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
+       memcpy(lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN);
        LSP_FRAGMENT(lsp_id) = 0;
        LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id;
 
@@ -1635,7 +1628,7 @@ int lsp_generate_pseudo(struct isis_circuit *circuit, int level)
        lsp_flood(lsp, NULL);
 
        refresh_time = lsp_refresh_time(lsp, rem_lifetime);
-       THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
+       thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[level - 1]);
        circuit->lsp_regenerate_pending[level - 1] = 0;
        if (level == IS_LEVEL_1)
                thread_add_timer(
@@ -1671,7 +1664,7 @@ static int lsp_regenerate_pseudo(struct isis_circuit *circuit, int level)
            || (circuit->u.bc.is_dr[level - 1] == 0))
                return ISIS_ERROR;
 
-       memcpy(lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
+       memcpy(lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN);
        LSP_PSEUDO_ID(lsp_id) = circuit->circuit_id;
        LSP_FRAGMENT(lsp_id) = 0;
 
@@ -1728,7 +1721,7 @@ static int lsp_l1_refresh_pseudo(struct thread *thread)
 
        if ((circuit->u.bc.is_dr[0] == 0)
            || (circuit->is_type & IS_LEVEL_1) == 0) {
-               memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
+               memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN);
                LSP_PSEUDO_ID(id) = circuit->circuit_id;
                LSP_FRAGMENT(id) = 0;
                lsp_purge_pseudo(id, circuit, IS_LEVEL_1);
@@ -1750,7 +1743,7 @@ static int lsp_l2_refresh_pseudo(struct thread *thread)
 
        if ((circuit->u.bc.is_dr[1] == 0)
            || (circuit->is_type & IS_LEVEL_2) == 0) {
-               memcpy(id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN);
+               memcpy(id, circuit->isis->sysid, ISIS_SYS_ID_LEN);
                LSP_PSEUDO_ID(id) = circuit->circuit_id;
                LSP_FRAGMENT(id) = 0;
                lsp_purge_pseudo(id, circuit, IS_LEVEL_2);
@@ -1826,7 +1819,7 @@ int lsp_regenerate_schedule_pseudo(struct isis_circuit *circuit, int level)
                        "ISIS (%s): Will schedule PSN regen timer. Last run was: %lld, Now is: %lld",
                        area->area_tag, (long long)lsp->last_generated,
                        (long long)now);
-               THREAD_TIMER_OFF(circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
+               thread_cancel(&circuit->u.bc.t_refresh_pseudo_lsp[lvl - 1]);
                diff = now - lsp->last_generated;
                if (diff < circuit->area->lsp_gen_interval[lvl - 1]) {
                        timeout =
index 27254597676b3091822e16bee8b6966705f089f9..a64decc14fbeb7d1c0d458b2d4e5e0c9c821fdf3 100644 (file)
@@ -39,6 +39,7 @@ DEFINE_MTYPE(ISISD, ISIS_SPFTREE, "ISIS SPFtree")
 DEFINE_MTYPE(ISISD, ISIS_VERTEX, "ISIS vertex")
 DEFINE_MTYPE(ISISD, ISIS_ROUTE_INFO, "ISIS route info")
 DEFINE_MTYPE(ISISD, ISIS_NEXTHOP, "ISIS nexthop")
+DEFINE_MTYPE(ISISD, ISIS_NEXTHOP_LABELS, "ISIS nexthop MPLS labels")
 DEFINE_MTYPE(ISISD, ISIS_DICT, "ISIS dictionary")
 DEFINE_MTYPE(ISISD, ISIS_DICT_NODE, "ISIS dictionary node")
 DEFINE_MTYPE(ISISD, ISIS_EXT_ROUTE, "ISIS redistributed route")
index e672340e8457c42c3b1504cbadcb0347a9bc5701..6b63b3ccb8cbad1e210ccfd5cb0c93d45c44d6d1 100644 (file)
@@ -38,6 +38,7 @@ DECLARE_MTYPE(ISIS_SPFTREE)
 DECLARE_MTYPE(ISIS_VERTEX)
 DECLARE_MTYPE(ISIS_ROUTE_INFO)
 DECLARE_MTYPE(ISIS_NEXTHOP)
+DECLARE_MTYPE(ISIS_NEXTHOP_LABELS)
 DECLARE_MTYPE(ISIS_DICT)
 DECLARE_MTYPE(ISIS_DICT_NODE)
 DECLARE_MTYPE(ISIS_EXT_ROUTE)
index 14ea1170c4ed265626503fced27fe9ccbf30f5ff..2d3c7e1e38b31d50176eb48b20969513ec3068c0 100644 (file)
@@ -537,6 +537,12 @@ const struct frr_yang_module_info frr_isisd_info = {
                                .modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify,
                        },
                },
+               {
+                       .xpath = "/frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear",
+                       .cbs = {
+                               .modify = isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify,
+                       }
+               },
                {
                        .xpath = "/frr-isisd:isis/instance/mpls/ldp-sync",
                        .cbs = {
@@ -818,6 +824,36 @@ const struct frr_yang_module_info frr_isisd_info = {
                                .modify = lib_interface_isis_multi_topology_ipv6_dstsrc_modify,
                        },
                },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute",
+                       .cbs = {
+                               .cli_show = cli_show_ip_isis_ti_lfa,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable",
+                       .cbs = {
+                               .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection",
+                       .cbs = {
+                               .modify = lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable",
+                       .cbs = {
+                               .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection",
+                       .cbs = {
+                               .modify = lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify,
+                       }
+               },
                {
                        .xpath = "/frr-interface:lib/interface/state/frr-isisd:isis",
                        .cbs = {
index 8a6d24b845854a14e89b4a56327721820e41ef69..fb843131d9fe943ab6da24b679d4669b4500f235 100644 (file)
@@ -206,6 +206,8 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_sid_value_modify(
        struct nb_cb_modify_args *args);
 int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_modify(
        struct nb_cb_modify_args *args);
+int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
+       struct nb_cb_modify_args *args);
 int isis_instance_mpls_ldp_sync_destroy(struct nb_cb_destroy_args *args);
 int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args);
 int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args);
@@ -256,6 +258,14 @@ int lib_interface_isis_multi_topology_ipv6_dstsrc_modify(
 int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args);
 int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args);
 int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args);
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify(
+       struct nb_cb_modify_args *args);
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
+       struct nb_cb_modify_args *args);
 struct yang_data *
 lib_interface_state_isis_get_elem(struct nb_cb_get_elem_args *args);
 const void *lib_interface_state_isis_adjacencies_adjacency_get_next(
@@ -432,6 +442,8 @@ void cli_show_ip_isis_mt_ipv6_mgmt(struct vty *vty, struct lyd_node *dnode,
                                   bool show_defaults);
 void cli_show_ip_isis_mt_ipv6_dstsrc(struct vty *vty, struct lyd_node *dnode,
                                     bool show_defaults);
+void cli_show_ip_isis_ti_lfa(struct vty *vty, struct lyd_node *dnode,
+                            bool show_defaults);
 void cli_show_ip_isis_circ_type(struct vty *vty, struct lyd_node *dnode,
                                bool show_defaults);
 void cli_show_ip_isis_network_type(struct vty *vty, struct lyd_node *dnode,
index 6edbc2956ae73796eb5150a6f8b6e19c03ca2612..6cb7d32c25dd52784d38e43ff4cbec4af827ea0a 100644 (file)
@@ -43,6 +43,7 @@
 #include "isisd/isis_csm.h"
 #include "isisd/isis_adjacency.h"
 #include "isisd/isis_spf.h"
+#include "isisd/isis_spf_private.h"
 #include "isisd/isis_te.h"
 #include "isisd/isis_memory.h"
 #include "isisd/isis_mt.h"
@@ -85,15 +86,13 @@ int isis_instance_destroy(struct nb_cb_destroy_args *args)
        if (args->event != NB_EV_APPLY)
                return NB_OK;
        area = nb_running_unset_entry(args->dnode);
-
        vrf_id = area->isis->vrf_id;
 
-       isis_area_destroy(area);
-
        /* remove ldp-sync config */
        if (vrf_id == VRF_DEFAULT)
                isis_ldp_sync_gbl_exit(true);
 
+       isis_area_destroy(area);
        return NB_OK;
 }
 
@@ -1838,6 +1837,23 @@ int isis_instance_segment_routing_prefix_sid_map_prefix_sid_last_hop_behavior_mo
        return NB_OK;
 }
 
+/*
+ * XPath: /frr-isisd:isis/instance/segment-routing/prefix-sid-map/prefix-sid/n-flag-clear
+ */
+int isis_instance_segment_routing_prefix_sid_map_prefix_sid_n_flag_clear_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct sr_prefix_cfg *pcfg;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       pcfg = nb_running_get_entry(args->dnode, NULL, true);
+       pcfg->n_flag_clear = yang_dnode_get_bool(args->dnode, NULL);
+
+       return NB_OK;
+}
+
 /*
  * XPath: /frr-isisd:isis/instance/mpls/ldp-sync
  */
@@ -1847,18 +1863,29 @@ int isis_instance_mpls_ldp_sync_create(struct nb_cb_create_args *args)
        struct listnode *node;
        struct isis_circuit *circuit;
        struct interface *ifp;
-       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
-       struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+       struct vrf *vrf;
+       struct isis *isis;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
-               if (isis == NULL)
+               area = nb_running_get_entry(args->dnode, NULL, false);
+               if (area == NULL || area->isis == NULL)
                        return NB_ERR_VALIDATION;
+
+               if (area->isis->vrf_id != VRF_DEFAULT) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "LDP-Sync only runs on Default VRF");
+                       return NB_ERR_VALIDATION;
+               }
                break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
                break;
        case NB_EV_APPLY:
+               area = nb_running_get_entry(args->dnode, NULL, true);
+               isis = area->isis;
+               vrf = vrf_lookup_by_id(isis->vrf_id);
+
                /* register with opaque client to recv LDP-IGP Sync msgs */
                zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
                zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
@@ -1906,19 +1933,29 @@ int isis_instance_mpls_ldp_sync_holddown_modify(struct nb_cb_modify_args *args)
        struct listnode *node;
        struct isis_circuit *circuit;
        struct interface *ifp;
-       struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
+       struct vrf *vrf;
        uint16_t holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
-       struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+       struct isis *isis;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
-               if (isis == NULL)
+               area = nb_running_get_entry(args->dnode, NULL, false);
+               if (area == NULL || area->isis == NULL)
+                       return NB_ERR_VALIDATION;
+
+               if (area->isis->vrf_id != VRF_DEFAULT) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "LDP-Sync only runs on Default VRF");
                        return NB_ERR_VALIDATION;
+               }
                break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
                break;
        case NB_EV_APPLY:
+               area = nb_running_get_entry(args->dnode, NULL, true);
+               isis = area->isis;
+               vrf = vrf_lookup_by_id(isis->vrf_id);
                holddown = yang_dnode_get_uint16(args->dnode, NULL);
 
                if (holddown == LDP_IGP_SYNC_HOLDDOWN_DEFAULT)
@@ -2056,7 +2093,6 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
        struct interface *ifp;
        struct vrf *vrf;
        const char *area_tag, *ifname, *vrfname;
-       struct isis *isis = NULL;
 
        if (args->event == NB_EV_VALIDATE) {
                /* libyang doesn't like relative paths across module boundaries
@@ -2072,11 +2108,7 @@ int lib_interface_isis_area_tag_modify(struct nb_cb_modify_args *args)
                if (!ifp)
                        return NB_OK;
 
-               isis = isis_lookup_by_vrfid(ifp->vrf_id);
-               if (isis == NULL)
-                       return NB_ERR_VALIDATION;
-
-               circuit = circuit_lookup_by_ifp(ifp, isis->init_circ_list);
+               circuit = circuit_scan_by_ifp(ifp);
                area_tag = yang_dnode_get_string(args->dnode, NULL);
                if (circuit && circuit->area && circuit->area->area_tag
                    && strcmp(circuit->area->area_tag, area_tag)) {
@@ -2116,11 +2148,11 @@ int lib_interface_isis_vrf_modify(struct nb_cb_modify_args *args)
 
                vrf_name = yang_dnode_get_string(args->dnode, NULL);
                circuit = circuit_scan_by_ifp(ifp);
-               if (circuit && circuit->area && circuit->area->isis
-                   && strcmp(circuit->area->isis->name, vrf_name)) {
+               if (circuit && circuit->area && circuit->isis
+                   && strcmp(circuit->isis->name, vrf_name)) {
                        snprintf(args->errmsg, args->errmsg_len,
                                 "ISIS circuit is already defined on vrf  %s",
-                                circuit->area->isis->name);
+                                circuit->isis->name);
                        return NB_ERR_VALIDATION;
                }
        }
@@ -2778,23 +2810,31 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
        struct isis_circuit *circuit;
        struct ldp_sync_info *ldp_sync_info;
        bool ldp_sync_enable;
-       struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+       struct isis *isis;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
-               if (isis == NULL)
+               circuit = nb_running_get_entry(args->dnode, NULL, false);
+               if (circuit == NULL || circuit->area == NULL)
                        return NB_ERR_VALIDATION;
-               break;
 
+               if (circuit->isis->vrf_id != VRF_DEFAULT) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "LDP-Sync only runs on Default VRF");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
                break;
        case NB_EV_APPLY:
                circuit = nb_running_get_entry(args->dnode, NULL, true);
                ldp_sync_enable = yang_dnode_get_bool(args->dnode, NULL);
+               isis = circuit->isis;
 
                if (circuit->ldp_sync_info == NULL)
                        isis_ldp_sync_if_init(circuit, isis);
+               assert(circuit->ldp_sync_info != NULL);
                ldp_sync_info = circuit->ldp_sync_info;
 
                if (ldp_sync_enable) {
@@ -2821,8 +2861,7 @@ int lib_interface_isis_mpls_ldp_sync_modify(struct nb_cb_modify_args *args)
                        SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
                        ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT;
                        ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
-                       THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-                       ldp_sync_info->t_holddown = NULL;
+                       THREAD_OFF(ldp_sync_info->t_holddown);
                        isis_ldp_sync_set_if_metric(circuit, true);
                }
                break;
@@ -2838,23 +2877,31 @@ int lib_interface_isis_mpls_holddown_modify(struct nb_cb_modify_args *args)
        struct isis_circuit *circuit;
        struct ldp_sync_info *ldp_sync_info;
        uint16_t holddown;
-       struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+       struct isis *isis;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
-               if (isis == NULL)
+               circuit = nb_running_get_entry(args->dnode, NULL, false);
+               if (circuit == NULL || circuit->area == NULL)
                        return NB_ERR_VALIDATION;
-               break;
 
+               if (circuit->isis->vrf_id != VRF_DEFAULT) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "LDP-Sync only runs on Default VRF");
+                       return NB_ERR_VALIDATION;
+               }
+               break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
                break;
        case NB_EV_APPLY:
                circuit = nb_running_get_entry(args->dnode, NULL, true);
                holddown = yang_dnode_get_uint16(args->dnode, NULL);
+               isis = circuit->isis;
 
                if (circuit->ldp_sync_info == NULL)
                        isis_ldp_sync_if_init(circuit, isis);
+               assert(circuit->ldp_sync_info != NULL);
                ldp_sync_info = circuit->ldp_sync_info;
 
                SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN);
@@ -2868,22 +2915,27 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
 {
        struct isis_circuit *circuit;
        struct ldp_sync_info *ldp_sync_info;
-       struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
+       struct isis *isis;
 
        switch (args->event) {
        case NB_EV_VALIDATE:
-               if (isis == NULL)
-                       return NB_ERR_VALIDATION;
-               circuit = nb_running_get_entry(args->dnode, NULL, true);
-               if (circuit->ldp_sync_info == NULL)
+               circuit = nb_running_get_entry(args->dnode, NULL, false);
+               if (circuit == NULL || circuit->ldp_sync_info == NULL
+                   || circuit->area == NULL)
                        return NB_ERR_VALIDATION;
 
+               if (circuit->isis->vrf_id != VRF_DEFAULT) {
+                       snprintf(args->errmsg, args->errmsg_len,
+                                "LDP-Sync only runs on Default VRF");
+                       return NB_ERR_VALIDATION;
+               }
                break;
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
                break;
        case NB_EV_APPLY:
                circuit = nb_running_get_entry(args->dnode, NULL, true);
+               isis = circuit->isis;
                ldp_sync_info = circuit->ldp_sync_info;
                UNSET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_HOLDDOWN);
 
@@ -2894,5 +2946,108 @@ int lib_interface_isis_mpls_holddown_destroy(struct nb_cb_destroy_args *args)
                        ldp_sync_info->holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
                break;
        }
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/enable
+ */
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = nb_running_get_entry(args->dnode, NULL, true);
+       circuit->tilfa_protection[0] = yang_dnode_get_bool(args->dnode, NULL);
+       if (circuit->tilfa_protection[0])
+               circuit->area->lfa_protected_links[0]++;
+       else {
+               assert(circuit->area->lfa_protected_links[0] > 0);
+               circuit->area->lfa_protected_links[0]--;
+       }
+
+       area = circuit->area;
+       lsp_regenerate_schedule(area, area->is_type, 0);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-1/ti-lfa/node-protection
+ */
+int lib_interface_isis_fast_reroute_level_1_ti_lfa_node_protection_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = nb_running_get_entry(args->dnode, NULL, true);
+       circuit->tilfa_node_protection[0] =
+               yang_dnode_get_bool(args->dnode, NULL);
+
+       area = circuit->area;
+       lsp_regenerate_schedule(area, area->is_type, 0);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/enable
+ */
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_enable_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = nb_running_get_entry(args->dnode, NULL, true);
+       circuit->tilfa_protection[1] = yang_dnode_get_bool(args->dnode, NULL);
+       if (circuit->tilfa_protection[1])
+               circuit->area->lfa_protected_links[1]++;
+       else {
+               assert(circuit->area->lfa_protected_links[1] > 0);
+               circuit->area->lfa_protected_links[1]--;
+       }
+
+       area = circuit->area;
+       lsp_regenerate_schedule(area, area->is_type, 0);
+
+       return NB_OK;
+}
+
+/*
+ * XPath:
+ * /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-2/ti-lfa/node-protection
+ */
+int lib_interface_isis_fast_reroute_level_2_ti_lfa_node_protection_modify(
+       struct nb_cb_modify_args *args)
+{
+       struct isis_area *area;
+       struct isis_circuit *circuit;
+
+       if (args->event != NB_EV_APPLY)
+               return NB_OK;
+
+       circuit = nb_running_get_entry(args->dnode, NULL, true);
+       circuit->tilfa_node_protection[1] =
+               yang_dnode_get_bool(args->dnode, NULL);
+
+       area = circuit->area;
+       lsp_regenerate_schedule(area, area->is_type, 0);
+
        return NB_OK;
 }
index 43b9f6685e51b237d3733be27c2a879dce350197..72de5d6543fa3625eba453721a1845da9897d592 100644 (file)
@@ -76,8 +76,7 @@ static int ack_lsp(struct isis_lsp_hdr *hdr, struct isis_circuit *circuit,
        lenp = stream_get_endp(circuit->snd_stream);
 
        stream_putw(circuit->snd_stream, 0); /* PDU length  */
-       stream_put(circuit->snd_stream, circuit->area->isis->sysid,
-                  ISIS_SYS_ID_LEN);
+       stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN);
        stream_putc(circuit->snd_stream, circuit->idx);
        stream_putc(circuit->snd_stream, 9);  /* code */
        stream_putc(circuit->snd_stream, 16); /* len */
@@ -143,8 +142,8 @@ static int process_p2p_hello(struct iih_info *iih)
                }
 
                if (tw_adj->neighbor_set
-                   && (memcmp(tw_adj->neighbor_id,
-                              iih->circuit->area->isis->sysid, ISIS_SYS_ID_LEN)
+                   && (memcmp(tw_adj->neighbor_id, iih->circuit->isis->sysid,
+                              ISIS_SYS_ID_LEN)
                        || tw_adj->neighbor_circuit_id
                                   != (uint32_t)iih->circuit->idx)) {
 
@@ -206,7 +205,7 @@ static int process_p2p_hello(struct iih_info *iih)
                                      adj);
 
        /* lets take care of the expiry */
-       THREAD_TIMER_OFF(adj->t_expire);
+       thread_cancel(&adj->t_expire);
        thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
                         &adj->t_expire);
 
@@ -498,7 +497,7 @@ static int process_lan_hello(struct iih_info *iih)
                                      adj);
 
        /* lets take care of the expiry */
-       THREAD_TIMER_OFF(adj->t_expire);
+       thread_cancel(&adj->t_expire);
        thread_add_timer(master, isis_adj_expire, adj, (long)adj->hold_time,
                         &adj->t_expire);
 
@@ -728,7 +727,7 @@ static int process_hello(uint8_t pdu_type, struct isis_circuit *circuit,
                goto out;
        }
 
-       if (!memcmp(iih.sys_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN)) {
+       if (!memcmp(iih.sys_id, circuit->isis->sysid, ISIS_SYS_ID_LEN)) {
                zlog_warn(
                        "ISIS-Adj (%s): Received IIH with own sysid - discard",
                        circuit->area->area_tag);
@@ -1044,7 +1043,7 @@ dontcheckadj:
                                ack_lsp(&hdr, circuit, level);
                        goto out; /* FIXME: do we need a purge? */
                } else {
-                       if (memcmp(hdr.lsp_id, circuit->area->isis->sysid,
+                       if (memcmp(hdr.lsp_id, circuit->isis->sysid,
                                   ISIS_SYS_ID_LEN)) {
                                /* LSP by some other system -> do 7.3.16.4 b) */
                                /* 7.3.16.4 b) 1)  */
@@ -1139,8 +1138,7 @@ dontcheckadj:
        }
        /* 7.3.15.1 c) - If this is our own lsp and we don't have it initiate a
         * purge */
-       if (memcmp(hdr.lsp_id, circuit->area->isis->sysid, ISIS_SYS_ID_LEN)
-           == 0) {
+       if (memcmp(hdr.lsp_id, circuit->isis->sysid, ISIS_SYS_ID_LEN) == 0) {
                if (!lsp) {
                        /* 7.3.16.4: initiate a purge */
                        lsp_purge_non_exist(level, &hdr, circuit->area);
@@ -1427,7 +1425,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
             entry = entry->next) {
                struct isis_lsp *lsp =
                        lsp_search(&circuit->area->lspdb[level - 1], entry->id);
-               bool own_lsp = !memcmp(entry->id, circuit->area->isis->sysid,
+               bool own_lsp = !memcmp(entry->id, circuit->isis->sysid,
                                       ISIS_SYS_ID_LEN);
                if (lsp) {
                        /* 7.3.15.2 b) 1) is this LSP newer */
@@ -1468,7 +1466,7 @@ static int process_snp(uint8_t pdu_type, struct isis_circuit *circuit,
                         * insert it and set SSN on it */
                        if (entry->rem_lifetime && entry->checksum
                            && entry->seqno
-                           && memcmp(entry->id, circuit->area->isis->sysid,
+                           && memcmp(entry->id, circuit->isis->sysid,
                                      ISIS_SYS_ID_LEN)) {
                                struct isis_lsp *lsp0 = NULL;
 
@@ -1679,11 +1677,11 @@ int isis_handle_pdu(struct isis_circuit *circuit, uint8_t *ssnpa)
        if (pdu_type != FS_LINK_STATE /* FS PDU doesn't contain max area addr
                                         field */
            && max_area_addrs != 0
-           && max_area_addrs != circuit->area->isis->max_area_addrs) {
+           && max_area_addrs != circuit->isis->max_area_addrs) {
                flog_err(
                        EC_ISIS_PACKET,
                        "maximumAreaAddressesMismatch: maximumAreaAdresses in a received PDU %hhu while the parameter for this IS is %u",
-                       max_area_addrs, circuit->area->isis->max_area_addrs);
+                       max_area_addrs, circuit->isis->max_area_addrs);
                circuit->max_area_addr_mismatches++;
 #ifndef FABRICD
                /* send northbound notification */
@@ -1792,8 +1790,7 @@ static void put_hello_hdr(struct isis_circuit *circuit, int level,
        fill_fixed_hdr(pdu_type, circuit->snd_stream);
 
        stream_putc(circuit->snd_stream, circuit->is_type);
-       stream_put(circuit->snd_stream, circuit->area->isis->sysid,
-                  ISIS_SYS_ID_LEN);
+       stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN);
 
        uint32_t holdtime = circuit->hello_multiplier[level - 1]
                            * circuit->hello_interval[level - 1];
@@ -1990,7 +1987,7 @@ static void _send_hello_sched(struct isis_circuit *circuit,
                if (thread_timer_remain_msec(*threadp) < (unsigned long)delay)
                        return;
 
-               thread_cancel(*threadp);
+               thread_cancel(threadp);
        }
 
        thread_add_timer_msec(master, send_hello_cb,
@@ -2064,8 +2061,7 @@ int send_csnp(struct isis_circuit *circuit, int level)
        size_t len_pointer = stream_get_endp(circuit->snd_stream);
 
        stream_putw(circuit->snd_stream, 0);
-       stream_put(circuit->snd_stream, circuit->area->isis->sysid,
-                  ISIS_SYS_ID_LEN);
+       stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN);
        /* with zero circuit id - ref 9.10, 9.11 */
        stream_putc(circuit->snd_stream, 0);
 
@@ -2242,8 +2238,7 @@ static int send_psnp(int level, struct isis_circuit *circuit)
 
        size_t len_pointer = stream_get_endp(circuit->snd_stream);
        stream_putw(circuit->snd_stream, 0); /* length is filled in later */
-       stream_put(circuit->snd_stream, circuit->area->isis->sysid,
-                  ISIS_SYS_ID_LEN);
+       stream_put(circuit->snd_stream, circuit->isis->sysid, ISIS_SYS_ID_LEN);
        stream_putc(circuit->snd_stream, circuit->idx);
 
        struct isis_passwd *passwd = (level == ISIS_LEVEL1)
index 44422ff6641ae9c0b09c6fa21dc7437dd5164292..e6c7a734bdcc47ea30688443bf186cf2e29eba17 100644 (file)
@@ -231,11 +231,8 @@ void isis_redist_add(struct isis *isis, int type, struct prefix *p,
        int level;
        struct isis_redist *redist;
 
-       char debug_buf[BUFSIZ];
-       prefix2str(p, debug_buf, sizeof(debug_buf));
-
-       zlog_debug("%s: New route %s from %s: distance %d.", __func__,
-                  debug_buf, zebra_route_string(type), distance);
+       zlog_debug("%s: New route %pFX from %s: distance %d.", __func__, p,
+                  zebra_route_string(type), distance);
 
        if (!ei_table) {
                zlog_warn("%s: External information table not initialized.",
@@ -282,10 +279,7 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
        int level;
        struct isis_redist *redist;
 
-       char debug_buf[BUFSIZ];
-       prefix2str(p, debug_buf, sizeof(debug_buf));
-
-       zlog_debug("%s: Removing route %s from %s.", __func__, debug_buf,
+       zlog_debug("%s: Removing route %pFX from %s.", __func__, p,
                   zebra_route_string(type));
 
        if (is_default_prefix(p)
@@ -307,11 +301,9 @@ void isis_redist_delete(struct isis *isis, int type, struct prefix *p,
 
        ei_node = srcdest_rnode_lookup(ei_table, p, src_p);
        if (!ei_node || !ei_node->info) {
-               char buf[BUFSIZ];
-               prefix2str(p, buf, sizeof(buf));
                zlog_warn(
-                       "%s: Got a delete for %s route %s, but that route was never added.",
-                       __func__, zebra_route_string(type), buf);
+                       "%s: Got a delete for %s route %pFX, but that route was never added.",
+                       __func__, zebra_route_string(type), p);
                if (ei_node)
                        route_unlock_node(ei_node);
                return;
index fa0657255529e5b593926e09d77d1e9bf9599445..d664a6f8962545c55eb25ed384b57d8137140c44 100644 (file)
@@ -71,13 +71,13 @@ static struct isis_nexthop *isis_nexthop_create(int family, union g_addr *ip,
        nexthop->family = family;
        nexthop->ifindex = ifindex;
        nexthop->ip = *ip;
-       isis_sr_nexthop_reset(&nexthop->sr);
 
        return nexthop;
 }
 
-static void isis_nexthop_delete(struct isis_nexthop *nexthop)
+void isis_nexthop_delete(struct isis_nexthop *nexthop)
 {
+       XFREE(MTYPE_ISIS_NEXTHOP_LABELS, nexthop->label_stack);
        XFREE(MTYPE_ISIS_NEXTHOP, nexthop);
 }
 
@@ -115,8 +115,9 @@ static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family,
        return NULL;
 }
 
-static void adjinfo2nexthop(int family, struct list *nexthops,
-                           struct isis_adjacency *adj)
+void adjinfo2nexthop(int family, struct list *nexthops,
+                    struct isis_adjacency *adj, struct isis_sr_psid_info *sr,
+                    struct mpls_label_stack *label_stack)
 {
        struct isis_nexthop *nh;
        union g_addr ip = {};
@@ -132,6 +133,9 @@ static void adjinfo2nexthop(int family, struct list *nexthops,
                                        AF_INET, &ip,
                                        adj->circuit->interface->ifindex);
                                memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
+                               if (sr)
+                                       nh->sr = *sr;
+                               nh->label_stack = label_stack;
                                listnode_add(nexthops, nh);
                                break;
                        }
@@ -147,6 +151,9 @@ static void adjinfo2nexthop(int family, struct list *nexthops,
                                        AF_INET6, &ip,
                                        adj->circuit->interface->ifindex);
                                memcpy(nh->sysid, adj->sysid, sizeof(nh->sysid));
+                               if (sr)
+                                       nh->sr = *sr;
+                               nh->label_stack = label_stack;
                                listnode_add(nexthops, nh);
                                break;
                        }
@@ -160,21 +167,23 @@ static void adjinfo2nexthop(int family, struct list *nexthops,
 }
 
 static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
-                                         const uint8_t *sysid)
+                                         const uint8_t *sysid,
+                                         struct isis_sr_psid_info *sr,
+                                         struct mpls_label_stack *label_stack)
 {
        struct isis_nexthop *nh;
 
        nh = XCALLOC(MTYPE_ISIS_NEXTHOP, sizeof(struct isis_nexthop));
        memcpy(nh->sysid, sysid, sizeof(nh->sysid));
-       isis_sr_nexthop_reset(&nh->sr);
+       nh->sr = *sr;
+       nh->label_stack = label_stack;
        listnode_add(rinfo->nexthops, nh);
 }
 
-static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
-                                                  struct prefix_ipv6 *src_p,
-                                                  uint32_t cost,
-                                                  uint32_t depth,
-                                                  struct list *adjacencies)
+static struct isis_route_info *
+isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
+                   uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
+                   struct list *adjacencies)
 {
        struct isis_route_info *rinfo;
        struct isis_vertex_adj *vadj;
@@ -186,13 +195,16 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
        for (ALL_LIST_ELEMENTS_RO(adjacencies, node, vadj)) {
                struct isis_spf_adj *sadj = vadj->sadj;
                struct isis_adjacency *adj = sadj->adj;
+               struct isis_sr_psid_info *sr = &vadj->sr;
+               struct mpls_label_stack *label_stack = vadj->label_stack;
 
                /*
                 * Create dummy nexthops when running SPF on a testing
                 * environment.
                 */
                if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) {
-                       isis_route_add_dummy_nexthops(rinfo, sadj->id);
+                       isis_route_add_dummy_nexthops(rinfo, sadj->id, sr,
+                                                     label_stack);
                        continue;
                }
 
@@ -219,11 +231,13 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
                                 prefix->family);
                        exit(1);
                }
-               adjinfo2nexthop(prefix->family, rinfo->nexthops, adj);
+               adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, sr,
+                               label_stack);
        }
 
        rinfo->cost = cost;
        rinfo->depth = depth;
+       rinfo->sr = *sr;
 
        return rinfo;
 }
@@ -239,12 +253,34 @@ static void isis_route_info_delete(struct isis_route_info *route_info)
        XFREE(MTYPE_ISIS_ROUTE_INFO, route_info);
 }
 
+void isis_route_node_cleanup(struct route_table *table, struct route_node *node)
+{
+       if (node->info)
+               isis_route_info_delete(node->info);
+}
+
+static bool isis_sr_psid_info_same(struct isis_sr_psid_info *new,
+                                  struct isis_sr_psid_info *old)
+{
+       if (new->present != old->present)
+               return false;
+
+       if (new->label != old->label)
+               return false;
+
+       if (new->sid.flags != old->sid.flags
+           || new->sid.value != old->sid.value)
+               return false;
+
+       return true;
+}
+
 static int isis_route_info_same(struct isis_route_info *new,
                                struct isis_route_info *old, char *buf,
                                size_t buf_size)
 {
        struct listnode *node;
-       struct isis_nexthop *nexthop;
+       struct isis_nexthop *new_nh, *old_nh;
 
        if (new->cost != old->cost) {
                if (buf)
@@ -260,6 +296,12 @@ static int isis_route_info_same(struct isis_route_info *new,
                return 0;
        }
 
+       if (!isis_sr_psid_info_same(&new->sr, &old->sr)) {
+               if (buf)
+                       snprintf(buf, buf_size, "SR input label");
+               return 0;
+       }
+
        if (new->nexthops->count != old->nexthops->count) {
                if (buf)
                        snprintf(buf, buf_size, "nhops num (old: %u, new: %u)",
@@ -267,14 +309,20 @@ static int isis_route_info_same(struct isis_route_info *new,
                return 0;
        }
 
-       for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, nexthop)) {
-               if (!nexthoplookup(old->nexthops, nexthop->family, &nexthop->ip,
-                                  nexthop->ifindex)) {
+       for (ALL_LIST_ELEMENTS_RO(new->nexthops, node, new_nh)) {
+               old_nh = nexthoplookup(old->nexthops, new_nh->family,
+                                      &new_nh->ip, new_nh->ifindex);
+               if (!old_nh) {
                        if (buf)
                                snprintf(buf, buf_size,
                                         "new nhop"); /* TODO: print nhop */
                        return 0;
                }
+               if (!isis_sr_psid_info_same(&new_nh->sr, &old_nh->sr)) {
+                       if (buf)
+                               snprintf(buf, buf_size, "nhop SR label");
+                       return 0;
+               }
        }
 
        /* only the resync flag needs to be checked */
@@ -288,57 +336,53 @@ static int isis_route_info_same(struct isis_route_info *new,
        return 1;
 }
 
-struct isis_route_info *isis_route_create(struct prefix *prefix,
-                                         struct prefix_ipv6 *src_p,
-                                         uint32_t cost,
-                                         uint32_t depth,
-                                         struct list *adjacencies,
-                                         struct isis_area *area,
-                                         struct route_table *table)
+struct isis_route_info *
+isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p,
+                 uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
+                 struct list *adjacencies, struct isis_area *area,
+                 struct route_table *table)
 {
        struct route_node *route_node;
        struct isis_route_info *rinfo_new, *rinfo_old, *route_info = NULL;
-       char buff[PREFIX2STR_BUFFER];
        char change_buf[64];
 
-       /* for debugs */
-       prefix2str(prefix, buff, sizeof(buff));
-
        if (!table)
                return NULL;
 
-       rinfo_new = isis_route_info_new(prefix, src_p, cost,
-                                       depth, adjacencies);
+       rinfo_new = isis_route_info_new(prefix, src_p, cost, depth, sr,
+                                       adjacencies);
        route_node = srcdest_rnode_get(table, prefix, src_p);
 
        rinfo_old = route_node->info;
        if (!rinfo_old) {
                if (IS_DEBUG_RTE_EVENTS)
-                       zlog_debug("ISIS-Rte (%s) route created: %s",
-                                  area->area_tag, buff);
+                       zlog_debug("ISIS-Rte (%s) route created: %pFX",
+                                  area->area_tag, prefix);
                route_info = rinfo_new;
                UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
        } else {
                route_unlock_node(route_node);
 #ifdef EXTREME_DEBUG
                if (IS_DEBUG_RTE_EVENTS)
-                       zlog_debug("ISIS-Rte (%s) route already exists: %s",
-                                  area->area_tag, buff);
+                       zlog_debug("ISIS-Rte (%s) route already exists: %pFX",
+                                  area->area_tag, prefix);
 #endif /* EXTREME_DEBUG */
                if (isis_route_info_same(rinfo_new, rinfo_old, change_buf,
                                         sizeof(change_buf))) {
 #ifdef EXTREME_DEBUG
                        if (IS_DEBUG_RTE_EVENTS)
-                               zlog_debug("ISIS-Rte (%s) route unchanged: %s",
-                                          area->area_tag, buff);
+                               zlog_debug(
+                                       "ISIS-Rte (%s) route unchanged: %pFX",
+                                       area->area_tag, prefix);
 #endif /* EXTREME_DEBUG */
                        isis_route_info_delete(rinfo_new);
                        route_info = rinfo_old;
                } else {
                        if (IS_DEBUG_RTE_EVENTS)
                                zlog_debug(
-                                       "ISIS-Rte (%s): route changed: %s, change: %s",
-                                       area->area_tag, buff, change_buf);
+                                       "ISIS-Rte (%s): route changed: %pFX, change: %s",
+                                       area->area_tag, prefix, change_buf);
+                       rinfo_new->sr_previous = rinfo_old->sr;
                        isis_route_info_delete(rinfo_old);
                        route_info = rinfo_new;
                        UNSET_FLAG(route_info->flag,
@@ -394,7 +438,25 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix,
                if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
                        return;
 
-               isis_zebra_route_add_route(area->isis, prefix, src_p, route_info);
+               /*
+                * Explicitly uninstall previous Prefix-SID label if it has
+                * changed or was removed.
+                */
+               if (route_info->sr_previous.present
+                   && (!route_info->sr.present
+                       || route_info->sr_previous.label
+                                  != route_info->sr.label))
+                       isis_zebra_prefix_sid_uninstall(
+                               area, prefix, route_info,
+                               &route_info->sr_previous);
+
+               /* Install route. */
+               isis_zebra_route_add_route(area->isis, prefix, src_p,
+                                          route_info);
+               /* Install/reinstall Prefix-SID label. */
+               if (route_info->sr.present)
+                       isis_zebra_prefix_sid_install(area, prefix, route_info,
+                                                     &route_info->sr);
                hook_call(isis_route_update_hook, area, prefix, route_info);
 
                SET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
@@ -403,7 +465,13 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix,
                if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
                        return;
 
-               isis_zebra_route_del_route(area->isis, prefix, src_p, route_info);
+               /* Uninstall Prefix-SID label. */
+               if (route_info->sr.present)
+                       isis_zebra_prefix_sid_uninstall(
+                               area, prefix, route_info, &route_info->sr);
+               /* Uninstall route. */
+               isis_zebra_route_del_route(area->isis, prefix, src_p,
+                                          route_info);
                hook_call(isis_route_update_hook, area, prefix, route_info);
 
                UNSET_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
@@ -412,6 +480,7 @@ static void isis_route_update(struct isis_area *area, struct prefix *prefix,
 
 static void _isis_route_verify_table(struct isis_area *area,
                                     struct route_table *table,
+                                    struct route_table *table_backup,
                                     struct route_table **tables)
 {
        struct route_node *rnode, *drnode;
@@ -433,6 +502,19 @@ static void _isis_route_verify_table(struct isis_area *area,
                                       (const struct prefix **)&dst_p,
                                       (const struct prefix **)&src_p);
 
+               /* Link primary route to backup route. */
+               if (table_backup) {
+                       struct route_node *rnode_bck;
+
+                       rnode_bck = srcdest_rnode_lookup(table_backup, dst_p,
+                                                        src_p);
+                       if (rnode_bck) {
+                               rinfo->backup = rnode_bck->info;
+                               UNSET_FLAG(rinfo->flag,
+                                          ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
+                       }
+               }
+
 #ifdef EXTREME_DEBUG
                if (IS_DEBUG_RTE_EVENTS) {
                        srcdest2str(dst_p, src_p, buff, sizeof(buff));
@@ -490,9 +572,10 @@ static void _isis_route_verify_table(struct isis_area *area,
        }
 }
 
-void isis_route_verify_table(struct isis_area *area, struct route_table *table)
+void isis_route_verify_table(struct isis_area *area, struct route_table *table,
+                            struct route_table *table_backup)
 {
-       _isis_route_verify_table(area, table, NULL);
+       _isis_route_verify_table(area, table, table_backup, NULL);
 }
 
 /* Function to validate route tables for L1L2 areas. In this case we can't use
@@ -507,9 +590,13 @@ void isis_route_verify_table(struct isis_area *area, struct route_table *table)
  * to the RIB with different zebra route types and let RIB handle this? */
 void isis_route_verify_merge(struct isis_area *area,
                             struct route_table *level1_table,
-                            struct route_table *level2_table)
+                            struct route_table *level1_table_backup,
+                            struct route_table *level2_table,
+                            struct route_table *level2_table_backup)
 {
-       struct route_table *tables[] = { level1_table, level2_table };
+       struct route_table *tables[] = {level1_table, level2_table};
+       struct route_table *tables_backup[] = {level1_table_backup,
+                                              level2_table_backup};
        struct route_table *merge;
        struct route_node *rnode, *mrnode;
 
@@ -519,6 +606,8 @@ void isis_route_verify_merge(struct isis_area *area,
                for (rnode = route_top(tables[level - 1]); rnode;
                     rnode = srcdest_route_next(rnode)) {
                        struct isis_route_info *rinfo = rnode->info;
+                       struct route_node *rnode_bck;
+
                        if (!rinfo)
                                continue;
 
@@ -528,6 +617,16 @@ void isis_route_verify_merge(struct isis_area *area,
                        srcdest_rnode_prefixes(rnode,
                                               (const struct prefix **)&prefix,
                                               (const struct prefix **)&src_p);
+
+                       /* Link primary route to backup route. */
+                       rnode_bck = srcdest_rnode_lookup(
+                               tables_backup[level - 1], prefix, src_p);
+                       if (rnode_bck) {
+                               rinfo->backup = rnode_bck->info;
+                               UNSET_FLAG(rinfo->flag,
+                                          ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
+                       }
+
                        mrnode = srcdest_rnode_get(merge, prefix, src_p);
                        struct isis_route_info *mrinfo = mrnode->info;
                        if (mrinfo) {
@@ -566,7 +665,7 @@ void isis_route_verify_merge(struct isis_area *area,
                }
        }
 
-       _isis_route_verify_table(area, merge, tables);
+       _isis_route_verify_table(area, merge, NULL, tables);
        route_table_finish(merge);
 }
 
@@ -580,6 +679,14 @@ void isis_route_invalidate_table(struct isis_area *area,
                        continue;
                rinfo = rode->info;
 
+               if (rinfo->backup) {
+                       rinfo->backup = NULL;
+                       /*
+                        * For now, always force routes that have backup
+                        * nexthops to be reinstalled.
+                        */
+                       UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED);
+               }
                UNSET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ACTIVE);
        }
 }
index 0356668d7e6cd6ed8e072fd34c07c1f3f1838d6d..b5e4aed6cccbe6df6e968d5dc8a8ceeee4df2445 100644 (file)
@@ -32,7 +32,8 @@ struct isis_nexthop {
        int family;
        union g_addr ip;
        uint8_t sysid[ISIS_SYS_ID_LEN];
-       struct sr_nexthop_info sr;
+       struct isis_sr_psid_info sr;
+       struct mpls_label_stack *label_stack;
 };
 
 struct isis_route_info {
@@ -42,7 +43,10 @@ struct isis_route_info {
        uint8_t flag;
        uint32_t cost;
        uint32_t depth;
+       struct isis_sr_psid_info sr;
+       struct isis_sr_psid_info sr_previous;
        struct list *nexthops;
+       struct isis_route_info *backup;
 };
 
 DECLARE_HOOK(isis_route_update_hook,
@@ -50,26 +54,34 @@ DECLARE_HOOK(isis_route_update_hook,
              struct isis_route_info *route_info),
             (area, prefix, route_info))
 
-struct isis_route_info *isis_route_create(struct prefix *prefix,
-                                         struct prefix_ipv6 *src_p,
-                                         uint32_t cost,
-                                         uint32_t depth,
-                                         struct list *adjacencies,
-                                         struct isis_area *area,
-                                         struct route_table *table);
+void isis_nexthop_delete(struct isis_nexthop *nexthop);
+void adjinfo2nexthop(int family, struct list *nexthops,
+                    struct isis_adjacency *adj, struct isis_sr_psid_info *sr,
+                    struct mpls_label_stack *label_stack);
+struct isis_route_info *
+isis_route_create(struct prefix *prefix, struct prefix_ipv6 *src_p,
+                 uint32_t cost, uint32_t depth, struct isis_sr_psid_info *sr,
+                 struct list *adjacencies, struct isis_area *area,
+                 struct route_table *table);
 
 /* Walk the given table and install new routes to zebra and remove old ones.
  * route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
-void isis_route_verify_table(struct isis_area *area,
-                            struct route_table *table);
+void isis_route_verify_table(struct isis_area *area, struct route_table *table,
+                            struct route_table *table_backup);
 
 /* Same as isis_route_verify_table, but merge L1 and L2 routes before */
 void isis_route_verify_merge(struct isis_area *area,
                             struct route_table *level1_table,
-                            struct route_table *level2_table);
+                            struct route_table *level1_table_backup,
+                            struct route_table *level2_table,
+                            struct route_table *level2_table_backup);
 
 /* Unset ISIS_ROUTE_FLAG_ACTIVE on all routes. Used before running spf. */
 void isis_route_invalidate_table(struct isis_area *area,
                                 struct route_table *table);
 
+/* Cleanup route node when freeing routing table. */
+void isis_route_node_cleanup(struct route_table *table,
+                            struct route_node *node);
+
 #endif /* _ZEBRA_ISIS_ROUTE_H */
index dd0a6ec824ff344562e2174d1c1c02eaf2d428e3..690ea9f1a5e8979fd68c0478a71c563f75b861f0 100644 (file)
@@ -138,7 +138,7 @@ static void remove_excess_adjs(struct list *adjs)
        return;
 }
 
-static const char *vtype2string(enum vertextype vtype)
+const char *vtype2string(enum vertextype vtype)
 {
        switch (vtype) {
        case VTYPE_PSEUDO_IS:
@@ -167,7 +167,7 @@ static const char *vtype2string(enum vertextype vtype)
        return NULL; /* Not reached */
 }
 
-const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
+const char *vid2string(const struct isis_vertex *vertex, char *buff, int size)
 {
        if (VTYPE_IS(vertex->type) || VTYPE_ES(vertex->type)) {
                const char *hostname = print_sys_hostname(vertex->N.id);
@@ -176,9 +176,8 @@ const char *vid2string(struct isis_vertex *vertex, char *buff, int size)
        }
 
        if (VTYPE_IP(vertex->type)) {
-               srcdest2str(&vertex->N.ip.dest,
-                           &vertex->N.ip.src,
-                           buff, size);
+               srcdest2str(&vertex->N.ip.p.dest, &vertex->N.ip.p.src, buff,
+                           size);
                return buff;
        }
 
@@ -215,13 +214,33 @@ static struct isis_vertex *isis_vertex_new(struct isis_spftree *spftree,
        return vertex;
 }
 
-static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_vertex *vertex,
-                                                  struct isis_spf_adj *sadj)
+static struct isis_vertex_adj *isis_vertex_adj_add(struct isis_spftree *spftree,
+                                                  struct isis_vertex *vertex,
+                                                  struct isis_spf_adj *sadj,
+                                                  struct isis_prefix_sid *psid)
 {
        struct isis_vertex_adj *vadj;
 
        vadj = XCALLOC(MTYPE_ISIS_VERTEX_ADJ, sizeof(*vadj));
        vadj->sadj = sadj;
+       if (psid) {
+               if (vertex->N.ip.sr.present
+                   && vertex->N.ip.sr.sid.value != psid->value)
+                       zlog_warn(
+                               "ISIS-SPF: ignoring different Prefix-SID for route %pFX",
+                               &vertex->N.ip.p.dest);
+               else {
+                       bool last_hop;
+
+                       last_hop = (vertex->depth == 2);
+                       vadj->sr.sid = *psid;
+                       vadj->sr.label = sr_prefix_out_label(
+                               spftree->lspdb, vertex->N.ip.p.dest.family,
+                               psid, sadj->id, last_hop);
+                       if (vadj->sr.label != MPLS_INVALID_LABEL)
+                               vadj->sr.present = true;
+               }
+       }
        listnode_add(vertex->Adj_N, vadj);
 
        return vadj;
@@ -286,6 +305,9 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area,
        isis_vertex_queue_init(&tree->tents, "IS-IS SPF tents", true);
        isis_vertex_queue_init(&tree->paths, "IS-IS SPF paths", false);
        tree->route_table = srcdest_table_init();
+       tree->route_table->cleanup = isis_route_node_cleanup;
+       tree->route_table_backup = srcdest_table_init();
+       tree->route_table_backup->cleanup = isis_route_node_cleanup;
        tree->area = area;
        tree->lspdb = lspdb;
        tree->sadj_list = list_new();
@@ -300,16 +322,26 @@ struct isis_spftree *isis_spftree_new(struct isis_area *area,
        tree->tree_id = tree_id;
        tree->family = (tree->tree_id == SPFTREE_IPV4) ? AF_INET : AF_INET6;
        tree->flags = flags;
+       if (tree->type == SPF_TYPE_TI_LFA) {
+               isis_spf_node_list_init(&tree->lfa.p_space);
+               isis_spf_node_list_init(&tree->lfa.q_space);
+       }
 
        return tree;
 }
 
 void isis_spftree_del(struct isis_spftree *spftree)
 {
+       if (spftree->type == SPF_TYPE_TI_LFA) {
+               isis_spf_node_list_clear(&spftree->lfa.q_space);
+               isis_spf_node_list_clear(&spftree->lfa.p_space);
+       }
+       isis_spf_node_list_clear(&spftree->adj_nodes);
        list_delete(&spftree->sadj_list);
        isis_vertex_queue_free(&spftree->tents);
        isis_vertex_queue_free(&spftree->paths);
        route_table_finish(spftree->route_table);
+       route_table_finish(spftree->route_table_backup);
        spftree->route_table = NULL;
 
        XFREE(MTYPE_ISIS_SPFTREE, spftree);
@@ -389,8 +421,8 @@ static int spf_adj_state_change(struct isis_adjacency *adj)
  * Find the system LSP: returns the LSP in our LSP database
  * associated with the given system ID.
  */
-static struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb,
-                                            uint8_t *sysid)
+struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb,
+                                     const uint8_t *sysid)
 {
        struct isis_lsp *lsp;
        uint8_t lspid[ISIS_SYS_ID_LEN + 2];
@@ -421,7 +453,7 @@ static struct isis_vertex *isis_spf_add_root(struct isis_spftree *spftree)
        isis_vertex_queue_append(&spftree->paths, vertex);
 
 #ifdef EXTREME_DEBUG
-       zlog_debug("ISIS-Spf: added this IS %s %s depth %d dist %d to PATHS",
+       zlog_debug("ISIS-SPF: added this IS %s %s depth %d dist %d to PATHS",
                   vtype2string(vertex->type),
                   vid2string(vertex, buff, sizeof(buff)), vertex->depth,
                   vertex->d_N);
@@ -453,11 +485,10 @@ static void vertex_update_firsthops(struct isis_vertex *vertex,
 /*
  * Add a vertex to TENT sorted by cost and by vertextype on tie break situation
  */
-static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
-                                            enum vertextype vtype, void *id,
-                                            uint32_t cost, int depth,
-                                            struct isis_spf_adj *sadj,
-                                            struct isis_vertex *parent)
+static struct isis_vertex *
+isis_spf_add2tent(struct isis_spftree *spftree, enum vertextype vtype, void *id,
+                 uint32_t cost, int depth, struct isis_spf_adj *sadj,
+                 struct isis_prefix_sid *psid, struct isis_vertex *parent)
 {
        struct isis_vertex *vertex;
        struct listnode *node;
@@ -483,6 +514,16 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
        vertex = isis_vertex_new(spftree, id, vtype);
        vertex->d_N = cost;
        vertex->depth = depth;
+       if (VTYPE_IP(vtype) && psid) {
+               bool local;
+
+               local = (vertex->depth == 1);
+               vertex->N.ip.sr.sid = *psid;
+               vertex->N.ip.sr.label =
+                       sr_prefix_in_label(spftree->area, psid, local);
+               if (vertex->N.ip.sr.label != MPLS_INVALID_LABEL)
+                       vertex->N.ip.sr.present = true;
+       }
 
        if (parent) {
                listnode_add(vertex->parents, parent);
@@ -495,14 +536,15 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
                struct isis_vertex_adj *parent_vadj;
 
                for (ALL_LIST_ELEMENTS_RO(parent->Adj_N, node, parent_vadj))
-                       isis_vertex_adj_add(vertex, parent_vadj->sadj);
+                       isis_vertex_adj_add(spftree, vertex, parent_vadj->sadj,
+                                           psid);
        } else if (sadj) {
-               isis_vertex_adj_add(vertex, sadj);
+               isis_vertex_adj_add(spftree, vertex, sadj, psid);
        }
 
 #ifdef EXTREME_DEBUG
        zlog_debug(
-               "ISIS-Spf: add to TENT %s %s %s depth %d dist %d adjcount %d",
+               "ISIS-SPF: add to TENT %s %s %s depth %d dist %d adjcount %d",
                print_sys_hostname(vertex->N.id), vtype2string(vertex->type),
                vid2string(vertex, buff, sizeof(buff)), vertex->depth,
                vertex->d_N, listcount(vertex->Adj_N));
@@ -515,6 +557,7 @@ static struct isis_vertex *isis_spf_add2tent(struct isis_spftree *spftree,
 static void isis_spf_add_local(struct isis_spftree *spftree,
                               enum vertextype vtype, void *id,
                               struct isis_spf_adj *sadj, uint32_t cost,
+                              struct isis_prefix_sid *psid,
                               struct isis_vertex *parent)
 {
        struct isis_vertex *vertex;
@@ -525,7 +568,8 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
                /* C.2.5   c) */
                if (vertex->d_N == cost) {
                        if (sadj)
-                               isis_vertex_adj_add(vertex, sadj);
+                               isis_vertex_adj_add(spftree, vertex, sadj,
+                                                   psid);
                        /*       d) */
                        if (!CHECK_FLAG(spftree->flags,
                                        F_SPFTREE_NO_ADJACENCIES)
@@ -545,13 +589,13 @@ static void isis_spf_add_local(struct isis_spftree *spftree,
                }
        }
 
-       isis_spf_add2tent(spftree, vtype, id, cost, 1, sadj, parent);
+       isis_spf_add2tent(spftree, vtype, id, cost, 1, sadj, psid, parent);
        return;
 }
 
 static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
                      void *id, uint32_t dist, uint16_t depth,
-                     struct isis_vertex *parent)
+                     struct isis_prefix_sid *psid, struct isis_vertex *parent)
 {
        struct isis_vertex *vertex;
 #ifdef EXTREME_DEBUG
@@ -588,7 +632,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
        if (vertex) {
 #ifdef EXTREME_DEBUG
                zlog_debug(
-                       "ISIS-Spf: process_N %s %s %s dist %d already found from PATH",
+                       "ISIS-SPF: process_N %s %s %s dist %d already found from PATH",
                        print_sys_hostname(vertex->N.id), vtype2string(vtype),
                        vid2string(vertex, buff, sizeof(buff)), dist);
 #endif /* EXTREME_DEBUG */
@@ -602,7 +646,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
 /*        1) */
 #ifdef EXTREME_DEBUG
                zlog_debug(
-                       "ISIS-Spf: process_N %s %s %s dist %d parent %s adjcount %d",
+                       "ISIS-SPF: process_N %s %s %s dist %d parent %s adjcount %d",
                        print_sys_hostname(vertex->N.id), vtype2string(vtype),
                        vid2string(vertex, buff, sizeof(buff)), dist,
                        (parent ? print_sys_hostname(parent->N.id) : "null"),
@@ -615,8 +659,9 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
                                                  parent_vadj))
                                if (!isis_vertex_adj_exists(spftree, vertex,
                                                            parent_vadj->sadj))
-                                       isis_vertex_adj_add(vertex,
-                                                           parent_vadj->sadj);
+                                       isis_vertex_adj_add(spftree, vertex,
+                                                           parent_vadj->sadj,
+                                                           psid);
                        if (CHECK_FLAG(spftree->flags,
                                       F_SPFTREE_HOPCOUNT_METRIC))
                                vertex_update_firsthops(vertex, parent);
@@ -638,12 +683,12 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
        }
 
 #ifdef EXTREME_DEBUG
-       zlog_debug("ISIS-Spf: process_N add2tent %s %s dist %d parent %s",
+       zlog_debug("ISIS-SPF: process_N add2tent %s %s dist %d parent %s",
                   print_sys_hostname(id), vtype2string(vtype), dist,
                   (parent ? print_sys_hostname(parent->N.id) : "null"));
 #endif /* EXTREME_DEBUG */
 
-       isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, parent);
+       isis_spf_add2tent(spftree, vtype, id, dist, depth, NULL, psid, parent);
        return;
 }
 
@@ -662,6 +707,14 @@ static int isis_spf_process_lsp(struct isis_spftree *spftree,
        static const uint8_t null_sysid[ISIS_SYS_ID_LEN];
        struct isis_mt_router_info *mt_router_info = NULL;
        struct prefix_pair ip_info;
+       bool has_valid_psid;
+
+       if (isis_lfa_excise_node_check(spftree, lsp->hdr.lsp_id)) {
+               if (IS_DEBUG_TILFA)
+                       zlog_debug("ISIS-LFA: excising node %s",
+                                  print_sys_hostname(lsp->hdr.lsp_id));
+               return ISIS_OK;
+       }
 
        if (!lsp->tlvs)
                return ISIS_OK;
@@ -691,7 +744,7 @@ lspfragloop:
        }
 
 #ifdef EXTREME_DEBUG
-       zlog_debug("ISIS-Spf: process_lsp %s",
+       zlog_debug("ISIS-SPF: process_lsp %s",
                   print_sys_hostname(lsp->hdr.lsp_id));
 #endif /* EXTREME_DEBUG */
 
@@ -719,7 +772,7 @@ lspfragloop:
                                          LSP_PSEUDO_ID(r->id)
                                                  ? VTYPE_PSEUDO_IS
                                                  : VTYPE_NONPSEUDO_IS,
-                                         (void *)r->id, dist, depth + 1,
+                                         (void *)r->id, dist, depth + 1, NULL,
                                          parent);
                        }
                }
@@ -753,7 +806,8 @@ lspfragloop:
                        process_N(spftree,
                                  LSP_PSEUDO_ID(er->id) ? VTYPE_PSEUDO_TE_IS
                                                        : VTYPE_NONPSEUDO_TE_IS,
-                                 (void *)er->id, dist, depth + 1, parent);
+                                 (void *)er->id, dist, depth + 1, NULL,
+                                 parent);
                }
        }
 
@@ -778,7 +832,7 @@ lspfragloop:
                                ip_info.dest.u.prefix4 = r->prefix.prefix;
                                ip_info.dest.prefixlen = r->prefix.prefixlen;
                                process_N(spftree, vtype, &ip_info,
-                                         dist, depth + 1, parent);
+                                         dist, depth + 1, NULL, parent);
                        }
                }
        }
@@ -803,8 +857,34 @@ lspfragloop:
                        dist = cost + r->metric;
                        ip_info.dest.u.prefix4 = r->prefix.prefix;
                        ip_info.dest.prefixlen = r->prefix.prefixlen;
-                       process_N(spftree, VTYPE_IPREACH_TE, &ip_info,
-                                 dist, depth + 1, parent);
+
+                       /* Parse list of Prefix-SID subTLVs */
+                       has_valid_psid = false;
+                       if (r->subtlvs) {
+                               for (struct isis_item *i =
+                                            r->subtlvs->prefix_sids.head;
+                                    i; i = i->next) {
+                                       struct isis_prefix_sid *psid =
+                                               (struct isis_prefix_sid *)i;
+
+                                       if (psid->algorithm != SR_ALGORITHM_SPF)
+                                               continue;
+
+                                       has_valid_psid = true;
+                                       process_N(spftree, VTYPE_IPREACH_TE,
+                                                 &ip_info, dist, depth + 1,
+                                                 psid, parent);
+                                       /*
+                                        * Stop the Prefix-SID iteration since
+                                        * we only support the SPF algorithm for
+                                        * now.
+                                        */
+                                       break;
+                               }
+                       }
+                       if (!has_valid_psid)
+                               process_N(spftree, VTYPE_IPREACH_TE, &ip_info,
+                                         dist, depth + 1, NULL, parent);
                }
        }
 
@@ -845,8 +925,34 @@ lspfragloop:
                                }
                                ip_info.src = *r->subtlvs->source_prefix;
                        }
-                       process_N(spftree, vtype, &ip_info, dist,
-                                 depth + 1, parent);
+
+                       /* Parse list of Prefix-SID subTLVs */
+                       has_valid_psid = false;
+                       if (r->subtlvs) {
+                               for (struct isis_item *i =
+                                            r->subtlvs->prefix_sids.head;
+                                    i; i = i->next) {
+                                       struct isis_prefix_sid *psid =
+                                               (struct isis_prefix_sid *)i;
+
+                                       if (psid->algorithm != SR_ALGORITHM_SPF)
+                                               continue;
+
+                                       has_valid_psid = true;
+                                       process_N(spftree, vtype, &ip_info,
+                                                 dist, depth + 1, psid,
+                                                 parent);
+                                       /*
+                                        * Stop the Prefix-SID iteration since
+                                        * we only support the SPF algorithm for
+                                        * now.
+                                        */
+                                       break;
+                               }
+                       }
+                       if (!has_valid_psid)
+                               process_N(spftree, vtype, &ip_info, dist,
+                                         depth + 1, NULL, parent);
                }
        }
 
@@ -902,6 +1008,7 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix,
        struct isis_vertex *parent = args->parent;
        struct prefix_pair ip_info;
        enum vertextype vtype;
+       bool has_valid_psid = false;
 
        if (external)
                return LSP_ITER_CONTINUE;
@@ -916,7 +1023,30 @@ static int isis_spf_preload_tent_ip_reach_cb(const struct prefix *prefix,
        else
                vtype = VTYPE_IP6REACH_INTERNAL;
 
-       isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, parent);
+       /* Parse list of Prefix-SID subTLVs */
+       if (subtlvs) {
+               for (struct isis_item *i = subtlvs->prefix_sids.head; i;
+                    i = i->next) {
+                       struct isis_prefix_sid *psid =
+                               (struct isis_prefix_sid *)i;
+
+                       if (psid->algorithm != SR_ALGORITHM_SPF)
+                               continue;
+
+                       has_valid_psid = true;
+                       isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0,
+                                          psid, parent);
+
+                       /*
+                        * Stop the Prefix-SID iteration since we only support
+                        * the SPF algorithm for now.
+                        */
+                       break;
+               }
+       }
+       if (!has_valid_psid)
+               isis_spf_add_local(spftree, vtype, &ip_info, NULL, 0, NULL,
+                                  parent);
 
        return LSP_ITER_CONTINUE;
 }
@@ -940,8 +1070,22 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree,
 
        /* Iterate over adjacencies. */
        for (ALL_LIST_ELEMENTS_RO(spftree->sadj_list, node, sadj)) {
+               const uint8_t *adj_id;
                uint32_t metric;
 
+               if (CHECK_FLAG(sadj->flags, F_ISIS_SPF_ADJ_BROADCAST))
+                       adj_id = sadj->lan.desig_is_id;
+               else
+                       adj_id = sadj->id;
+
+               if (isis_lfa_excise_adj_check(spftree, adj_id)) {
+                       if (IS_DEBUG_TILFA)
+                               zlog_debug("ISIS-SPF: excising adjacency %s",
+                                          isis_format_id(sadj->id,
+                                                         ISIS_SYS_ID_LEN + 1));
+                       continue;
+               }
+
                metric = CHECK_FLAG(spftree->flags, F_SPFTREE_HOPCOUNT_METRIC)
                                 ? 1
                                 : sadj->metric;
@@ -951,7 +1095,8 @@ static void isis_spf_preload_tent(struct isis_spftree *spftree,
                                                      F_ISIS_SPF_ADJ_OLDMETRIC)
                                                   ? VTYPE_NONPSEUDO_IS
                                                   : VTYPE_NONPSEUDO_TE_IS,
-                                          sadj->id, sadj, metric, parent);
+                                          sadj->id, sadj, metric, NULL,
+                                          parent);
                } else if (sadj->lan.lsp_pseudo) {
                        isis_spf_process_lsp(spftree, sadj->lan.lsp_pseudo,
                                             metric, 0, spftree->sysid, parent);
@@ -1076,6 +1221,17 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree,
        /* Add adjacency to the list. */
        listnode_add(spftree->sadj_list, sadj);
 
+       if (!LSP_PSEUDO_ID(id)) {
+               struct isis_spf_node *node;
+
+               node = isis_spf_node_find(&spftree->adj_nodes, id);
+               if (!node)
+                       node = isis_spf_node_new(&spftree->adj_nodes, id);
+               if (node->best_metric == 0 || sadj->metric < node->best_metric)
+                       node->best_metric = sadj->metric;
+               listnode_add(node->adjacencies, sadj);
+       }
+
        /* Parse pseudonode LSP too. */
        if (LSP_PSEUDO_ID(id)) {
                uint8_t lspid[ISIS_SYS_ID_LEN + 2];
@@ -1086,7 +1242,7 @@ static void spf_adj_list_parse_tlv(struct isis_spftree *spftree,
                lsp_pseudo = lsp_search(spftree->lspdb, lspid);
                if (lsp_pseudo == NULL || lsp_pseudo->hdr.rem_lifetime == 0) {
                        zlog_warn(
-                               "ISIS-Spf: No LSP found from root to L%d DR %s",
+                               "ISIS-SPF: No LSP found from root to L%d DR %s",
                                spftree->level, rawlspid_print(id));
                        return;
                }
@@ -1177,39 +1333,26 @@ static void isis_spf_build_adj_list(struct isis_spftree *spftree,
 static void add_to_paths(struct isis_spftree *spftree,
                         struct isis_vertex *vertex)
 {
+#ifdef EXTREME_DEBUG
        char buff[VID2STR_BUFFER];
+#endif /* EXTREME_DEBUG */
 
        if (isis_find_vertex(&spftree->paths, &vertex->N, vertex->type))
                return;
        isis_vertex_queue_append(&spftree->paths, vertex);
 
 #ifdef EXTREME_DEBUG
-       zlog_debug("ISIS-Spf: added %s %s %s depth %d dist %d to PATHS",
+       zlog_debug("ISIS-SPF: added %s %s %s depth %d dist %d to PATHS",
                   print_sys_hostname(vertex->N.id), vtype2string(vertex->type),
                   vid2string(vertex, buff, sizeof(buff)), vertex->depth,
                   vertex->d_N);
 #endif /* EXTREME_DEBUG */
-
-       if (VTYPE_IP(vertex->type)
-           && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ROUTES)) {
-               if (listcount(vertex->Adj_N) > 0)
-                       isis_route_create(&vertex->N.ip.dest, &vertex->N.ip.src,
-                                         vertex->d_N, vertex->depth,
-                                         vertex->Adj_N, spftree->area,
-                                         spftree->route_table);
-               else if (IS_DEBUG_SPF_EVENTS)
-                       zlog_debug(
-                               "ISIS-Spf: no adjacencies do not install route for %s depth %d dist %d",
-                               vid2string(vertex, buff, sizeof(buff)),
-                               vertex->depth, vertex->d_N);
-       }
-
-       return;
 }
 
 static void init_spt(struct isis_spftree *spftree, int mtid)
 {
        /* Clear data from previous run. */
+       isis_spf_node_list_clear(&spftree->adj_nodes);
        list_delete_all_node(spftree->sadj_list);
        isis_vertex_queue_clear(&spftree->tents);
        isis_vertex_queue_clear(&spftree->paths);
@@ -1217,18 +1360,73 @@ static void init_spt(struct isis_spftree *spftree, int mtid)
        spftree->mtid = mtid;
 }
 
+static void spf_path_process(struct isis_spftree *spftree,
+                            struct isis_vertex *vertex)
+{
+       struct isis_area *area = spftree->area;
+       char buff[VID2STR_BUFFER];
+
+       if (VTYPE_IS(vertex->type)
+           && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES)) {
+               if (listcount(vertex->Adj_N) > 0) {
+                       if (spftree->type == SPF_TYPE_TI_LFA) {
+                               struct isis_adjacency *adj;
+
+                               if (isis_lfa_check(spftree, vertex) != 0)
+                                       return;
+
+                               adj = isis_adj_find(area, spftree->level,
+                                                   vertex->N.id);
+                               if (adj)
+                                       sr_adj_sid_add_single(
+                                               adj, spftree->family, true,
+                                               vertex->Adj_N);
+                       }
+               } else if (IS_DEBUG_SPF_EVENTS)
+                       zlog_debug(
+                               "ISIS-SPF: no adjacencies, do not install backup Adj-SID for %s depth %d dist %d",
+                               vid2string(vertex, buff, sizeof(buff)),
+                               vertex->depth, vertex->d_N);
+       }
+
+       if (VTYPE_IP(vertex->type)
+           && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ROUTES)) {
+               if (vertex->depth == 1 || listcount(vertex->Adj_N) > 0) {
+                       struct route_table *route_table;
+
+                       if (spftree->type == SPF_TYPE_TI_LFA) {
+                               if (isis_lfa_check(spftree, vertex) != 0)
+                                       return;
+                               route_table = spftree->lfa.old.spftree
+                                                     ->route_table_backup;
+                       } else
+                               route_table = spftree->route_table;
+
+                       isis_route_create(&vertex->N.ip.p.dest,
+                                         &vertex->N.ip.p.src, vertex->d_N,
+                                         vertex->depth, &vertex->N.ip.sr,
+                                         vertex->Adj_N, area, route_table);
+               } else if (IS_DEBUG_SPF_EVENTS)
+                       zlog_debug(
+                               "ISIS-SPF: no adjacencies, do not install route for %s depth %d dist %d",
+                               vid2string(vertex, buff, sizeof(buff)),
+                               vertex->depth, vertex->d_N);
+       }
+}
+
 static void isis_spf_loop(struct isis_spftree *spftree,
                          uint8_t *root_sysid)
 {
        struct isis_vertex *vertex;
        struct isis_lsp *lsp;
+       struct listnode *node;
 
        while (isis_vertex_queue_count(&spftree->tents)) {
                vertex = isis_vertex_queue_pop(&spftree->tents);
 
 #ifdef EXTREME_DEBUG
                zlog_debug(
-                       "ISIS-Spf: get TENT node %s %s depth %d dist %d to PATHS",
+                       "ISIS-SPF: get TENT node %s %s depth %d dist %d to PATHS",
                        print_sys_hostname(vertex->N.id),
                        vtype2string(vertex->type), vertex->depth, vertex->d_N);
 #endif /* EXTREME_DEBUG */
@@ -1239,7 +1437,7 @@ static void isis_spf_loop(struct isis_spftree *spftree,
 
                lsp = lsp_for_vertex(spftree, vertex);
                if (!lsp) {
-                       zlog_warn("ISIS-Spf: No LSP found for %s",
+                       zlog_warn("ISIS-SPF: No LSP found for %s",
                                  isis_format_id(vertex->N.id,
                                                 sizeof(vertex->N.id)));
                        continue;
@@ -1248,6 +1446,23 @@ static void isis_spf_loop(struct isis_spftree *spftree,
                isis_spf_process_lsp(spftree, lsp, vertex->d_N, vertex->depth,
                                     root_sysid, vertex);
        }
+
+       /* Generate routes once the SPT is formed. */
+       for (ALL_QUEUE_ELEMENTS_RO(&spftree->paths, node, vertex)) {
+               /* New-style TLVs take precedence over the old-style TLVs. */
+               switch (vertex->type) {
+               case VTYPE_IPREACH_INTERNAL:
+               case VTYPE_IPREACH_EXTERNAL:
+                       if (isis_find_vertex(&spftree->paths, &vertex->N,
+                                            VTYPE_IPREACH_TE))
+                               continue;
+                       break;
+               default:
+                       break;
+               }
+
+               spf_path_process(spftree, vertex);
+       }
 }
 
 struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
@@ -1301,7 +1516,7 @@ void isis_run_spf(struct isis_spftree *spftree)
 
        root_lsp = isis_root_system_lsp(spftree->lspdb, spftree->sysid);
        if (root_lsp == NULL) {
-               zlog_err("ISIS-Spf: could not find own l%d LSP!",
+               zlog_err("ISIS-SPF: could not find own l%d LSP!",
                         spftree->level);
                return;
        }
@@ -1343,7 +1558,7 @@ void isis_run_spf(struct isis_spftree *spftree)
         */
        if (!isis_vertex_queue_count(&spftree->tents)
            && (IS_DEBUG_SPF_EVENTS)) {
-               zlog_warn("ISIS-Spf: TENT is empty SPF-root:%s",
+               zlog_warn("ISIS-SPF: TENT is empty SPF-root:%s",
                          print_sys_hostname(spftree->sysid));
        }
 
@@ -1356,28 +1571,48 @@ void isis_run_spf(struct isis_spftree *spftree)
                + (time_end.tv_usec - time_start.tv_usec);
 }
 
+static void isis_run_spf_with_protection(struct isis_area *area,
+                                        struct isis_spftree *spftree)
+{
+       /* Run forward SPF locally. */
+       memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN);
+       isis_run_spf(spftree);
+
+       /* Run LFA protection if configured. */
+       if (area->lfa_protected_links[spftree->level - 1] > 0)
+               isis_spf_run_lfa(area, spftree);
+}
+
 void isis_spf_verify_routes(struct isis_area *area, struct isis_spftree **trees)
 {
        if (area->is_type == IS_LEVEL_1) {
-               isis_route_verify_table(area, trees[0]->route_table);
+               isis_route_verify_table(area, trees[0]->route_table,
+                                       trees[0]->route_table_backup);
        } else if (area->is_type == IS_LEVEL_2) {
-               isis_route_verify_table(area, trees[1]->route_table);
+               isis_route_verify_table(area, trees[1]->route_table,
+                                       trees[1]->route_table_backup);
        } else {
                isis_route_verify_merge(area, trees[0]->route_table,
-                                       trees[1]->route_table);
+                                       trees[0]->route_table_backup,
+                                       trees[1]->route_table,
+                                       trees[1]->route_table_backup);
        }
 }
 
 void isis_spf_invalidate_routes(struct isis_spftree *tree)
 {
        isis_route_invalidate_table(tree->area, tree->route_table);
+
+       /* Delete backup routes. */
+       route_table_finish(tree->route_table_backup);
+       tree->route_table_backup = srcdest_table_init();
+       tree->route_table_backup->cleanup = isis_route_node_cleanup;
 }
 
 static int isis_run_spf_cb(struct thread *thread)
 {
        struct isis_spf_run *run = THREAD_ARG(thread);
        struct isis_area *area = run->area;
-       struct isis_spftree *spftree;
        int level = run->level;
 
        XFREE(MTYPE_ISIS_SPF_RUN, run);
@@ -1390,32 +1625,25 @@ static int isis_run_spf_cb(struct thread *thread)
                return ISIS_WARNING;
        }
 
+       isis_area_delete_backup_adj_sids(area, level);
        isis_area_invalidate_routes(area, level);
 
        if (IS_DEBUG_SPF_EVENTS)
-               zlog_debug("ISIS-Spf (%s) L%d SPF needed, periodic SPF",
+               zlog_debug("ISIS-SPF (%s) L%d SPF needed, periodic SPF",
                           area->area_tag, level);
 
-       if (area->ip_circuits) {
-               spftree = area->spftree[SPFTREE_IPV4][level - 1];
-               memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN);
-               isis_run_spf(spftree);
-       }
-       if (area->ipv6_circuits) {
-               spftree = area->spftree[SPFTREE_IPV6][level - 1];
-               memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN);
-               isis_run_spf(spftree);
-       }
-       if (area->ipv6_circuits && isis_area_ipv6_dstsrc_enabled(area)) {
-               spftree = area->spftree[SPFTREE_DSTSRC][level - 1];
-               memcpy(spftree->sysid, area->isis->sysid, ISIS_SYS_ID_LEN);
-               isis_run_spf(spftree);
-       }
+       if (area->ip_circuits)
+               isis_run_spf_with_protection(
+                       area, area->spftree[SPFTREE_IPV4][level - 1]);
+       if (area->ipv6_circuits)
+               isis_run_spf_with_protection(
+                       area, area->spftree[SPFTREE_IPV6][level - 1]);
+       if (area->ipv6_circuits && isis_area_ipv6_dstsrc_enabled(area))
+               isis_run_spf_with_protection(
+                       area, area->spftree[SPFTREE_DSTSRC][level - 1]);
 
        isis_area_verify_routes(area);
 
-       isis_area_verify_sr(area);
-
        /* walk all circuits and reset any spf specific flags */
        struct listnode *node;
        struct isis_circuit *circuit;
@@ -1452,7 +1680,7 @@ int _isis_spf_schedule(struct isis_area *area, int level,
 
        if (IS_DEBUG_SPF_EVENTS) {
                zlog_debug(
-                       "ISIS-Spf (%s) L%d SPF schedule called, lastrun %d sec ago Caller: %s %s:%d",
+                       "ISIS-SPF (%s) L%d SPF schedule called, lastrun %d sec ago Caller: %s %s:%d",
                        area->area_tag, level, diff, func, file, line);
        }
 
@@ -1487,7 +1715,7 @@ int _isis_spf_schedule(struct isis_area *area, int level,
 
                if (area->bfd_force_spf_refresh) {
                        zlog_debug(
-                               "ISIS-Spf (%s) L%d SPF scheduled immediately due to BFD 'down' message",
+                               "ISIS-SPF (%s) L%d SPF scheduled immediately due to BFD 'down' message",
                                area->area_tag, level);
                        area->bfd_force_spf_refresh = false;
                }
@@ -1499,7 +1727,7 @@ int _isis_spf_schedule(struct isis_area *area, int level,
                         timer, &area->spf_timer[level - 1]);
 
        if (IS_DEBUG_SPF_EVENTS)
-               zlog_debug("ISIS-Spf (%s) L%d SPF scheduled %ld sec from now",
+               zlog_debug("ISIS-SPF (%s) L%d SPF scheduled %ld sec from now",
                           area->area_tag, level, timer);
 
        return ISIS_OK;
@@ -1706,10 +1934,126 @@ DEFUN(show_isis_topology, show_isis_topology_cmd,
        return CMD_SUCCESS;
 }
 
-void isis_print_routes(struct vty *vty, struct isis_spftree *spftree)
+static void isis_print_route(struct ttable *tt, const struct prefix *prefix,
+                            struct isis_route_info *rinfo, bool prefix_sid,
+                            bool no_adjacencies)
 {
+       struct isis_nexthop *nexthop;
+       struct listnode *node;
+       bool first = true;
+       char buf_prefix[BUFSIZ];
+
+       (void)prefix2str(prefix, buf_prefix, sizeof(buf_prefix));
+       for (ALL_LIST_ELEMENTS_RO(rinfo->nexthops, node, nexthop)) {
+               struct interface *ifp;
+               char buf_iface[BUFSIZ];
+               char buf_nhop[BUFSIZ];
+
+               if (!no_adjacencies) {
+                       inet_ntop(nexthop->family, &nexthop->ip, buf_nhop,
+                                 sizeof(buf_nhop));
+                       ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT);
+                       if (ifp)
+                               strlcpy(buf_iface, ifp->name,
+                                       sizeof(buf_iface));
+                       else
+                               snprintf(buf_iface, sizeof(buf_iface),
+                                        "ifindex %u", nexthop->ifindex);
+               } else {
+                       strlcpy(buf_nhop, print_sys_hostname(nexthop->sysid),
+                               sizeof(buf_nhop));
+                       strlcpy(buf_iface, "-", sizeof(buf_iface));
+               }
+
+               if (prefix_sid) {
+                       char buf_sid[BUFSIZ] = {};
+                       char buf_lblop[BUFSIZ] = {};
+
+                       if (nexthop->sr.present) {
+                               snprintf(buf_sid, sizeof(buf_sid), "%u",
+                                        nexthop->sr.sid.value);
+                               sr_op2str(buf_lblop, sizeof(buf_lblop),
+                                         rinfo->sr.label, nexthop->sr.label);
+                       } else {
+                               strlcpy(buf_sid, "-", sizeof(buf_sid));
+                               strlcpy(buf_lblop, "-", sizeof(buf_lblop));
+                       }
+
+                       if (first) {
+                               ttable_add_row(tt, "%s|%u|%s|%s|%s|%s",
+                                              buf_prefix, rinfo->cost,
+                                              buf_iface, buf_nhop, buf_sid,
+                                              buf_lblop);
+                               first = false;
+                       } else
+                               ttable_add_row(tt, "||%s|%s|%s|%s", buf_iface,
+                                              buf_nhop, buf_sid, buf_lblop);
+               } else {
+                       char buf_labels[BUFSIZ] = {};
+
+                       if (nexthop->label_stack) {
+                               for (int i = 0;
+                                    i < nexthop->label_stack->num_labels;
+                                    i++) {
+                                       char buf_label[BUFSIZ];
+
+                                       label2str(
+                                               nexthop->label_stack->label[i],
+                                               buf_label, sizeof(buf_label));
+                                       if (i != 0)
+                                               strlcat(buf_labels, "/",
+                                                       sizeof(buf_labels));
+                                       strlcat(buf_labels, buf_label,
+                                               sizeof(buf_labels));
+                               }
+                       } else if (nexthop->sr.present)
+                               label2str(nexthop->sr.label, buf_labels,
+                                         sizeof(buf_labels));
+                       else
+                               strlcpy(buf_labels, "-", sizeof(buf_labels));
+
+                       if (first) {
+                               ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix,
+                                              rinfo->cost, buf_iface, buf_nhop,
+                                              buf_labels);
+                               first = false;
+                       } else
+                               ttable_add_row(tt, "||%s|%s|%s", buf_iface,
+                                              buf_nhop, buf_labels);
+               }
+       }
+       if (list_isempty(rinfo->nexthops)) {
+               if (prefix_sid) {
+                       char buf_sid[BUFSIZ] = {};
+                       char buf_lblop[BUFSIZ] = {};
+
+                       if (rinfo->sr.present) {
+                               snprintf(buf_sid, sizeof(buf_sid), "%u",
+                                        rinfo->sr.sid.value);
+                               sr_op2str(buf_lblop, sizeof(buf_lblop),
+                                         rinfo->sr.label,
+                                         MPLS_LABEL_IMPLICIT_NULL);
+                       } else {
+                               strlcpy(buf_sid, "-", sizeof(buf_sid));
+                               strlcpy(buf_lblop, "-", sizeof(buf_lblop));
+                       }
+
+                       ttable_add_row(tt, "%s|%u|%s|%s|%s|%s", buf_prefix,
+                                      rinfo->cost, "-", "-", buf_sid,
+                                      buf_lblop);
+               } else
+                       ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix,
+                                      rinfo->cost, "-", "-", "-");
+       }
+}
+
+void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
+                      bool prefix_sid, bool backup)
+{
+       struct route_table *route_table;
        struct ttable *tt;
        struct route_node *rn;
+       bool no_adjacencies = false;
        const char *tree_id_text = NULL;
 
        if (!spftree)
@@ -1735,65 +2079,28 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree)
 
        /* Prepare table. */
        tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
-       ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|Label(s)");
+       if (prefix_sid)
+               ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|SID|Label Op.");
+       else
+               ttable_add_row(tt, "Prefix|Metric|Interface|Nexthop|Label(s)");
        tt->style.cell.rpad = 2;
        tt->style.corner = '+';
        ttable_restyle(tt);
        ttable_rowseps(tt, 0, BOTTOM, true, '-');
 
-       for (rn = route_top(spftree->route_table); rn; rn = route_next(rn)) {
+       if (CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES))
+               no_adjacencies = true;
+
+       route_table =
+               (backup) ? spftree->route_table_backup : spftree->route_table;
+       for (rn = route_top(route_table); rn; rn = route_next(rn)) {
                struct isis_route_info *rinfo;
-               struct isis_nexthop *nexthop;
-               struct listnode *node;
-               bool first = true;
-               char buf_prefix[BUFSIZ];
 
                rinfo = rn->info;
                if (!rinfo)
                        continue;
 
-               (void)prefix2str(&rn->p, buf_prefix, sizeof(buf_prefix));
-               for (ALL_LIST_ELEMENTS_RO(rinfo->nexthops, node, nexthop)) {
-                       struct interface *ifp;
-                       char buf_iface[BUFSIZ];
-                       char buf_nhop[BUFSIZ];
-                       char buf_labels[BUFSIZ] = {};
-
-                       if (!CHECK_FLAG(spftree->flags,
-                                       F_SPFTREE_NO_ADJACENCIES)) {
-                               inet_ntop(nexthop->family, &nexthop->ip,
-                                         buf_nhop, sizeof(buf_nhop));
-                               ifp = if_lookup_by_index(nexthop->ifindex,
-                                                        VRF_DEFAULT);
-                               if (ifp)
-                                       strlcpy(buf_iface, ifp->name,
-                                               sizeof(buf_iface));
-                               else
-                                       snprintf(buf_iface, sizeof(buf_iface),
-                                                "ifindex %u",
-                                                nexthop->ifindex);
-                       } else {
-                               strlcpy(buf_nhop,
-                                       print_sys_hostname(nexthop->sysid),
-                                       sizeof(buf_nhop));
-                               strlcpy(buf_iface, "-", sizeof(buf_iface));
-                       }
-
-                       if (nexthop->sr.label != MPLS_INVALID_LABEL)
-                               label2str(nexthop->sr.label, buf_labels,
-                                         sizeof(buf_labels));
-                       else
-                               strlcpy(buf_labels, "-", sizeof(buf_labels));
-
-                       if (first) {
-                               ttable_add_row(tt, "%s|%u|%s|%s|%s", buf_prefix,
-                                              rinfo->cost, buf_iface, buf_nhop,
-                                              buf_labels);
-                               first = false;
-                       } else
-                               ttable_add_row(tt, "||%s|%s|%s", buf_iface,
-                                              buf_nhop, buf_labels);
-               }
+               isis_print_route(tt, &rn->p, rinfo, prefix_sid, no_adjacencies);
        }
 
        /* Dump the generated table. */
@@ -1808,7 +2115,8 @@ void isis_print_routes(struct vty *vty, struct isis_spftree *spftree)
 }
 
 static void show_isis_route_common(struct vty *vty, int levels,
-                                  struct isis *isis)
+                                  struct isis *isis, bool prefix_sid,
+                                  bool backup)
 {
        struct listnode *node;
        struct isis_area *area;
@@ -1827,17 +2135,20 @@ static void show_isis_route_common(struct vty *vty, int levels,
                        if (area->ip_circuits > 0) {
                                isis_print_routes(
                                        vty,
-                                       area->spftree[SPFTREE_IPV4][level - 1]);
+                                       area->spftree[SPFTREE_IPV4][level - 1],
+                                       prefix_sid, backup);
                        }
                        if (area->ipv6_circuits > 0) {
                                isis_print_routes(
                                        vty,
-                                       area->spftree[SPFTREE_IPV6][level - 1]);
+                                       area->spftree[SPFTREE_IPV6][level - 1],
+                                       prefix_sid, backup);
                        }
                        if (isis_area_ipv6_dstsrc_enabled(area)) {
                                isis_print_routes(vty,
                                                  area->spftree[SPFTREE_DSTSRC]
-                                                              [level - 1]);
+                                                              [level - 1],
+                                                 prefix_sid, backup);
                        }
                }
        }
@@ -1849,20 +2160,23 @@ DEFUN(show_isis_route, show_isis_route_cmd,
 #ifndef FABRICD
       " [<level-1|level-2>]"
 #endif
-      ,
+      " [<prefix-sid|backup>]",
       SHOW_STR PROTO_HELP VRF_FULL_CMD_HELP_STR
       "IS-IS routing table\n"
 #ifndef FABRICD
       "level-1 routes\n"
       "level-2 routes\n"
 #endif
-)
+      "Show Prefix-SID information\n"
+      "Show backup routes\n")
 {
        int levels;
        struct isis *isis;
        struct listnode *node;
        const char *vrf_name = VRF_DEFAULT_NAME;
        bool all_vrf = false;
+       bool prefix_sid = false;
+       bool backup = false;
        int idx = 0;
 
        if (argv_find(argv, argc, "level-1", &idx))
@@ -1878,15 +2192,22 @@ DEFUN(show_isis_route, show_isis_route_cmd,
        }
        ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf);
 
+       if (argv_find(argv, argc, "prefix-sid", &idx))
+               prefix_sid = true;
+       if (argv_find(argv, argc, "backup", &idx))
+               backup = true;
+
        if (vrf_name) {
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
-                               show_isis_route_common(vty, levels, isis);
+                               show_isis_route_common(vty, levels, isis,
+                                                      prefix_sid, backup);
                        return CMD_SUCCESS;
                }
                isis = isis_lookup_by_vrfname(vrf_name);
                if (isis != NULL)
-                       show_isis_route_common(vty, levels, isis);
+                       show_isis_route_common(vty, levels, isis, prefix_sid,
+                                              backup);
        }
 
        return CMD_SUCCESS;
index b2dc23496f3e356bd2572045896397539f0de636..15d3ff92727831265cd8a83ca2b4a7d619902714 100644 (file)
 #ifndef _ZEBRA_ISIS_SPF_H
 #define _ZEBRA_ISIS_SPF_H
 
+#include "isisd/isis_lfa.h"
+
 struct isis_spftree;
 
 enum spf_type {
        SPF_TYPE_FORWARD = 1,
        SPF_TYPE_REVERSE,
+       SPF_TYPE_TI_LFA,
 };
 
 struct isis_spf_adj {
@@ -56,17 +59,21 @@ void isis_spf_verify_routes(struct isis_area *area,
 void isis_spftree_del(struct isis_spftree *spftree);
 void spftree_area_init(struct isis_area *area);
 void spftree_area_del(struct isis_area *area);
+struct isis_lsp *isis_root_system_lsp(struct lspdb_head *lspdb,
+                                     const uint8_t *sysid);
 #define isis_spf_schedule(area, level) \
        _isis_spf_schedule((area), (level), __func__, \
                           __FILE__, __LINE__)
 int _isis_spf_schedule(struct isis_area *area, int level,
                       const char *func, const char *file, int line);
 void isis_print_spftree(struct vty *vty, struct isis_spftree *spftree);
-void isis_print_routes(struct vty *vty, struct isis_spftree *spftree);
+void isis_print_routes(struct vty *vty, struct isis_spftree *spftree,
+                      bool prefix_sid, bool backup);
 void isis_spf_init(void);
 void isis_spf_print(struct isis_spftree *spftree, struct vty *vty);
 void isis_run_spf(struct isis_spftree *spftree);
 struct isis_spftree *isis_run_hopcount_spf(struct isis_area *area,
                                           uint8_t *sysid,
                                           struct isis_spftree *spftree);
+
 #endif /* _ZEBRA_ISIS_SPF_H */
index 1e61bf0f4855d0c1f11a97154532057b53334e52..e999f965396925667b7a8ead19d8614d8b3da95e 100644 (file)
@@ -52,6 +52,7 @@ struct prefix_pair {
 
 struct isis_vertex_adj {
        struct isis_spf_adj *sadj;
+       struct isis_sr_psid_info sr;
        struct mpls_label_stack *label_stack;
 };
 
@@ -62,7 +63,10 @@ struct isis_vertex {
        enum vertextype type;
        union {
                uint8_t id[ISIS_SYS_ID_LEN + 1];
-               struct prefix_pair ip;
+               struct {
+                       struct prefix_pair p;
+                       struct isis_sr_psid_info sr;
+               } ip;
        } N;
        uint32_t d_N;     /* d(N) Distance from this IS      */
        uint16_t depth; /* The depth in the imaginary tree */
@@ -91,8 +95,8 @@ static unsigned isis_vertex_queue_hash_key(const void *vp)
        if (VTYPE_IP(vertex->type)) {
                uint32_t key;
 
-               key = prefix_hash_key(&vertex->N.ip.dest);
-               key = jhash_1word(prefix_hash_key(&vertex->N.ip.src), key);
+               key = prefix_hash_key(&vertex->N.ip.p.dest);
+               key = jhash_1word(prefix_hash_key(&vertex->N.ip.p.src), key);
                return key;
        }
 
@@ -108,11 +112,12 @@ static bool isis_vertex_queue_hash_cmp(const void *a, const void *b)
                return false;
 
        if (VTYPE_IP(va->type)) {
-               if (prefix_cmp(&va->N.ip.dest, &vb->N.ip.dest))
+               if (prefix_cmp(&va->N.ip.p.dest, &vb->N.ip.p.dest))
                        return false;
 
-               return prefix_cmp((const struct prefix *)&va->N.ip.src,
-                                 (const struct prefix *)&vb->N.ip.src) == 0;
+               return prefix_cmp((const struct prefix *)&va->N.ip.p.src,
+                                 (const struct prefix *)&vb->N.ip.p.src)
+                      == 0;
        }
 
        return memcmp(va->N.id, vb->N.id, ISIS_SYS_ID_LEN + 1) == 0;
@@ -306,8 +311,10 @@ struct isis_spftree {
        struct isis_vertex_queue paths; /* the SPT */
        struct isis_vertex_queue tents; /* TENT */
        struct route_table *route_table;
+       struct route_table *route_table_backup;
        struct lspdb_head *lspdb; /* link-state db */
        struct list *sadj_list;
+       struct isis_spf_nodes adj_nodes;
        struct isis_area *area;    /* back pointer to area */
        unsigned int runcount;     /* number of runs since uptime */
        time_t last_run_timestamp; /* last run timestamp as wall time for display */
@@ -320,7 +327,20 @@ struct isis_spftree {
        int family;
        int level;
        enum spf_tree_id tree_id;
-       bool hopcount_metric;
+       struct {
+               /* Original pre-failure local SPTs. */
+               struct {
+                       struct isis_spftree *spftree;
+                       struct isis_spftree *spftree_reverse;
+               } old;
+
+               /* Protected resource. */
+               struct lfa_protected_resource protected_resource;
+
+               /* P-space and Q-space. */
+               struct isis_spf_nodes p_space;
+               struct isis_spf_nodes q_space;
+       } lfa;
        uint8_t flags;
 };
 #define F_SPFTREE_HOPCOUNT_METRIC 0x01
@@ -336,7 +356,7 @@ static void isis_vertex_id_init(struct isis_vertex *vertex, const void *id,
        if (VTYPE_IS(vtype) || VTYPE_ES(vtype)) {
                memcpy(vertex->N.id, id, ISIS_SYS_ID_LEN + 1);
        } else if (VTYPE_IP(vtype)) {
-               memcpy(&vertex->N.ip, id, sizeof(vertex->N.ip));
+               memcpy(&vertex->N.ip.p, id, sizeof(vertex->N.ip.p));
        } else {
                flog_err(EC_LIB_DEVELOPMENT, "Unknown Vertex Type");
        }
@@ -373,6 +393,7 @@ static struct isis_lsp *lsp_for_vertex(struct isis_spftree *spftree,
 }
 
 #define VID2STR_BUFFER SRCDEST2STR_BUFFER
-const char *vid2string(struct isis_vertex *vertex, char *buff, int size);
+const char *vtype2string(enum vertextype vtype);
+const char *vid2string(const struct isis_vertex *vertex, char *buff, int size);
 
 #endif
index d05afaa63081c8dcb6aa69f01cae852a1e5c7460..89fa2018b9545842b8bd228d10222382ff075ce6 100644 (file)
@@ -31,6 +31,7 @@
 #include "memory.h"
 #include "prefix.h"
 #include "table.h"
+#include "srcdest_table.h"
 #include "vty.h"
 #include "zclient.h"
 #include "lib/lib_errors.h"
 /* Local variables and functions */
 DEFINE_MTYPE_STATIC(ISISD, ISIS_SR_INFO, "ISIS segment routing information")
 
-static void sr_prefix_uninstall(struct sr_prefix *srp);
-static void sr_prefix_reinstall(struct sr_prefix *srp, bool make_before_break);
 static void sr_local_block_delete(struct isis_area *area);
 static int sr_local_block_init(struct isis_area *area);
 static void sr_adj_sid_update(struct sr_adjacency *sra,
                              struct sr_local_block *srlb);
+static void sr_adj_sid_del(struct sr_adjacency *sra);
 
 /* --- RB-Tree Management functions ----------------------------------------- */
 
 /**
- * SR Prefix comparison for RB-Tree.
+ * Configured SR Prefix comparison for RB-Tree.
  *
  * @param a    First SR prefix
  * @param b    Second SR prefix
  *
  * @return     -1 (a < b), 0 (a == b) or +1 (a > b)
  */
-static inline int sr_prefix_sid_compare(const struct sr_prefix *a,
-                                       const struct sr_prefix *b)
+static inline int sr_prefix_sid_cfg_compare(const struct sr_prefix_cfg *a,
+                                           const struct sr_prefix_cfg *b)
 {
        return prefix_cmp(&a->prefix, &b->prefix);
 }
-DECLARE_RBTREE_UNIQ(srdb_node_prefix, struct sr_prefix, node_entry,
-                   sr_prefix_sid_compare)
-DECLARE_RBTREE_UNIQ(srdb_area_prefix, struct sr_prefix, area_entry,
-                   sr_prefix_sid_compare)
+DECLARE_RBTREE_UNIQ(srdb_prefix_cfg, struct sr_prefix_cfg, entry,
+                   sr_prefix_sid_cfg_compare)
 
 /**
- * Configured SR Prefix comparison for RB-Tree.
+ * Find SRGB associated to a System ID.
  *
- * @param a    First SR prefix
- * @param b    Second SR prefix
+ * @param area IS-IS LSP database
+ * @param sysid        System ID to lookup
  *
- * @return     -1 (a < b), 0 (a == b) or +1 (a > b)
+ * @return     Pointer to SRGB if found, NULL otherwise
  */
-static inline int sr_prefix_sid_cfg_compare(const struct sr_prefix_cfg *a,
-                                           const struct sr_prefix_cfg *b)
+struct isis_sr_block *isis_sr_find_srgb(struct lspdb_head *lspdb,
+                                       const uint8_t *sysid)
 {
-       return prefix_cmp(&a->prefix, &b->prefix);
+       struct isis_lsp *lsp;
+
+       lsp = isis_root_system_lsp(lspdb, sysid);
+       if (!lsp)
+               return NULL;
+
+       if (!lsp->tlvs->router_cap
+           || lsp->tlvs->router_cap->srgb.range_size == 0)
+               return NULL;
+
+       return &lsp->tlvs->router_cap->srgb;
 }
-DECLARE_RBTREE_UNIQ(srdb_prefix_cfg, struct sr_prefix_cfg, entry,
-                   sr_prefix_sid_cfg_compare)
 
 /**
- * SR Node comparison for RB-Tree.
+ * Compute input label for the given Prefix-SID.
  *
- * @param a    First SR node
- * @param b    Second SR node
+ * @param area   IS-IS area
+ * @param psid   IS-IS Prefix-SID Sub-TLV
+ * @param local          Indicates whether the Prefix-SID is local or not
  *
- * @return     -1 (a < b), 0 (a == b) or +1 (a > b)
+ * @return     MPLS label or MPLS_INVALID_LABEL in case of SRGB overflow
  */
-static inline int sr_node_compare(const struct sr_node *a,
-                                 const struct sr_node *b)
+mpls_label_t sr_prefix_in_label(struct isis_area *area,
+                               struct isis_prefix_sid *psid, bool local)
 {
-       return memcmp(a->sysid, b->sysid, ISIS_SYS_ID_LEN);
+       /*
+        * No need to assign a label for local Prefix-SIDs unless the no-PHP
+        * flag is set.
+        */
+       if (local
+           && (!CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP)
+               || CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL)))
+               return MPLS_INVALID_LABEL;
+
+       /* Return SID value as MPLS label if it is an Absolute SID */
+       if (CHECK_FLAG(psid->flags,
+                      ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL))
+               return psid->value;
+
+       /* Check that SID index falls inside the SRGB */
+       if (psid->value >= (area->srdb.config.srgb_upper_bound
+                           - area->srdb.config.srgb_lower_bound + 1)) {
+               flog_warn(EC_ISIS_SID_OVERFLOW,
+                         "%s: SID index %u falls outside local SRGB range",
+                         __func__, psid->value);
+               return MPLS_INVALID_LABEL;
+       }
+
+       /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */
+       return (area->srdb.config.srgb_lower_bound + psid->value);
+}
+
+/**
+ * Compute output label for the given Prefix-SID.
+ *
+ * @param lspdb                IS-IS LSP database
+ * @param family       Prefix-SID address family
+ * @param psid         Prefix-SID Sub-TLV
+ * @param nh_sysid     System ID of the nexthop node
+ * @param last_hop     Indicates whether the nexthop node is the last hop
+ *
+ * @return             MPLS label or MPLS_INVALID_LABEL in case of error
+ */
+mpls_label_t sr_prefix_out_label(struct lspdb_head *lspdb, int family,
+                                struct isis_prefix_sid *psid,
+                                const uint8_t *nh_sysid, bool last_hop)
+{
+       struct isis_sr_block *nh_srgb;
+
+       if (last_hop) {
+               if (!CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP))
+                       return MPLS_LABEL_IMPLICIT_NULL;
+
+               if (CHECK_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL)) {
+                       if (family == AF_INET)
+                               return MPLS_LABEL_IPV4_EXPLICIT_NULL;
+                       else
+                               return MPLS_LABEL_IPV6_EXPLICIT_NULL;
+               }
+               /* Fallthrough */
+       }
+
+       /* Return SID value as MPLS label if it is an Absolute SID */
+       if (CHECK_FLAG(psid->flags,
+                      ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL)) {
+               /*
+                * V/L SIDs have local significance, so only adjacent routers
+                * can use them (RFC8667 section #2.1.1.1)
+                */
+               if (!last_hop)
+                       return MPLS_INVALID_LABEL;
+               return psid->value;
+       }
+
+       /* Check that SID index falls inside the SRGB */
+       nh_srgb = isis_sr_find_srgb(lspdb, nh_sysid);
+       if (!nh_srgb)
+               return MPLS_INVALID_LABEL;
+
+       /*
+        * Check if the nexthop can handle SR-MPLS encapsulated IPv4 or
+        * IPv6 packets.
+        */
+       if ((family == AF_INET && !IS_SR_IPV4(nh_srgb))
+           || (family == AF_INET6 && !IS_SR_IPV6(nh_srgb)))
+               return MPLS_INVALID_LABEL;
+
+       if (psid->value >= nh_srgb->range_size) {
+               flog_warn(EC_ISIS_SID_OVERFLOW,
+                         "%s: SID index %u falls outside remote SRGB range",
+                         __func__, psid->value);
+               return MPLS_INVALID_LABEL;
+       }
+
+       /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */
+       return (nh_srgb->lower_bound + psid->value);
 }
-DECLARE_RBTREE_UNIQ(srdb_node, struct sr_node, entry, sr_node_compare)
 
 /* --- Functions used for Yang model and CLI to configure Segment Routing --- */
 
@@ -161,8 +257,6 @@ int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
        srdb->config.srgb_upper_bound = upper_bound;
 
        if (srdb->enabled) {
-               struct sr_prefix *srp;
-
                /* then request new SRGB if SR is enabled. */
                if (isis_zebra_request_label_range(
                            srdb->config.srgb_lower_bound,
@@ -178,14 +272,6 @@ int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
                         srdb->config.srgb_lower_bound,
                         srdb->config.srgb_upper_bound);
 
-               /* Reinstall local Prefix-SIDs to update their input labels. */
-               for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
-                       frr_each (srdb_area_prefix,
-                                 &area->srdb.prefix_sids[level - 1], srp) {
-                               sr_prefix_reinstall(srp, false);
-                       }
-               }
-
                lsp_regenerate_schedule(area, area->is_type, 0);
        } else if (srdb->config.enabled) {
                /* Try to enable SR again using the new SRGB. */
@@ -243,1098 +329,141 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
                lsp_regenerate_schedule(area, area->is_type, 0);
        } else if (srdb->config.enabled) {
                /* Try to enable SR again using the new SRLB. */
-               isis_sr_start(area);
-       }
-
-       return 0;
-}
-
-/**
- * Add new Prefix-SID configuration to the SRDB.
- *
- * @param area   IS-IS area
- * @param prefix  Prefix to be added
- *
- * @return       Newly added Prefix-SID configuration structure
- */
-struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area,
-                                            const struct prefix *prefix)
-{
-       struct sr_prefix_cfg *pcfg;
-       struct interface *ifp;
-
-       sr_debug("ISIS-Sr (%s): Add local prefix %pFX", area->area_tag, prefix);
-
-       pcfg = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*pcfg));
-       pcfg->prefix = *prefix;
-       pcfg->area = area;
-
-       /* Pull defaults from the YANG module. */
-       pcfg->sid_type = yang_get_default_enum(
-               "%s/prefix-sid-map/prefix-sid/sid-value-type", ISIS_SR);
-       pcfg->last_hop_behavior = yang_get_default_enum(
-               "%s/prefix-sid-map/prefix-sid/last-hop-behavior", ISIS_SR);
-
-       /* Set the N-flag when appropriate. */
-       ifp = if_lookup_prefix(prefix, VRF_DEFAULT);
-       if (ifp && sr_prefix_is_node_sid(ifp, prefix))
-               pcfg->node_sid = true;
-
-       /* Save prefix-sid configuration. */
-       srdb_prefix_cfg_add(&area->srdb.config.prefix_sids, pcfg);
-
-       return pcfg;
-}
-
-/**
- * Removal of locally configured Prefix-SID.
- *
- * @param pcfg Configured Prefix-SID
- */
-void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg)
-{
-       struct isis_area *area = pcfg->area;
-
-       sr_debug("ISIS-Sr (%s): Delete local Prefix-SID %pFX %s %u",
-                area->area_tag, &pcfg->prefix,
-                pcfg->sid_type == SR_SID_VALUE_TYPE_INDEX ? "index" : "label",
-                pcfg->sid);
-
-       srdb_prefix_cfg_del(&area->srdb.config.prefix_sids, pcfg);
-       XFREE(MTYPE_ISIS_SR_INFO, pcfg);
-}
-
-/**
- * Lookup for Prefix-SID in the local configuration.
- *
- * @param area   IS-IS area
- * @param prefix  Prefix to lookup
- *
- * @return       Configured Prefix-SID structure if found, NULL otherwise
- */
-struct sr_prefix_cfg *isis_sr_cfg_prefix_find(struct isis_area *area,
-                                             union prefixconstptr prefix)
-{
-       struct sr_prefix_cfg pcfg = {};
-
-       prefix_copy(&pcfg.prefix, prefix.p);
-       return srdb_prefix_cfg_find(&area->srdb.config.prefix_sids, &pcfg);
-}
-
-/**
- * Fill in Prefix-SID Sub-TLV according to the corresponding configuration.
- *
- * @param pcfg     Prefix-SID configuration
- * @param external  False if prefix is locally configured, true otherwise
- * @param psid     Prefix-SID sub-TLV to be updated
- */
-void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, bool external,
-                              struct isis_prefix_sid *psid)
-{
-       /* Set SID algorithm. */
-       psid->algorithm = SR_ALGORITHM_SPF;
-
-       /* Set SID flags. */
-       psid->flags = 0;
-       switch (pcfg->last_hop_behavior) {
-       case SR_LAST_HOP_BEHAVIOR_EXP_NULL:
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
-               break;
-       case SR_LAST_HOP_BEHAVIOR_NO_PHP:
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
-               UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
-               break;
-       case SR_LAST_HOP_BEHAVIOR_PHP:
-               UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
-               UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
-               break;
-       }
-       if (external)
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_READVERTISED);
-       if (pcfg->node_sid)
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_NODE);
-
-       /* Set SID value. */
-       psid->value = pcfg->sid;
-       if (pcfg->sid_type == SR_SID_VALUE_TYPE_ABSOLUTE) {
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_VALUE);
-               SET_FLAG(psid->flags, ISIS_PREFIX_SID_LOCAL);
-       }
-}
-
-/* --- Segment Routing Prefix Management functions -------------------------- */
-
-/**
- * Add Segment Routing Prefix to a given Segment Routing Node.
- *
- * @param area   IS-IS area
- * @param srn    Segment Routing Node
- * @param prefix  Prefix to be added
- * @param local          True if prefix is locally configured, false otherwise
- * @param psid   Prefix-SID sub-TLVs
- *
- * @return       New Segment Routing Prefix structure
- */
-static struct sr_prefix *sr_prefix_add(struct isis_area *area,
-                                      struct sr_node *srn,
-                                      union prefixconstptr prefix, bool local,
-                                      const struct isis_prefix_sid *psid)
-{
-       struct sr_prefix *srp;
-
-       srp = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*srp));
-       prefix_copy(&srp->prefix, prefix.p);
-       srp->sid = *psid;
-       srp->input_label = MPLS_INVALID_LABEL;
-       if (local) {
-               srp->type = ISIS_SR_PREFIX_LOCAL;
-               isis_sr_nexthop_reset(&srp->u.local.info);
-       } else {
-               srp->type = ISIS_SR_PREFIX_REMOTE;
-               srp->u.remote.rinfo = NULL;
-       }
-       srp->srn = srn;
-       srdb_node_prefix_add(&srn->prefix_sids, srp);
-       /* TODO: this might fail if we have Anycast SIDs in the IS-IS area. */
-       srdb_area_prefix_add(&area->srdb.prefix_sids[srn->level - 1], srp);
-
-       sr_debug("  |- Added new SR Prefix-SID %pFX %s %u to SR Node %s",
-                &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index",
-                srp->sid.value, sysid_print(srn->sysid));
-
-       return srp;
-}
-
-/**
- * Remove given Segment Prefix from given Segment Routing Node.
- * Prefix-SID is un-installed first.
- *
- * @param area IS-IS area
- * @param srn  Segment Routing Node
- * @param srp  Segment Routing Prefix
- */
-static void sr_prefix_del(struct isis_area *area, struct sr_node *srn,
-                         struct sr_prefix *srp)
-{
-       sr_debug("  |- Delete SR Prefix-SID %pFX %s %u to SR Node %s",
-                &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index",
-                srp->sid.value, sysid_print(srn->sysid));
-
-       sr_prefix_uninstall(srp);
-       srdb_node_prefix_del(&srn->prefix_sids, srp);
-       srdb_area_prefix_del(&area->srdb.prefix_sids[srn->level - 1], srp);
-       XFREE(MTYPE_ISIS_SR_INFO, srp);
-}
-
-/**
- * Find Segment Routing Prefix by Area.
- *
- * @param area   IS-IS area
- * @param level          IS-IS level
- * @param prefix  Prefix to lookup
- *
- * @return       Segment Routing Prefix structure if found, NULL otherwise
- */
-static struct sr_prefix *sr_prefix_find_by_area(struct isis_area *area,
-                                               int level,
-                                               union prefixconstptr prefix)
-{
-       struct sr_prefix srp = {};
-
-       prefix_copy(&srp.prefix, prefix.p);
-       return srdb_area_prefix_find(&area->srdb.prefix_sids[level - 1], &srp);
-}
-
-/**
- * Find Segment Routing Prefix by Segment Routing Node.
- *
- * @param srn    Segment Routing Node
- * @param prefix  Prefix to lookup
- *
- * @return       Segment Routing Prefix structure if found, NULL otherwise
- */
-static struct sr_prefix *sr_prefix_find_by_node(struct sr_node *srn,
-                                               union prefixconstptr prefix)
-{
-       struct sr_prefix srp = {};
-
-       prefix_copy(&srp.prefix, prefix.p);
-       return srdb_node_prefix_find(&srn->prefix_sids, &srp);
-}
-
-/* --- Segment Routing Node Management functions ---------------------------- */
-
-/**
- * Add Segment Routing Node to the Segment Routing Data Base.
- *
- * @param area  IS-IS area
- * @param level         IS-IS level
- * @param sysid         Node System ID
- * @param cap   Segment Routing Capability sub-TLVs
- *
- * @return      New Segment Routing Node structure
- */
-static struct sr_node *sr_node_add(struct isis_area *area, int level,
-                                  const uint8_t *sysid)
-{
-       struct sr_node *srn;
-
-       srn = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*srn));
-       srn->level = level;
-       memcpy(srn->sysid, sysid, ISIS_SYS_ID_LEN);
-       srn->area = area;
-       srdb_node_prefix_init(&srn->prefix_sids);
-       srdb_node_add(&area->srdb.sr_nodes[level - 1], srn);
-
-       sr_debug("  |- Added new SR Node %s", sysid_print(srn->sysid));
-
-       return srn;
-}
-
-static void sr_node_del(struct isis_area *area, int level, struct sr_node *srn)
-/**
- * Remove Segment Routing Node from the Segment Routing Data Base.
- * All Prefix-SID attached to this Segment Routing Node are removed first.
- *
- * @param area  IS-IS area
- * @param level         IS-IS level
- * @param srn   Segment Routing Node to be deleted
- */
-{
-
-       sr_debug("  |- Delete SR Node %s", sysid_print(srn->sysid));
-
-       /* Remove and uninstall Prefix-SIDs. */
-       while (srdb_node_prefix_count(&srn->prefix_sids) > 0) {
-               struct sr_prefix *srp;
-
-               srp = srdb_node_prefix_first(&srn->prefix_sids);
-               sr_prefix_del(area, srn, srp);
-       }
-
-       srdb_node_del(&area->srdb.sr_nodes[level - 1], srn);
-       XFREE(MTYPE_ISIS_SR_INFO, srn);
-}
-
-/**
- * Find Segment Routing Node in the Segment Routing Data Base per system ID.
- *
- * @param area  IS-IS area
- * @param level         IS-IS level
- * @param sysid         Node System ID to lookup
- *
- * @return      Segment Routing Node structure if found, NULL otherwise
- */
-static struct sr_node *sr_node_find(struct isis_area *area, int level,
-                                   const uint8_t *sysid)
-{
-       struct sr_node srn = {};
-
-       memcpy(srn.sysid, sysid, ISIS_SYS_ID_LEN);
-       return srdb_node_find(&area->srdb.sr_nodes[level - 1], &srn);
-}
-
-/**
- * Update Segment Routing Node following an SRGB update. This function
- * is called when a neighbor SR Node has updated its SRGB.
- *
- * @param area  IS-IS area
- * @param level         IS-IS level
- * @param sysid         Segment Routing Node system ID
- */
-static void sr_node_srgb_update(struct isis_area *area, int level,
-                               uint8_t *sysid)
-{
-       struct sr_prefix *srp;
-
-       sr_debug("ISIS-Sr (%s): Update neighbors SR Node with new SRGB",
-                area->area_tag);
-
-       frr_each (srdb_area_prefix, &area->srdb.prefix_sids[level - 1], srp) {
-               struct listnode *node;
-               struct isis_nexthop *nh;
-
-               if (srp->type == ISIS_SR_PREFIX_LOCAL)
-                       continue;
-
-               if (srp->u.remote.rinfo == NULL)
-                       continue;
-
-               for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node,
-                                         nh)) {
-                       if (memcmp(nh->sysid, sysid, ISIS_SYS_ID_LEN) != 0)
-                               continue;
-
-                       /*
-                        * The Prefix-SID input label hasn't changed. We could
-                        * re-install all Prefix-SID with "Make Before Break"
-                        * option. Zebra layer will update output label(s) by
-                        * adding new entry before removing the old one(s).
-                        */
-                       sr_prefix_reinstall(srp, true);
-                       break;
-               }
-       }
-}
-
-/* --- Segment Routing Nexthop information Management functions ------------- */
-
-/**
- * Update Segment Routing Nexthop.
- *
- * @param srnh  Segment Routing next hop
- * @param label         Output MPLS label
- */
-void isis_sr_nexthop_update(struct sr_nexthop_info *srnh, mpls_label_t label)
-{
-       srnh->label = label;
-       if (srnh->uptime == 0)
-               srnh->uptime = time(NULL);
-}
-
-/**
- * Reset Segment Routing Nexthop.
- *
- * @param srnh Segment Routing Nexthop
- */
-void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh)
-{
-       srnh->label = MPLS_INVALID_LABEL;
-       srnh->uptime = 0;
-}
-
-/* --- Segment Routing Prefix-SID Management functions to configure LFIB ---- */
-
-/**
- * Lookup IS-IS route in the Shortest Path Tree.
- *
- * @param area    IS-IS area
- * @param tree_id  Shortest Path Tree identifier
- * @param srp     Segment Routing Prefix to lookup
- *
- * @return        Route Information for this prefix if found, NULL otherwise
- */
-static struct isis_route_info *sr_prefix_lookup_route(struct isis_area *area,
-                                                     enum spf_tree_id tree_id,
-                                                     struct sr_prefix *srp)
-{
-       struct route_node *rn;
-       int level = srp->srn->level;
-
-       rn = route_node_lookup(area->spftree[tree_id][level - 1]->route_table,
-                              &srp->prefix);
-       if (rn) {
-               route_unlock_node(rn);
-               if (rn->info)
-                       return rn->info;
-       }
-
-       return NULL;
-}
-
-/**
- * Compute input label for the given Prefix-SID.
- *
- * @param srp  Segment Routing Prefix
- *
- * @return     MPLS label or MPLS_INVALID_LABEL in case of SRGB overflow
- */
-static mpls_label_t sr_prefix_in_label(const struct sr_prefix *srp)
-{
-       const struct sr_node *srn = srp->srn;
-       struct isis_area *area = srn->area;
-
-       /* Return SID value as MPLS label if it is an Absolute SID */
-       if (CHECK_FLAG(srp->sid.flags,
-                      ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL))
-               return srp->sid.value;
-
-       /* Check that SID index falls inside the SRGB */
-       if (srp->sid.value >= (area->srdb.config.srgb_upper_bound
-                              - area->srdb.config.srgb_lower_bound + 1)) {
-               flog_warn(EC_ISIS_SID_OVERFLOW,
-                         "%s: SID index %u falls outside local SRGB range",
-                         __func__, srp->sid.value);
-               return MPLS_INVALID_LABEL;
-       }
-
-       /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */
-       return (area->srdb.config.srgb_lower_bound + srp->sid.value);
-}
-
-/**
- * Compute output label for the given Prefix-SID.
- *
- * @param srp          Segment Routing Prefix
- * @param srn_nexthop  Segment Routing nexthop node
- * @param sysid                System ID of the SR node which advertised the Prefix-SID
- *
- * @return             MPLS label or MPLS_INVALID_LABEL in case of error
- */
-static mpls_label_t sr_prefix_out_label(const struct sr_prefix *srp,
-                                       const struct sr_node *srn_nexthop,
-                                       const uint8_t *sysid)
-{
-       const struct sr_node *srn = srp->srn;
-
-       /* Check if the nexthop SR Node is the last hop? */
-       if (memcmp(sysid, srn->sysid, ISIS_SYS_ID_LEN) == 0) {
-               /* SR-Node doesn't request NO-PHP. Return Implicit NULL label */
-               if (!CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_NO_PHP))
-                       return MPLS_LABEL_IMPLICIT_NULL;
-
-               /* SR-Node requests Implicit NULL Label */
-               if (CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_EXPLICIT_NULL)) {
-                       if (srp->prefix.family == AF_INET)
-                               return MPLS_LABEL_IPV4_EXPLICIT_NULL;
-                       else
-                               return MPLS_LABEL_IPV6_EXPLICIT_NULL;
-               }
-               /* Fallthrough */
-       }
-
-       /* Return SID value as MPLS label if it is an Absolute SID */
-       if (CHECK_FLAG(srp->sid.flags,
-                      ISIS_PREFIX_SID_VALUE | ISIS_PREFIX_SID_LOCAL)) {
-               /*
-                * V/L SIDs have local significance, so only adjacent routers
-                * can use them (RFC8667 section #2.1.1.1)
-                */
-               if (srp->srn != srn_nexthop)
-                       return MPLS_INVALID_LABEL;
-               return srp->sid.value;
-       }
-
-       /* Check that SID index falls inside the SRGB */
-       if (srp->sid.value >= srn_nexthop->cap.srgb.range_size) {
-               flog_warn(EC_ISIS_SID_OVERFLOW,
-                         "%s: SID index %u falls outside remote SRGB range",
-                         __func__, srp->sid.value);
-               return MPLS_INVALID_LABEL;
-       }
-
-       /* Return MPLS label as SID index + SRGB_lower_bound as per RFC 8667 */
-       return (srn_nexthop->cap.srgb.lower_bound + srp->sid.value);
-}
-
-/**
- * Process local Prefix-SID and install it if possible. Input label is
- * computed before installing it in LFIB.
- *
- * @param srp  Segment Routing Prefix
- *
- * @return     0 on success, -1 otherwise
- */
-static int sr_prefix_install_local(struct sr_prefix *srp)
-{
-       mpls_label_t input_label;
-       const struct sr_node *srn = srp->srn;
-
-       /*
-        * No need to install Label for local Prefix-SID unless the
-        * no-PHP option is configured.
-        */
-       if (!CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_NO_PHP)
-           || CHECK_FLAG(srp->sid.flags, ISIS_PREFIX_SID_EXPLICIT_NULL))
-               return -1;
-
-       sr_debug("  |- Installing Prefix-SID %pFX %s %u (%s) with nexthop self",
-                &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index",
-                srp->sid.value, circuit_t2string(srn->level));
-
-       /* Compute input label and check that is valid. */
-       input_label = sr_prefix_in_label(srp);
-       if (input_label == MPLS_INVALID_LABEL)
-               return -1;
-
-       /* Update internal state. */
-       srp->input_label = input_label;
-       isis_sr_nexthop_update(&srp->u.local.info, MPLS_LABEL_IMPLICIT_NULL);
-
-       /* Install Prefix-SID in the forwarding plane. */
-       isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_REPLACE, srp);
-
-       return 0;
-}
-
-/**
- * Process remote Prefix-SID and install it if possible. Input and Output
- * labels are computed before installing them in LFIB.
- *
- * @param srp  Segment Routing Prefix
- *
- * @return     0 on success, -1 otherwise
- */
-static int sr_prefix_install_remote(struct sr_prefix *srp)
-{
-       const struct sr_node *srn = srp->srn;
-       struct isis_area *area = srn->area;
-       enum spf_tree_id tree_id;
-       struct listnode *node;
-       struct isis_nexthop *nexthop;
-       mpls_label_t input_label;
-       size_t nexthop_num = 0;
-
-       /* Lookup to associated IS-IS route. */
-       tree_id = (srp->prefix.family == AF_INET) ? SPFTREE_IPV4 : SPFTREE_IPV6;
-       srp->u.remote.rinfo = sr_prefix_lookup_route(area, tree_id, srp);
-       if (!srp->u.remote.rinfo)
-               /* SPF hasn't converged for this route yet. */
-               return -1;
-
-       /* Compute input label and check that is valid. */
-       input_label = sr_prefix_in_label(srp);
-       if (input_label == MPLS_INVALID_LABEL)
-               return -1;
-
-       sr_debug("  |- Installing Prefix-SID %pFX %s %u (%s)", &srp->prefix,
-                IS_SID_VALUE(srp->sid.flags) ? "label" : "index",
-                srp->sid.value, circuit_t2string(srn->level));
-
-       /* Process all SPF nexthops */
-       for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node,
-                                 nexthop)) {
-               struct sr_node *srn_nexthop;
-               mpls_label_t output_label;
-
-               /* Check if the nexthop advertised a SRGB. */
-               srn_nexthop = sr_node_find(area, srn->level, nexthop->sysid);
-               if (!srn_nexthop)
-                       goto next;
-
-               /*
-                * Check if the nexthop can handle SR-MPLS encapsulated IPv4 or
-                * IPv6 packets.
-                */
-               if ((nexthop->family == AF_INET
-                    && !IS_SR_IPV4(srn_nexthop->cap.srgb))
-                   || (nexthop->family == AF_INET6
-                       && !IS_SR_IPV6(srn_nexthop->cap.srgb)))
-                       goto next;
-
-               /* Compute output label and check if it is valid */
-               output_label =
-                       sr_prefix_out_label(srp, srn_nexthop, nexthop->sysid);
-               if (output_label == MPLS_INVALID_LABEL)
-                       goto next;
-
-               if (IS_DEBUG_SR) {
-                       static char buf[INET6_ADDRSTRLEN];
-
-                       inet_ntop(nexthop->family, &nexthop->ip, buf,
-                                 sizeof(buf));
-                       zlog_debug("    |- nexthop %s label %u", buf,
-                                  output_label);
-               }
-
-               isis_sr_nexthop_update(&nexthop->sr, output_label);
-               nexthop_num++;
-               continue;
-       next:
-               isis_sr_nexthop_reset(&nexthop->sr);
-       }
-
-       /* Check that we found at least one valid nexthop */
-       if (nexthop_num == 0) {
-               sr_debug("    |- no valid nexthops");
-               return -1;
-       }
-
-       /* Update internal state. */
-       srp->input_label = input_label;
-
-       /* Install Prefix-SID in the forwarding plane. */
-       isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_REPLACE, srp);
-
-       return 0;
-}
-
-/**
- * Process local or remote Prefix-SID and install it if possible.
- *
- * @param srp  Segment Routing Prefix
- */
-static void sr_prefix_install(struct sr_prefix *srp)
-{
-       const struct sr_node *srn = srp->srn;
-       struct isis_area *area = srn->area;
-       int ret;
-
-       sr_debug("ISIS-Sr (%s): Install Prefix-SID %pFX %s %u", area->area_tag,
-                &srp->prefix, IS_SID_VALUE(srp->sid.flags) ? "label" : "index",
-                srp->sid.value);
-
-       /* L1 routes are preferred over the L2 ones. */
-       if (area->is_type == IS_LEVEL_1_AND_2) {
-               struct sr_prefix *srp_l1, *srp_l2;
-
-               switch (srn->level) {
-               case ISIS_LEVEL1:
-                       srp_l2 = sr_prefix_find_by_area(area, ISIS_LEVEL2,
-                                                       &srp->prefix);
-                       if (srp_l2)
-                               sr_prefix_uninstall(srp_l2);
-                       break;
-               case ISIS_LEVEL2:
-                       srp_l1 = sr_prefix_find_by_area(area, ISIS_LEVEL1,
-                                                       &srp->prefix);
-                       if (srp_l1)
-                               return;
-                       break;
-               default:
-                       break;
-               }
-       }
-
-       /* Install corresponding LFIB entry */
-       if (srp->type == ISIS_SR_PREFIX_LOCAL)
-               ret = sr_prefix_install_local(srp);
-       else
-               ret = sr_prefix_install_remote(srp);
-       if (ret != 0)
-               sr_prefix_uninstall(srp);
-}
-
-/**
- * Uninstall local or remote Prefix-SID.
- *
- * @param srp  Segment Routing Prefix
- */
-static void sr_prefix_uninstall(struct sr_prefix *srp)
-{
-       struct listnode *node;
-       struct isis_nexthop *nexthop;
-
-       /* Check that Input Label is valid */
-       if (srp->input_label == MPLS_INVALID_LABEL)
-               return;
-
-       sr_debug("ISIS-Sr: Un-install Prefix-SID %pFX %s %u", &srp->prefix,
-                IS_SID_VALUE(srp->sid.flags) ? "label" : "index",
-                srp->sid.value);
-
-       /* Uninstall Prefix-SID from the forwarding plane. */
-       isis_zebra_send_prefix_sid(ZEBRA_MPLS_LABELS_DELETE, srp);
-
-       /* Reset internal state. */
-       srp->input_label = MPLS_INVALID_LABEL;
-       switch (srp->type) {
-       case ISIS_SR_PREFIX_LOCAL:
-               isis_sr_nexthop_reset(&srp->u.local.info);
-               break;
-       case ISIS_SR_PREFIX_REMOTE:
-               if (srp->u.remote.rinfo) {
-                       for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops,
-                                                 node, nexthop))
-                               isis_sr_nexthop_reset(&nexthop->sr);
-               }
-               break;
-       }
-}
-
-/**
- * Reinstall local or remote Prefix-SID.
- *
- * @param srp  Segment Routing Prefix
- */
-static inline void sr_prefix_reinstall(struct sr_prefix *srp,
-                                      bool make_before_break)
-{
-       /*
-        * Make Before Break can be used only when we know for sure that
-        * the Prefix-SID input label hasn't changed. Otherwise we need to
-        * uninstall the Prefix-SID first using the old input label before
-        * reinstalling it.
-        */
-       if (!make_before_break)
-               sr_prefix_uninstall(srp);
-
-       /* New input label is computed in sr_prefix_install() function */
-       sr_prefix_install(srp);
-}
-
-/* --- IS-IS LSP Parse functions -------------------------------------------- */
-
-/**
- * Compare Router Capabilities. Only Flags, SRGB and Algorithm are used for the
- * comparison. MSD and SRLB modification must not trigger and SR-Prefix update.
- *
- * @param r1   First Router Capabilities to compare
- * @param r2   Second Router Capabilities to compare
- * @return     0 if r1 and r2 are equal or -1 otherwise
- */
-static int router_cap_cmp(const struct isis_router_cap *r1,
-                         const struct isis_router_cap *r2)
-{
-       if (r1->flags == r2->flags
-           && r1->srgb.lower_bound == r2->srgb.lower_bound
-           && r1->srgb.range_size == r2->srgb.range_size
-           && r1->algo[0] == r2->algo[0])
-               return 0;
-       else
-               return -1;
-}
-
-/**
- * Parse all SR-related information from the given Router Capabilities TLV.
- *
- * @param area         IS-IS area
- * @param level                IS-IS level
- * @param sysid                System ID of the LSP
- * @param router_cap   Router Capability subTLVs
- *
- * @return             Segment Routing Node structure for this System ID
- */
-static struct sr_node *
-parse_router_cap_tlv(struct isis_area *area, int level, const uint8_t *sysid,
-                    const struct isis_router_cap *router_cap)
-{
-       struct sr_node *srn;
-
-       if (!router_cap || router_cap->srgb.range_size == 0)
-               return NULL;
-
-       sr_debug("ISIS-Sr (%s): Parse Router Capability TLV", area->area_tag);
-
-       srn = sr_node_find(area, level, sysid);
-       if (srn) {
-               if (router_cap_cmp(&srn->cap, router_cap) != 0) {
-                       srn->state = SRDB_STATE_MODIFIED;
-               } else
-                       srn->state = SRDB_STATE_UNCHANGED;
-               sr_debug("  |- Found %s SR Node %s",
-                        srn->state == SRDB_STATE_MODIFIED ? "Modified"
-                                                          : "Unchanged",
-                        sysid_print(srn->sysid));
-       } else {
-               srn = sr_node_add(area, level, sysid);
-               srn->state = SRDB_STATE_NEW;
-       }
-
-       /*
-        * Update Router Capabilities in any case as SRLB or MSD
-        * modification are not take into account for comparison.
-        */
-       srn->cap = *router_cap;
-
-       return srn;
-}
-
-/**
- * Parse list of Prefix-SID Sub-TLVs.
- *
- * @param srn          Segment Routing Node
- * @param prefix       Prefix to be parsed
- * @param local                True if prefix comes from own LSP, false otherwise
- * @param prefix_sids  Prefix SID subTLVs
- */
-static void parse_prefix_sid_subtlvs(struct sr_node *srn,
-                                    union prefixconstptr prefix, bool local,
-                                    struct isis_item_list *prefix_sids)
-{
-       struct isis_area *area = srn->area;
-       struct isis_item *i;
-
-       sr_debug("ISIS-Sr (%s): Parse Prefix SID TLV", area->area_tag);
-
-       /* Parse list of Prefix SID subTLVs */
-       for (i = prefix_sids->head; i; i = i->next) {
-               struct isis_prefix_sid *psid = (struct isis_prefix_sid *)i;
-               struct sr_prefix *srp;
-
-               /* Only SPF algorithm is supported right now */
-               if (psid->algorithm != SR_ALGORITHM_SPF)
-                       continue;
-
-               /* Compute corresponding Segment Routing Prefix */
-               srp = sr_prefix_find_by_node(srn, prefix);
-               if (srp) {
-                       if (srp->sid.flags != psid->flags
-                           || srp->sid.algorithm != psid->algorithm
-                           || srp->sid.value != psid->value) {
-                               srp->sid = *psid;
-                               srp->state = SRDB_STATE_MODIFIED;
-                       } else if (srp->state == SRDB_STATE_VALIDATED)
-                               srp->state = SRDB_STATE_UNCHANGED;
-                       sr_debug("  |- Found %s Prefix-SID %pFX",
-                                srp->state == SRDB_STATE_MODIFIED
-                                        ? "Modified"
-                                        : "Unchanged",
-                                &srp->prefix);
-
-               } else {
-                       srp = sr_prefix_add(area, srn, prefix, local, psid);
-                       srp->state = SRDB_STATE_NEW;
-               }
-               /*
-                * Stop the Prefix-SID iteration since we only support the SPF
-                * algorithm for now.
-                */
-               break;
+               isis_sr_start(area);
        }
+
+       return 0;
 }
 
 /**
- * Parse all SR-related information from the given LSP.
+ * Add new Prefix-SID configuration to the SRDB.
  *
- * @param area IS-IS area
- * @param level        IS-IS level
- * @param srn  Segment Routing Node
- * @param lsp  IS-IS LSP
+ * @param area   IS-IS area
+ * @param prefix  Prefix to be added
+ *
+ * @return       Newly added Prefix-SID configuration structure
  */
-static void parse_lsp(struct isis_area *area, int level, struct sr_node **srn,
-                     struct isis_lsp *lsp)
+struct sr_prefix_cfg *isis_sr_cfg_prefix_add(struct isis_area *area,
+                                            const struct prefix *prefix)
 {
-       struct isis_item_list *items;
-       struct isis_item *i;
-       bool local = lsp->own_lsp;
-
-       /* Check LSP sequence number */
-       if (lsp->hdr.seqno == 0) {
-               zlog_warn("%s: lsp with 0 seq_num - ignore", __func__);
-               return;
-       }
-
-       sr_debug("ISIS-Sr (%s): Parse LSP from node %s", area->area_tag,
-                sysid_print(lsp->hdr.lsp_id));
-
-       /* Parse the Router Capability TLV. */
-       if (*srn == NULL) {
-               *srn = parse_router_cap_tlv(area, level, lsp->hdr.lsp_id,
-                                           lsp->tlvs->router_cap);
-               if (!*srn)
-                       return;
-       }
+       struct sr_prefix_cfg *pcfg;
+       struct interface *ifp;
 
-       /* Parse the Extended IP Reachability TLV. */
-       items = &lsp->tlvs->extended_ip_reach;
-       for (i = items->head; i; i = i->next) {
-               struct isis_extended_ip_reach *ir;
+       sr_debug("ISIS-Sr (%s): Add local prefix %pFX", area->area_tag, prefix);
 
-               ir = (struct isis_extended_ip_reach *)i;
-               if (!ir->subtlvs)
-                       continue;
+       pcfg = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*pcfg));
+       pcfg->prefix = *prefix;
+       pcfg->area = area;
 
-               parse_prefix_sid_subtlvs(*srn, &ir->prefix, local,
-                                        &ir->subtlvs->prefix_sids);
-       }
+       /* Pull defaults from the YANG module. */
+       pcfg->sid_type = yang_get_default_enum(
+               "%s/prefix-sid-map/prefix-sid/sid-value-type", ISIS_SR);
+       pcfg->last_hop_behavior = yang_get_default_enum(
+               "%s/prefix-sid-map/prefix-sid/last-hop-behavior", ISIS_SR);
 
-       /* Parse Multi Topology Reachable IPv6 Prefixes TLV. */
-       items = isis_lookup_mt_items(&lsp->tlvs->mt_ipv6_reach,
-                                    ISIS_MT_IPV6_UNICAST);
-       for (i = items ? items->head : NULL; i; i = i->next) {
-               struct isis_ipv6_reach *ir;
+       /* Set the N-flag when appropriate. */
+       ifp = if_lookup_prefix(prefix, VRF_DEFAULT);
+       if (ifp && sr_prefix_is_node_sid(ifp, prefix) && !pcfg->n_flag_clear)
+               pcfg->node_sid = true;
 
-               ir = (struct isis_ipv6_reach *)i;
-               if (!ir->subtlvs)
-                       continue;
+       /* Save prefix-sid configuration. */
+       srdb_prefix_cfg_add(&area->srdb.config.prefix_sids, pcfg);
 
-               parse_prefix_sid_subtlvs(*srn, &ir->prefix, local,
-                                        &ir->subtlvs->prefix_sids);
-       }
+       return pcfg;
 }
 
 /**
- * Parse all SR-related information from the entire LSPDB.
+ * Removal of locally configured Prefix-SID.
  *
- * @param area IS-IS area
+ * @param pcfg Configured Prefix-SID
  */
-static void parse_lspdb(struct isis_area *area)
+void isis_sr_cfg_prefix_del(struct sr_prefix_cfg *pcfg)
 {
-       struct isis_lsp *lsp;
+       struct isis_area *area = pcfg->area;
 
-       sr_debug("ISIS-Sr (%s): Parse LSP Data Base", area->area_tag);
-
-       /* Process all LSP from Level 1 & 2 */
-       for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
-               frr_each (lspdb, &area->lspdb[level - 1], lsp) {
-                       struct isis_lsp *frag;
-                       struct listnode *node;
-                       struct sr_node *srn = NULL;
-
-                       /* Skip Pseudo ID LSP and LSP without TLVs */
-                       if (LSP_PSEUDO_ID(lsp->hdr.lsp_id))
-                               continue;
-                       if (!lsp->tlvs)
-                               continue;
-
-                       /* Parse LSP, then fragment */
-                       parse_lsp(area, level, &srn, lsp);
-                       for (ALL_LIST_ELEMENTS_RO(lsp->lspu.frags, node, frag))
-                               parse_lsp(area, level, &srn, frag);
-               }
-       }
+       sr_debug("ISIS-Sr (%s): Delete local Prefix-SID %pFX %s %u",
+                area->area_tag, &pcfg->prefix,
+                pcfg->sid_type == SR_SID_VALUE_TYPE_INDEX ? "index" : "label",
+                pcfg->sid);
+
+       srdb_prefix_cfg_del(&area->srdb.config.prefix_sids, pcfg);
+       XFREE(MTYPE_ISIS_SR_INFO, pcfg);
 }
 
 /**
- * Process any new/deleted/modified Prefix-SID in the LSPDB.
+ * Lookup for Prefix-SID in the local configuration.
  *
- * @param srn  Segment Routing Node
- * @param srp  Segment Routing Prefix
+ * @param area   IS-IS area
+ * @param prefix  Prefix to lookup
+ *
+ * @return       Configured Prefix-SID structure if found, NULL otherwise
  */
-static void process_prefix_changes(struct sr_node *srn, struct sr_prefix *srp)
+struct sr_prefix_cfg *isis_sr_cfg_prefix_find(struct isis_area *area,
+                                             union prefixconstptr prefix)
 {
-       struct isis_area *area = srn->area;
-
-       /* Install/reinstall/uninstall Prefix-SID if necessary. */
-       switch (srp->state) {
-       case SRDB_STATE_NEW:
-               sr_debug("ISIS-Sr (%s): Created Prefix-SID %pFX for SR node %s",
-                        area->area_tag, &srp->prefix, sysid_print(srn->sysid));
-               sr_prefix_install(srp);
-               break;
-       case SRDB_STATE_MODIFIED:
-               sr_debug(
-                       "ISIS-Sr (%s): Modified Prefix-SID %pFX for SR node %s",
-                       area->area_tag, &srp->prefix, sysid_print(srn->sysid));
-               sr_prefix_reinstall(srp, false);
-               break;
-       case SRDB_STATE_UNCHANGED:
-               break;
-       default:
-               sr_debug("ISIS-Sr (%s): Removed Prefix-SID %pFX for SR node %s",
-                        area->area_tag, &srp->prefix, sysid_print(srn->sysid));
-               sr_prefix_del(area, srn, srp);
-               return;
-       }
+       struct sr_prefix_cfg pcfg = {};
 
-       /* Validate SRDB State for next LSPDB parsing */
-       srp->state = SRDB_STATE_VALIDATED;
+       prefix_copy(&pcfg.prefix, prefix.p);
+       return srdb_prefix_cfg_find(&area->srdb.config.prefix_sids, &pcfg);
 }
 
 /**
- * Process any new/deleted/modified SRGB in the LSPDB.
+ * Fill in Prefix-SID Sub-TLV according to the corresponding configuration.
  *
- * @param area IS-IS area
- * @param level        IS-IS level
- * @param srn  Segment Routing Node
+ * @param pcfg     Prefix-SID configuration
+ * @param external  False if prefix is locally configured, true otherwise
+ * @param psid     Prefix-SID sub-TLV to be updated
  */
-static void process_node_changes(struct isis_area *area, int level,
-                                struct sr_node *srn)
+void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg, bool external,
+                              struct isis_prefix_sid *psid)
 {
-       struct sr_prefix *srp;
-       uint8_t sysid[ISIS_SYS_ID_LEN];
-       bool adjacent;
-
-       memcpy(sysid, srn->sysid, sizeof(sysid));
+       /* Set SID algorithm. */
+       psid->algorithm = SR_ALGORITHM_SPF;
 
-       /*
-        * If an neighbor router's SRGB was changed or created, then reinstall
-        * all Prefix-SIDs from all nodes that use this neighbor as nexthop.
-        */
-       adjacent = !!isis_adj_find(area, level, sysid);
-       switch (srn->state) {
-       case SRDB_STATE_NEW:
-       case SRDB_STATE_MODIFIED:
-               sr_debug("ISIS-Sr (%s): Create/Update SR node %s",
-                        area->area_tag, sysid_print(srn->sysid));
-               if (adjacent)
-                       sr_node_srgb_update(area, level, sysid);
+       /* Set SID flags. */
+       psid->flags = 0;
+       switch (pcfg->last_hop_behavior) {
+       case SR_LAST_HOP_BEHAVIOR_EXP_NULL:
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
                break;
-       case SRDB_STATE_UNCHANGED:
+       case SR_LAST_HOP_BEHAVIOR_NO_PHP:
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
+               UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
+               break;
+       case SR_LAST_HOP_BEHAVIOR_PHP:
+               UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_NO_PHP);
+               UNSET_FLAG(psid->flags, ISIS_PREFIX_SID_EXPLICIT_NULL);
                break;
-       default:
-               /* SR capabilities have been removed. Delete SR-Node */
-               sr_debug("ISIS-Sr (%s): Remove SR node %s", area->area_tag,
-                        sysid_print(srn->sysid));
-
-               sr_node_del(area, level, srn);
-               /* and Update remaining Prefix-SID from all remaining SR Node */
-               if (adjacent)
-                       sr_node_srgb_update(area, level, sysid);
-               return;
        }
+       if (external)
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_READVERTISED);
+       if (pcfg->node_sid)
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_NODE);
 
-       /* Validate SRDB State for next LSPDB parsing */
-       srn->state = SRDB_STATE_VALIDATED;
-
-       /* Finally, process all Prefix-SID of this SR Node */
-       frr_each_safe (srdb_node_prefix, &srn->prefix_sids, srp)
-               process_prefix_changes(srn, srp);
-}
-
-/**
- * Parse and process all SR-related Sub-TLVs after running the SPF algorithm.
- *
- * @param area IS-IS area
- */
-void isis_area_verify_sr(struct isis_area *area)
-{
-       struct sr_node *srn;
-
-       if (!area->srdb.enabled)
-               return;
-
-       /* Parse LSPDB to detect new/deleted/modified SR (sub-)TLVs. */
-       parse_lspdb(area);
-
-       /* Process possible SR-related changes in the LDPSB. */
-       for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
-               frr_each_safe (srdb_node, &area->srdb.sr_nodes[level - 1], srn)
-                       process_node_changes(area, level, srn);
+       /* Set SID value. */
+       psid->value = pcfg->sid;
+       if (pcfg->sid_type == SR_SID_VALUE_TYPE_ABSOLUTE) {
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_VALUE);
+               SET_FLAG(psid->flags, ISIS_PREFIX_SID_LOCAL);
        }
 }
 
 /**
- * Once a route is updated in the SPT, reinstall or uninstall its corresponding
- * Prefix-SID (if any).
+ * Delete all backup Adj-SIDs.
  *
- * @param area         IS-IS area
- * @param prefix       Prefix to be updated
- * @param route_info   New Route Information
- *
- * @return             0
+ * @param area IS-IS area
+ * @param level        IS-IS level
  */
-static int sr_route_update(struct isis_area *area, struct prefix *prefix,
-                          struct isis_route_info *route_info)
+void isis_area_delete_backup_adj_sids(struct isis_area *area, int level)
 {
-       struct sr_prefix *srp;
-
-       if (!area->srdb.enabled)
-               return 0;
-
-       sr_debug("ISIS-Sr (%s): Update route for prefix %pFX", area->area_tag,
-                prefix);
-
-       /* Lookup to Segment Routing Prefix for this prefix */
-       switch (area->is_type) {
-       case IS_LEVEL_1:
-               srp = sr_prefix_find_by_area(area, ISIS_LEVEL1, prefix);
-               break;
-       case IS_LEVEL_2:
-               srp = sr_prefix_find_by_area(area, ISIS_LEVEL2, prefix);
-               break;
-       case IS_LEVEL_1_AND_2:
-               srp = sr_prefix_find_by_area(area, ISIS_LEVEL1, prefix);
-               if (!srp)
-                       srp = sr_prefix_find_by_area(area, ISIS_LEVEL2, prefix);
-               break;
-       default:
-               flog_err(EC_LIB_DEVELOPMENT, "%s: unknown area level",
-                        __func__);
-               exit(1);
-       }
-
-       /* Skip NULL or local Segment Routing Prefix */
-       if (!srp || srp->type == ISIS_SR_PREFIX_LOCAL)
-               return 0;
-
-       /* Install or unintall Prefix-SID if route is Active or not */
-       if (CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ACTIVE)) {
-               /*
-                * The Prefix-SID input label hasn't changed. We could use the
-                * "Make Before Break" option. Zebra layer will update output
-                * label by adding new label(s) before removing old one(s).
-                */
-               sr_prefix_reinstall(srp, true);
-               srp->u.remote.rinfo = route_info;
-       } else {
-               sr_prefix_uninstall(srp);
-               srp->u.remote.rinfo = NULL;
-       }
+       struct sr_adjacency *sra;
+       struct listnode *node, *nnode;
 
-       return 0;
+       for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra))
+               if (sra->type == ISIS_SR_LAN_BACKUP
+                   && (sra->adj->level & level))
+                       sr_adj_sid_del(sra);
 }
 
 /* --- Segment Routing Local Block management functions --------------------- */
@@ -1499,12 +628,13 @@ static int sr_local_block_release_label(struct sr_local_block *srlb,
 /**
  * Add new local Adjacency-SID.
  *
- * @param adj    IS-IS Adjacency
- * @param family  Inet Family (IPv4 or IPv6)
- * @param backup  True to initialize backup Adjacency SID
+ * @param adj     IS-IS Adjacency
+ * @param family   Inet Family (IPv4 or IPv6)
+ * @param backup   True to initialize backup Adjacency SID
+ * @param nexthops List of backup nexthops (for backup Adj-SIDs only)
  */
-static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
-                                 bool backup)
+void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup,
+                          struct list *nexthops)
 {
        struct isis_circuit *circuit = adj->circuit;
        struct isis_area *area = circuit->area;
@@ -1555,9 +685,25 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
 
        sra = XCALLOC(MTYPE_ISIS_SR_INFO, sizeof(*sra));
        sra->type = backup ? ISIS_SR_LAN_BACKUP : ISIS_SR_ADJ_NORMAL;
+       sra->input_label = input_label;
        sra->nexthop.family = family;
        sra->nexthop.address = nexthop;
-       sra->nexthop.label = input_label;
+
+       if (backup && nexthops) {
+               struct isis_vertex_adj *vadj;
+               struct listnode *node;
+
+               sra->backup_nexthops = list_new();
+               for (ALL_LIST_ELEMENTS_RO(nexthops, node, vadj)) {
+                       struct isis_adjacency *adj = vadj->sadj->adj;
+                       struct mpls_label_stack *label_stack;
+
+                       label_stack = vadj->label_stack;
+                       adjinfo2nexthop(family, sra->backup_nexthops, adj, NULL,
+                                       label_stack);
+               }
+       }
+
        switch (circuit->circ_type) {
        /* LAN Adjacency-SID for Broadcast interface section #2.2.2 */
        case CIRCUIT_T_BROADCAST:
@@ -1603,8 +749,7 @@ static void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
  */
 static void sr_adj_sid_add(struct isis_adjacency *adj, int family)
 {
-       sr_adj_sid_add_single(adj, family, false);
-       sr_adj_sid_add_single(adj, family, true);
+       sr_adj_sid_add_single(adj, family, false, NULL);
 }
 
 static void sr_adj_sid_update(struct sr_adjacency *sra,
@@ -1616,16 +761,16 @@ static void sr_adj_sid_update(struct sr_adjacency *sra,
        isis_zebra_send_adjacency_sid(ZEBRA_MPLS_LABELS_DELETE, sra);
 
        /* Got new label in the new SRLB */
-       sra->nexthop.label = sr_local_block_request_label(srlb);
-       if (sra->nexthop.label == MPLS_INVALID_LABEL)
+       sra->input_label = sr_local_block_request_label(srlb);
+       if (sra->input_label == MPLS_INVALID_LABEL)
                return;
 
        switch (circuit->circ_type) {
        case CIRCUIT_T_BROADCAST:
-               sra->u.ladj_sid->sid = sra->nexthop.label;
+               sra->u.ladj_sid->sid = sra->input_label;
                break;
        case CIRCUIT_T_P2P:
-               sra->u.adj_sid->sid = sra->nexthop.label;
+               sra->u.adj_sid->sid = sra->input_label;
                break;
        default:
                flog_warn(EC_LIB_DEVELOPMENT, "%s: unexpected circuit type: %u",
@@ -1669,12 +814,38 @@ static void sr_adj_sid_del(struct sr_adjacency *sra)
                exit(1);
        }
 
+       if (sra->type == ISIS_SR_LAN_BACKUP && sra->backup_nexthops) {
+               sra->backup_nexthops->del =
+                       (void (*)(void *))isis_nexthop_delete;
+               list_delete(&sra->backup_nexthops);
+       }
+
        /* Remove Adjacency-SID from the SRDB */
        listnode_delete(area->srdb.adj_sids, sra);
        listnode_delete(sra->adj->adj_sids, sra);
        XFREE(MTYPE_ISIS_SR_INFO, sra);
 }
 
+/**
+ * Lookup Segment Routing Adj-SID by family and type.
+ *
+ * @param adj    IS-IS Adjacency
+ * @param family  Inet Family (IPv4 or IPv6)
+ * @param type    Adjacency SID type
+ */
+struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj,
+                                         int family, enum sr_adj_type type)
+{
+       struct sr_adjacency *sra;
+       struct listnode *node;
+
+       for (ALL_LIST_ELEMENTS_RO(adj->adj_sids, node, sra))
+               if (sra->nexthop.family == family && sra->type == type)
+                       return sra;
+
+       return NULL;
+}
+
 /**
  * Remove all Adjacency-SIDs associated to an adjacency that is going down.
  *
@@ -1778,7 +949,7 @@ static int sr_if_new_hook(struct interface *ifp)
                        continue;
 
                if (sr_prefix_is_node_sid(ifp, &pcfg->prefix)
-                   && !pcfg->node_sid) {
+                   && !pcfg->n_flag_clear) {
                        pcfg->node_sid = true;
                        lsp_regenerate_schedule(area, area->is_type, 0);
                }
@@ -1787,20 +958,18 @@ static int sr_if_new_hook(struct interface *ifp)
        return 0;
 }
 
-/* --- Segment Routing Show information functions --------------------------- */
-
 /**
  * Show LFIB operation in human readable format.
  *
- * @param buf       Buffer to store string output. Must be pre-allocate
- * @param size      Size of the buffer
- * @param label_in   Input Label
- * @param label_out  Output Label
+ * @param buf        Buffer to store string output. Must be pre-allocate
+ * @param size       Size of the buffer
+ * @param label_in    Input Label
+ * @param label_out   Output Label
  *
  * @return          String containing LFIB operation in human readable format
  */
-static char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
-                      mpls_label_t label_out)
+char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
+               mpls_label_t label_out)
 {
        if (size < 24)
                return NULL;
@@ -1828,205 +997,6 @@ static char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
        return buf;
 }
 
-/**
- * Show Local Prefix-SID.
- *
- * @param vty  VTY output
- * @param tt   Table format
- * @param area IS-IS area
- * @param srp  Segment Routing Prefix
- */
-static void show_prefix_sid_local(struct vty *vty, struct ttable *tt,
-                                 const struct isis_area *area,
-                                 const struct sr_prefix *srp)
-{
-       const struct sr_nexthop_info *srnh = &srp->u.local.info;
-       char buf_prefix[BUFSIZ];
-       char buf_oper[BUFSIZ];
-       char buf_iface[BUFSIZ];
-       char buf_uptime[BUFSIZ];
-
-       if (srnh->label != MPLS_INVALID_LABEL) {
-               struct interface *ifp;
-               ifp = if_lookup_prefix(&srp->prefix, VRF_DEFAULT);
-               if (ifp)
-                       strlcpy(buf_iface, ifp->name, sizeof(buf_iface));
-               else
-                       snprintf(buf_iface, sizeof(buf_iface), "-");
-               log_uptime(srnh->uptime, buf_uptime, sizeof(buf_uptime));
-       } else {
-               snprintf(buf_iface, sizeof(buf_iface), "-");
-               snprintf(buf_uptime, sizeof(buf_uptime), "-");
-       }
-       sr_op2str(buf_oper, sizeof(buf_oper), srp->input_label,
-                 MPLS_LABEL_IMPLICIT_NULL);
-
-       ttable_add_row(tt, "%s|%u|%s|-|%s|%s",
-                      prefix2str(&srp->prefix, buf_prefix, sizeof(buf_prefix)),
-                      srp->sid.value, buf_oper, buf_iface, buf_uptime);
-}
-
-/**
- * Show Remote Prefix-SID.
- *
- * @param vty  VTY output
- * @param tt   Table format
- * @param area IS-IS area
- * @param srp  Segment Routing Prefix
- */
-static void show_prefix_sid_remote(struct vty *vty, struct ttable *tt,
-                                  const struct isis_area *area,
-                                  const struct sr_prefix *srp)
-{
-       struct isis_nexthop *nexthop;
-       struct listnode *node;
-       char buf_prefix[BUFSIZ];
-       char buf_oper[BUFSIZ];
-       char buf_nhop[BUFSIZ];
-       char buf_iface[BUFSIZ];
-       char buf_uptime[BUFSIZ];
-       bool first = true;
-
-       (void)prefix2str(&srp->prefix, buf_prefix, sizeof(buf_prefix));
-
-       if (!srp->u.remote.rinfo) {
-               ttable_add_row(tt, "%s|%u|%s|-|-|-", buf_prefix, srp->sid.value,
-                              sr_op2str(buf_oper, sizeof(buf_oper),
-                                        srp->input_label,
-                                        MPLS_LABEL_IMPLICIT_NULL));
-               return;
-       }
-
-       for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node,
-                                 nexthop)) {
-               struct interface *ifp;
-
-               inet_ntop(nexthop->family, &nexthop->ip, buf_nhop,
-                         sizeof(buf_nhop));
-               ifp = if_lookup_by_index(nexthop->ifindex, VRF_DEFAULT);
-               if (ifp)
-                       strlcpy(buf_iface, ifp->name, sizeof(buf_iface));
-               else
-                       snprintf(buf_iface, sizeof(buf_iface), "ifindex %u",
-                                nexthop->ifindex);
-               if (nexthop->sr.label == MPLS_INVALID_LABEL)
-                       snprintf(buf_uptime, sizeof(buf_uptime), "-");
-               else
-                       log_uptime(nexthop->sr.uptime, buf_uptime,
-                                  sizeof(buf_uptime));
-               sr_op2str(buf_oper, sizeof(buf_oper), srp->input_label,
-                         nexthop->sr.label);
-
-               if (first)
-                       ttable_add_row(tt, "%s|%u|%s|%s|%s|%s", buf_prefix,
-                                      srp->sid.value, buf_oper, buf_nhop,
-                                      buf_iface, buf_uptime);
-               else
-                       ttable_add_row(tt, "|||%s|%s|%s|%s", buf_oper, buf_nhop,
-                                      buf_iface, buf_uptime);
-               first = false;
-       }
-}
-
-/**
- * Show Prefix-SIDs.
- *
- * @param vty  VTY output
- * @param area IS-IS area
- * @param level        IS-IS level
- */
-static void show_prefix_sids(struct vty *vty, struct isis_area *area, int level)
-{
-       struct sr_prefix *srp;
-       struct ttable *tt;
-
-       if (srdb_area_prefix_count(&area->srdb.prefix_sids[level - 1]) == 0)
-               return;
-
-       vty_out(vty, " IS-IS %s Prefix-SIDs:\n\n", circuit_t2string(level));
-
-       /* Prepare table. */
-       tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
-       ttable_add_row(tt, "Prefix|SID|Label Op.|Nexthop|Interface|Uptime");
-       tt->style.cell.rpad = 2;
-       tt->style.corner = '+';
-       ttable_restyle(tt);
-       ttable_rowseps(tt, 0, BOTTOM, true, '-');
-
-       /* Process all Prefix-SID from the SRDB */
-       frr_each (srdb_area_prefix, &area->srdb.prefix_sids[level - 1], srp) {
-               switch (srp->type) {
-               case ISIS_SR_PREFIX_LOCAL:
-                       show_prefix_sid_local(vty, tt, area, srp);
-                       break;
-               case ISIS_SR_PREFIX_REMOTE:
-                       show_prefix_sid_remote(vty, tt, area, srp);
-                       break;
-               }
-       }
-
-       /* Dump the generated table. */
-       if (tt->nrows > 1) {
-               char *table;
-
-               table = ttable_dump(tt, "\n");
-               vty_out(vty, "%s\n", table);
-               XFREE(MTYPE_TMP, table);
-       }
-       ttable_del(tt);
-}
-
-/**
- * Declaration of new show commands.
- */
-DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
-      "show isis [vrf <NAME|all>] segment-routing prefix-sids",
-      SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
-      "All VRFs\n"
-      "Segment-Routing\n"
-      "Segment-Routing Prefix-SIDs\n")
-{
-       struct listnode *node, *inode;
-       struct isis_area *area;
-       struct isis *isis = NULL;
-       const char *vrf_name = VRF_DEFAULT_NAME;
-       bool all_vrf = false;
-       int idx_vrf = 0;
-
-       ISIS_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
-       if (vrf_name) {
-               if (all_vrf) {
-                       for (ALL_LIST_ELEMENTS_RO(im->isis, inode, isis)) {
-                               for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
-                                                         area)) {
-                                       vty_out(vty, "Area %s:\n",
-                                               area->area_tag ? area->area_tag
-                                                              : "null");
-                                       for (int level = ISIS_LEVEL1;
-                                            level <= ISIS_LEVELS; level++)
-                                               show_prefix_sids(vty, area,
-                                                                level);
-                               }
-                       }
-                       return 0;
-               }
-               isis = isis_lookup_by_vrfname(vrf_name);
-               if (isis != NULL) {
-                       for (ALL_LIST_ELEMENTS_RO(isis->area_list, node,
-                                                 area)) {
-                               vty_out(vty, "Area %s:\n",
-                                       area->area_tag ? area->area_tag
-                                                      : "null");
-                               for (int level = ISIS_LEVEL1;
-                                    level <= ISIS_LEVELS; level++)
-                                       show_prefix_sids(vty, area, level);
-                       }
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
 /**
  * Show Segment Routing Node.
  *
@@ -2036,13 +1006,10 @@ DEFUN(show_sr_prefix_sids, show_sr_prefix_sids_cmd,
  */
 static void show_node(struct vty *vty, struct isis_area *area, int level)
 {
-       struct sr_node *srn;
+       struct isis_lsp *lsp;
        struct ttable *tt;
 
-       if (srdb_area_prefix_count(&area->srdb.prefix_sids[level - 1]) == 0)
-               return;
-
-       vty_out(vty, " IS-IS %s SR-Node:\n\n", circuit_t2string(level));
+       vty_out(vty, " IS-IS %s SR-Nodes:\n\n", circuit_t2string(level));
 
        /* Prepare table. */
        tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]);
@@ -2052,19 +1019,23 @@ static void show_node(struct vty *vty, struct isis_area *area, int level)
        ttable_restyle(tt);
        ttable_rowseps(tt, 0, BOTTOM, true, '-');
 
-       /* Process all SR-Node from the SRDB */
-       frr_each (srdb_node, &area->srdb.sr_nodes[level - 1], srn) {
+       frr_each (lspdb, &area->lspdb[level - 1], lsp) {
+               struct isis_router_cap *cap;
+
+               if (!lsp->tlvs)
+                       continue;
+               cap = lsp->tlvs->router_cap;
+               if (!cap)
+                       continue;
+
                ttable_add_row(
                        tt, "%s|%u - %u|%u - %u|%s|%u",
-                       sysid_print(srn->sysid),
-                       srn->cap.srgb.lower_bound,
-                       srn->cap.srgb.lower_bound + srn->cap.srgb.range_size
-                               - 1,
-                       srn->cap.srlb.lower_bound,
-                       srn->cap.srlb.lower_bound + srn->cap.srlb.range_size
-                               - 1,
-                       srn->cap.algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF",
-                       srn->cap.msd);
+                       sysid_print(lsp->hdr.lsp_id), cap->srgb.lower_bound,
+                       cap->srgb.lower_bound + cap->srgb.range_size - 1,
+                       cap->srlb.lower_bound,
+                       cap->srlb.lower_bound + cap->srlb.range_size - 1,
+                       cap->algo[0] == SR_ALGORITHM_SPF ? "SPF" : "S-SPF",
+                       cap->msd);
        }
 
        /* Dump the generated table. */
@@ -2102,7 +1073,6 @@ DEFUN(show_sr_node, show_sr_node_cmd,
        return CMD_SUCCESS;
 }
 
-
 /* --- IS-IS Segment Routing Management function ---------------------------- */
 
 /**
@@ -2202,22 +1172,12 @@ void isis_sr_stop(struct isis_area *area)
                 area->area_tag);
 
        /* Disable any re-attempt to connect to Label Manager */
-       THREAD_TIMER_OFF(srdb->t_start_lm);
+       thread_cancel(&srdb->t_start_lm);
 
        /* Uninstall all local Adjacency-SIDs. */
        for (ALL_LIST_ELEMENTS(area->srdb.adj_sids, node, nnode, sra))
                sr_adj_sid_del(sra);
 
-       /* Uninstall all Prefix-SIDs from all SR Node. */
-       for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
-               while (srdb_node_count(&srdb->sr_nodes[level - 1]) > 0) {
-                       struct sr_node *srn;
-
-                       srn = srdb_node_first(&srdb->sr_nodes[level - 1]);
-                       sr_node_del(area, level, srn);
-               }
-       }
-
        /* Release SRGB if active. */
        if (srdb->srgb_active) {
                isis_zebra_release_label_range(srdb->config.srgb_lower_bound,
@@ -2250,11 +1210,6 @@ void isis_sr_area_init(struct isis_area *area)
        memset(srdb, 0, sizeof(*srdb));
        srdb->adj_sids = list_new();
 
-       for (int level = ISIS_LEVEL1; level <= ISIS_LEVELS; level++) {
-               srdb_node_init(&srdb->sr_nodes[level - 1]);
-               srdb_area_prefix_init(&srdb->prefix_sids[level - 1]);
-       }
-
        /* Pull defaults from the YANG module. */
 #ifndef FABRICD
        srdb->config.enabled = yang_get_default_bool("%s/enabled", ISIS_SR);
@@ -2304,14 +1259,12 @@ void isis_sr_area_term(struct isis_area *area)
  */
 void isis_sr_init(void)
 {
-       install_element(VIEW_NODE, &show_sr_prefix_sids_cmd);
        install_element(VIEW_NODE, &show_sr_node_cmd);
 
        /* Register hooks. */
        hook_register(isis_adj_state_change_hook, sr_adj_state_change);
        hook_register(isis_adj_ip_enabled_hook, sr_adj_ip_enabled);
        hook_register(isis_adj_ip_disabled_hook, sr_adj_ip_disabled);
-       hook_register(isis_route_update_hook, sr_route_update);
        hook_register(isis_if_new_hook, sr_if_new_hook);
 }
 
@@ -2324,6 +1277,5 @@ void isis_sr_term(void)
        hook_unregister(isis_adj_state_change_hook, sr_adj_state_change);
        hook_unregister(isis_adj_ip_enabled_hook, sr_adj_ip_enabled);
        hook_unregister(isis_adj_ip_disabled_hook, sr_adj_ip_disabled);
-       hook_unregister(isis_route_update_hook, sr_route_update);
        hook_unregister(isis_if_new_hook, sr_if_new_hook);
 }
index 4379a1dcba611700c61a37571184f9a7866f37c1..b012dfb00a03e50a0ff9dfff44755074d801504c 100644 (file)
 #define SRLB_UPPER_BOUND               15999
 
 /* Segment Routing Data Base (SRDB) RB-Tree structure */
-PREDECL_RBTREE_UNIQ(srdb_node)
-PREDECL_RBTREE_UNIQ(srdb_node_prefix)
-PREDECL_RBTREE_UNIQ(srdb_area_prefix)
 PREDECL_RBTREE_UNIQ(srdb_prefix_cfg)
 
+/*
+ * Segment Routing Prefix-SID information.
+ *
+ * This structure is intended to be embedded inside other structures that
+ * might or might not contain Prefix-SID information.
+ */
+struct isis_sr_psid_info {
+       /* Prefix-SID Sub-TLV information. */
+       struct isis_prefix_sid sid;
+
+       /* Resolved input/output label. */
+       mpls_label_t label;
+
+       /* Indicates whether the Prefix-SID is present or not. */
+       bool present;
+};
+
 /* Segment Routing Local Block allocation */
 struct sr_local_block {
        bool active;
@@ -84,13 +98,18 @@ struct sr_adjacency {
        /* Adjacency type. */
        enum sr_adj_type type;
 
+       /* Adjacency-SID input label. */
+       mpls_label_t input_label;
+
        /* Adjacency-SID nexthop information. */
        struct {
                int family;
                union g_addr address;
-               mpls_label_t label;
        } nexthop;
 
+       /* Adjacency-SID TI-LFA backup nexthops. */
+       struct list *backup_nexthops;
+
        /* (LAN-)Adjacency-SID Sub-TLV. */
        union {
                struct isis_adj_sid *adj_sid;
@@ -101,85 +120,6 @@ struct sr_adjacency {
        struct isis_adjacency *adj;
 };
 
-/* Segment Routing Prefix-SID type. */
-enum sr_prefix_type {
-       ISIS_SR_PREFIX_LOCAL = 0,
-       ISIS_SR_PREFIX_REMOTE,
-};
-
-/* Segment Routing Nexthop Information. */
-struct sr_nexthop_info {
-       mpls_label_t label;
-       time_t uptime;
-};
-
-/* State of Object (SR-Node and SR-Prefix) stored in SRDB */
-enum srdb_state {
-       SRDB_STATE_VALIDATED = 0,
-       SRDB_STATE_NEW,
-       SRDB_STATE_MODIFIED,
-       SRDB_STATE_UNCHANGED
-};
-
-/* Segment Routing Prefix-SID. */
-struct sr_prefix {
-       /* SRDB RB-tree entries. */
-       struct srdb_node_prefix_item node_entry;
-       struct srdb_area_prefix_item area_entry;
-
-       /* IP prefix. */
-       struct prefix prefix;
-
-       /* SID value, algorithm and flags subTLVs. */
-       struct isis_prefix_sid sid;
-
-       /* Input label value. */
-       mpls_label_t input_label;
-
-       /* Prefix-SID type. */
-       enum sr_prefix_type type;
-       union {
-               struct {
-                       /* Information about this local Prefix-SID. */
-                       struct sr_nexthop_info info;
-               } local;
-               struct {
-                       /* Route associated to this remote Prefix-SID. */
-                       struct isis_route_info *rinfo;
-               } remote;
-       } u;
-
-       /* Backpointer to Segment Routing node. */
-       struct sr_node *srn;
-
-       /* SR-Prefix State used while the LSPDB is being parsed. */
-       enum srdb_state state;
-};
-
-/* Segment Routing node. */
-struct sr_node {
-       /* SRDB RB-tree entry. */
-       struct srdb_node_item entry;
-
-       /* IS-IS level: ISIS_LEVEL1 or ISIS_LEVEL2. */
-       int level;
-
-       /* IS-IS node identifier. */
-       uint8_t sysid[ISIS_SYS_ID_LEN];
-
-       /* Segment Routing node capabilities (SRGB, SR Algorithms) subTLVs. */
-       struct isis_router_cap cap;
-
-       /* List of Prefix-SIDs advertised by this node. */
-       struct srdb_node_prefix_head prefix_sids;
-
-       /* Backpointer to IS-IS area. */
-       struct isis_area *area;
-
-       /* SR-Node State used while the LSPDB is being parsed. */
-       enum srdb_state state;
-};
-
 /* SID type. NOTE: these values must be in sync with the YANG module. */
 enum sr_sid_value_type {
        SR_SID_VALUE_TYPE_INDEX = 0,
@@ -212,6 +152,9 @@ struct sr_prefix_cfg {
        /* SID last hop behavior. */
        enum sr_last_hop_behavior last_hop_behavior;
 
+       /* Indicates whether the node flag must be explicitly unset. */
+       bool n_flag_clear;
+
        /* Does this Prefix-SID refer to a loopback address (Node-SID)? */
        bool node_sid;
 
@@ -230,12 +173,6 @@ struct isis_sr_db {
        /* List of local Adjacency-SIDs. */
        struct list *adj_sids;
 
-       /* Segment Routing Node information per IS-IS level. */
-       struct srdb_node_head sr_nodes[ISIS_LEVELS];
-
-       /* Segment Routing Prefix-SIDs per IS-IS level. */
-       struct srdb_area_prefix_head prefix_sids[ISIS_LEVELS];
-
        /* Management of SRLB & SRGB allocation */
        struct sr_local_block srlb;
        bool srgb_active;
@@ -262,6 +199,14 @@ struct isis_sr_db {
 };
 
 /* Prototypes. */
+extern struct isis_sr_block *isis_sr_find_srgb(struct lspdb_head *lspdb,
+                                              const uint8_t *sysid);
+extern mpls_label_t sr_prefix_in_label(struct isis_area *area,
+                                      struct isis_prefix_sid *psid,
+                                      bool local);
+extern mpls_label_t sr_prefix_out_label(struct lspdb_head *lspdb, int family,
+                                       struct isis_prefix_sid *psid,
+                                       const uint8_t *nh_sysid, bool last_hop);
 extern int isis_sr_cfg_srgb_update(struct isis_area *area, uint32_t lower_bound,
                                   uint32_t upper_bound);
 extern int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
@@ -274,10 +219,14 @@ isis_sr_cfg_prefix_find(struct isis_area *area, union prefixconstptr prefix);
 extern void isis_sr_prefix_cfg2subtlv(const struct sr_prefix_cfg *pcfg,
                                      bool external,
                                      struct isis_prefix_sid *psid);
-extern void isis_sr_nexthop_update(struct sr_nexthop_info *srnh,
-                                  mpls_label_t label);
-extern void isis_sr_nexthop_reset(struct sr_nexthop_info *srnh);
-extern void isis_area_verify_sr(struct isis_area *area);
+extern void sr_adj_sid_add_single(struct isis_adjacency *adj, int family,
+                                 bool backup, struct list *nexthops);
+extern struct sr_adjacency *isis_sr_adj_sid_find(struct isis_adjacency *adj,
+                                                int family,
+                                                enum sr_adj_type type);
+extern void isis_area_delete_backup_adj_sids(struct isis_area *area, int level);
+extern char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
+                      mpls_label_t label_out);
 extern int isis_sr_start(struct isis_area *area);
 extern void isis_sr_stop(struct isis_area *area);
 extern void isis_sr_area_init(struct isis_area *area);
index 87c44281558b31dcf8944adac98add6099d77e98..8daa2b36bfb3629bcff468368744e43ba5f5efcd 100644 (file)
@@ -336,10 +336,8 @@ DEFUN(show_isis_mpls_te_router,
                                        if (ntohs(area->mta->router_id.s_addr)
                                            != 0)
                                                vty_out(vty,
-                                                       "  MPLS-TE Router-Address: %s\n",
-                                                       inet_ntoa(
-                                                               area->mta
-                                                                       ->router_id));
+                                                       "  MPLS-TE Router-Address: %pI4\n",
+                                                       &area->mta->router_id);
                                        else
                                                vty_out(vty, "  N/A\n");
                                }
@@ -357,9 +355,8 @@ DEFUN(show_isis_mpls_te_router,
                                vty_out(vty, "Area %s:\n", area->area_tag);
                                if (ntohs(area->mta->router_id.s_addr) != 0)
                                        vty_out(vty,
-                                               "  MPLS-TE Router-Address: %s\n",
-                                               inet_ntoa(
-                                                       area->mta->router_id));
+                                               "  MPLS-TE Router-Address: %pI4\n",
+                                               &area->mta->router_id);
                                else
                                        vty_out(vty, "  N/A\n");
                        }
@@ -394,11 +391,11 @@ static void show_ext_sub(struct vty *vty, char *name,
                          ext->remote_llri);
        }
        if (IS_SUBTLV(ext, EXT_LOCAL_ADDR))
-               sbuf_push(&buf, 4, "Local Interface IP Address(es): %s\n",
-                         inet_ntoa(ext->local_addr));
+               sbuf_push(&buf, 4, "Local Interface IP Address(es): %pI4\n",
+                         &ext->local_addr);
        if (IS_SUBTLV(ext, EXT_NEIGH_ADDR))
-               sbuf_push(&buf, 4, "Remote Interface IP Address(es): %s\n",
-                         inet_ntoa(ext->neigh_addr));
+               sbuf_push(&buf, 4, "Remote Interface IP Address(es): %pI4\n",
+                         &ext->neigh_addr);
        if (IS_SUBTLV(ext, EXT_LOCAL_ADDR6))
                sbuf_push(&buf, 4, "Local Interface IPv6 Address(es): %s\n",
                          inet_ntop(AF_INET6, &ext->local_addr6, ibuf,
@@ -432,8 +429,8 @@ static void show_ext_sub(struct vty *vty, char *name,
                          ext->remote_as);
        if (IS_SUBTLV(ext, EXT_RMT_IP))
                sbuf_push(&buf, 4,
-                         "Inter-AS TE Remote ASBR IP address: %s\n",
-                         inet_ntoa(ext->remote_ip));
+                         "Inter-AS TE Remote ASBR IP address: %pI4\n",
+                         &ext->remote_ip);
        if (IS_SUBTLV(ext, EXT_DELAY))
                sbuf_push(&buf, 4,
                          "%s Average Link Delay: %u (micro-sec)\n",
index a1f9cc236ff75d4df146c99dca7d822410a7d333..af419961d56fb7974306de28ec3b6a23a20e7471 100644 (file)
@@ -209,11 +209,11 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
                          exts->remote_llri);
        }
        if (IS_SUBTLV(exts, EXT_LOCAL_ADDR))
-               sbuf_push(buf, indent, "Local Interface IP Address(es): %s\n",
-                         inet_ntoa(exts->local_addr));
+               sbuf_push(buf, indent, "Local Interface IP Address(es): %pI4\n",
+                         &exts->local_addr);
        if (IS_SUBTLV(exts, EXT_NEIGH_ADDR))
-               sbuf_push(buf, indent, "Remote Interface IP Address(es): %s\n",
-                         inet_ntoa(exts->neigh_addr));
+               sbuf_push(buf, indent, "Remote Interface IP Address(es): %pI4\n",
+                         &exts->neigh_addr);
        if (IS_SUBTLV(exts, EXT_LOCAL_ADDR6))
                sbuf_push(buf, indent, "Local Interface IPv6 Address(es): %s\n",
                        inet_ntop(AF_INET6, &exts->local_addr6, ibuf,
@@ -247,8 +247,8 @@ static void format_item_ext_subtlvs(struct isis_ext_subtlvs *exts,
                          exts->remote_as);
        if (IS_SUBTLV(exts, EXT_RMT_IP))
                sbuf_push(buf, indent,
-                         "Inter-AS TE Remote ASBR IP address: %s\n",
-                         inet_ntoa(exts->remote_ip));
+                         "Inter-AS TE Remote ASBR IP address: %pI4\n",
+                         &exts->remote_ip);
        /* Extended metrics */
        if (IS_SUBTLV(exts, EXT_DELAY))
                sbuf_push(buf, indent,
@@ -2400,11 +2400,11 @@ static int unpack_tlv_threeway_adj(enum isis_tlv_context context,
 }
 
 /* Functions related to TLVs 236/237 IPv6/MT-IPv6 reach */
-
 static struct isis_item *copy_item_ipv6_reach(struct isis_item *i)
 {
        struct isis_ipv6_reach *r = (struct isis_ipv6_reach *)i;
        struct isis_ipv6_reach *rv = XCALLOC(MTYPE_ISIS_TLV, sizeof(*rv));
+
        rv->metric = r->metric;
        rv->down = r->down;
        rv->external = r->external;
@@ -2573,11 +2573,13 @@ out:
 static struct isis_router_cap *copy_tlv_router_cap(
                               const struct isis_router_cap *router_cap)
 {
-       struct isis_router_cap *rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv));
+       struct isis_router_cap *rv;
 
        if (!router_cap)
                return NULL;
 
+       rv = XMALLOC(MTYPE_ISIS_TLV, sizeof(*rv));
+
        memcpy(rv, router_cap, sizeof(*rv));
 
        return rv;
@@ -2603,8 +2605,8 @@ static void format_tlv_router_cap(const struct isis_router_cap *router_cap,
                sbuf_push(
                        buf, indent,
                        "  Segment Routing: I:%s V:%s, Global Block Base: %u Range: %u\n",
-                       IS_SR_IPV4(router_cap->srgb) ? "1" : "0",
-                       IS_SR_IPV6(router_cap->srgb) ? "1" : "0",
+                       IS_SR_IPV4(&router_cap->srgb) ? "1" : "0",
+                       IS_SR_IPV6(&router_cap->srgb) ? "1" : "0",
                        router_cap->srgb.lower_bound,
                        router_cap->srgb.range_size);
 
@@ -4412,11 +4414,19 @@ static void tlvs_area_addresses_to_adj(struct isis_tlvs *tlvs,
                                       bool *changed)
 {
        if (adj->area_address_count != tlvs->area_addresses.count) {
+               uint32_t oc = adj->area_address_count;
+
                *changed = true;
                adj->area_address_count = tlvs->area_addresses.count;
                adj->area_addresses = XREALLOC(
                        MTYPE_ISIS_ADJACENCY_INFO, adj->area_addresses,
                        adj->area_address_count * sizeof(*adj->area_addresses));
+
+               for (; oc < adj->area_address_count; oc++) {
+                       adj->area_addresses[oc].addr_len = 0;
+                       memset(&adj->area_addresses[oc].area_addr, 0,
+                              sizeof(adj->area_addresses[oc].area_addr));
+               }
        }
 
        struct isis_area_address *addr = NULL;
@@ -4494,11 +4504,18 @@ static void tlvs_ipv4_addresses_to_adj(struct isis_tlvs *tlvs,
                hook_call(isis_adj_ip_disabled_hook, adj, AF_INET);
 
        if (adj->ipv4_address_count != tlvs->ipv4_address.count) {
+               uint32_t oc = adj->ipv4_address_count;
+
                *changed = true;
                adj->ipv4_address_count = tlvs->ipv4_address.count;
                adj->ipv4_addresses = XREALLOC(
                        MTYPE_ISIS_ADJACENCY_INFO, adj->ipv4_addresses,
                        adj->ipv4_address_count * sizeof(*adj->ipv4_addresses));
+
+               for (; oc < adj->ipv4_address_count; oc++) {
+                       memset(&adj->ipv4_addresses[oc], 0,
+                              sizeof(adj->ipv4_addresses[oc]));
+               }
        }
 
        struct isis_ipv4_address *addr = NULL;
@@ -4533,11 +4550,18 @@ static void tlvs_ipv6_addresses_to_adj(struct isis_tlvs *tlvs,
                hook_call(isis_adj_ip_disabled_hook, adj, AF_INET6);
 
        if (adj->ipv6_address_count != tlvs->ipv6_address.count) {
+               uint32_t oc = adj->ipv6_address_count;
+
                *changed = true;
                adj->ipv6_address_count = tlvs->ipv6_address.count;
                adj->ipv6_addresses = XREALLOC(
                        MTYPE_ISIS_ADJACENCY_INFO, adj->ipv6_addresses,
                        adj->ipv6_address_count * sizeof(*adj->ipv6_addresses));
+
+               for (; oc < adj->ipv6_address_count; oc++) {
+                       memset(&adj->ipv6_addresses[oc], 0,
+                              sizeof(adj->ipv6_addresses[oc]));
+               }
        }
 
        struct isis_ipv6_address *addr = NULL;
index 1c0d97f2c39684f99082a55010a9e78c84c50486..54ded8121d740a9c0b6b498bb421c8791d7a1f50 100644 (file)
@@ -138,8 +138,8 @@ struct isis_threeway_adj {
 /* Segment Routing subTLV's as per RFC8667 */
 #define ISIS_SUBTLV_SRGB_FLAG_I                0x80
 #define ISIS_SUBTLV_SRGB_FLAG_V                0x40
-#define IS_SR_IPV4(srgb)               (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_I)
-#define IS_SR_IPV6(srgb)               (srgb.flags & ISIS_SUBTLV_SRGB_FLAG_V)
+#define IS_SR_IPV4(srgb)               ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_I)
+#define IS_SR_IPV6(srgb)               ((srgb)->flags & ISIS_SUBTLV_SRGB_FLAG_V)
 #define SUBTLV_SR_BLOCK_SIZE            6
 #define SUBTLV_RANGE_INDEX_SIZE         10
 #define SUBTLV_RANGE_LABEL_SIZE         9
index 1424b55bdce4580f88a356f2e912504173de4121..5c87e39157df4df8dc613b1a236ff7fb30260393 100644 (file)
@@ -93,8 +93,7 @@ static void tx_queue_element_free(void *element)
 {
        struct isis_tx_queue_entry *e = element;
 
-       if (e->retry)
-               thread_cancel(e->retry);
+       thread_cancel(&(e->retry));
 
        XFREE(MTYPE_TX_QUEUE_ENTRY, e);
 }
@@ -166,8 +165,7 @@ void _isis_tx_queue_add(struct isis_tx_queue *queue,
 
        e->type = type;
 
-       if (e->retry)
-               thread_cancel(e->retry);
+       thread_cancel(&(e->retry));
        thread_add_event(master, tx_queue_send_event, e, 0, &e->retry);
 
        e->is_retry = false;
@@ -190,8 +188,7 @@ void _isis_tx_queue_del(struct isis_tx_queue *queue, struct isis_lsp *lsp,
                           func, file, line);
        }
 
-       if (e->retry)
-               thread_cancel(e->retry);
+       thread_cancel(&(e->retry));
 
        hash_release(queue->hash, e);
        XFREE(MTYPE_TX_QUEUE_ENTRY, e);
index 15b51589ae3ddce24e1eb18dda7d2500da5a3efa..805ede1e44593c24e68f6f63f7405556e44c8762 100644 (file)
@@ -85,9 +85,8 @@ static int isis_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
 
 static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
 {
+       struct isis_circuit *circuit;
        struct connected *c;
-       struct prefix *p;
-       char buf[PREFIX2STR_BUFFER];
 
        c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
                                         zclient->ibuf, vrf_id);
@@ -95,29 +94,26 @@ static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
        if (c == NULL)
                return 0;
 
-       p = c->address;
-
-       prefix2str(p, buf, sizeof(buf));
 #ifdef EXTREME_DEBUG
        if (p->family == AF_INET)
-               zlog_debug("connected IP address %s", buf);
+               zlog_debug("connected IP address %pFX", c->address);
        if (p->family == AF_INET6)
-               zlog_debug("connected IPv6 address %s", buf);
+               zlog_debug("connected IPv6 address %pFX", c->address);
 #endif /* EXTREME_DEBUG */
-       if (if_is_operative(c->ifp))
-               isis_circuit_add_addr(circuit_scan_by_ifp(c->ifp), c);
+
+       if (if_is_operative(c->ifp)) {
+               circuit = circuit_scan_by_ifp(c->ifp);
+               if (circuit)
+                       isis_circuit_add_addr(circuit, c);
+       }
 
        return 0;
 }
 
 static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
 {
+       struct isis_circuit *circuit;
        struct connected *c;
-       struct interface *ifp;
-#ifdef EXTREME_DEBUG
-       struct prefix *p;
-       char buf[PREFIX2STR_BUFFER];
-#endif /* EXTREME_DEBUG */
 
        c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
                                         zclient->ibuf, vrf_id);
@@ -125,20 +121,19 @@ static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
        if (c == NULL)
                return 0;
 
-       ifp = c->ifp;
-
 #ifdef EXTREME_DEBUG
-       p = c->address;
-       prefix2str(p, buf, sizeof(buf));
-
        if (p->family == AF_INET)
-               zlog_debug("disconnected IP address %s", buf);
+               zlog_debug("disconnected IP address %pFX", c->address);
        if (p->family == AF_INET6)
-               zlog_debug("disconnected IPv6 address %s", buf);
+               zlog_debug("disconnected IPv6 address %pFX", c->address);
 #endif /* EXTREME_DEBUG */
 
-       if (if_is_operative(ifp))
-               isis_circuit_del_addr(circuit_scan_by_ifp(ifp), c);
+       if (if_is_operative(c->ifp)) {
+               circuit = circuit_scan_by_ifp(c->ifp);
+               if (circuit)
+                       isis_circuit_del_addr(circuit, c);
+       }
+
        connected_free(&c);
 
        return 0;
@@ -159,42 +154,27 @@ static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
        return 0;
 }
 
-void isis_zebra_route_add_route(struct isis *isis,
-                               struct prefix *prefix,
-                               struct prefix_ipv6 *src_p,
-                               struct isis_route_info *route_info)
+enum isis_zebra_nexthop_type {
+       ISIS_NEXTHOP_MAIN = 0,
+       ISIS_NEXTHOP_BACKUP,
+};
+
+static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
+                                  struct zapi_nexthop zapi_nexthops[],
+                                  enum isis_zebra_nexthop_type type,
+                                  bool mpls_lsp, uint8_t backup_nhs)
 {
-       struct zapi_route api;
-       struct zapi_nexthop *api_nh;
        struct isis_nexthop *nexthop;
        struct listnode *node;
        int count = 0;
 
-       if (zclient->sock < 0)
-               return;
-
-       memset(&api, 0, sizeof(api));
-       api.vrf_id = isis->vrf_id;
-       api.type = PROTO_TYPE;
-       api.safi = SAFI_UNICAST;
-       api.prefix = *prefix;
-       if (src_p && src_p->prefixlen) {
-               api.src_prefix = *src_p;
-               SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
-       }
-       SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
-       SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
-       api.metric = route_info->cost;
-#if 0
-       SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
-       api.distance = route_info->depth;
-#endif
-
        /* Nexthops */
-       for (ALL_LIST_ELEMENTS_RO(route_info->nexthops, node, nexthop)) {
+       for (ALL_LIST_ELEMENTS_RO(nexthops, node, nexthop)) {
+               struct zapi_nexthop *api_nh;
+
                if (count >= MULTIPATH_NUM)
                        break;
-               api_nh = &api.nexthops[count];
+               api_nh = &zapi_nexthops[count];
                if (fabricd)
                        SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_ONLINK);
                api_nh->vrf_id = isis->vrf_id;
@@ -225,11 +205,97 @@ void isis_zebra_route_add_route(struct isis *isis,
                }
 
                api_nh->ifindex = nexthop->ifindex;
+
+               /* Add MPLS label(s). */
+               switch (type) {
+               case ISIS_NEXTHOP_MAIN:
+                       if (nexthop->sr.present) {
+                               api_nh->label_num = 1;
+                               api_nh->labels[0] = nexthop->sr.label;
+                       } else if (mpls_lsp)
+                               /*
+                                * Do not use non-SR enabled nexthops to prevent
+                                * broken LSPs from being formed.
+                                */
+                               continue;
+                       break;
+               case ISIS_NEXTHOP_BACKUP:
+                       if (nexthop->label_stack) {
+                               api_nh->label_num =
+                                       nexthop->label_stack->num_labels;
+                               memcpy(api_nh->labels,
+                                      nexthop->label_stack->label,
+                                      sizeof(mpls_label_t)
+                                              * api_nh->label_num);
+                       } else if (mpls_lsp) {
+                               /*
+                                * This is necessary because zebra requires
+                                * the nexthops of MPLS LSPs to be labeled.
+                                */
+                               api_nh->label_num = 1;
+                               api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
+                       }
+                       break;
+               }
+
+               /* Backup nexthop handling. */
+               if (backup_nhs) {
+                       SET_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
+                       /*
+                        * If the backup has multiple nexthops, all of them
+                        * protect the same primary nexthop since ECMP routes
+                        * have no backups.
+                        */
+                       api_nh->backup_num = backup_nhs;
+                       for (int i = 0; i < backup_nhs; i++)
+                               api_nh->backup_idx[i] = i;
+               }
                count++;
        }
-       if (!count)
+
+       return count;
+}
+
+void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
+                               struct prefix_ipv6 *src_p,
+                               struct isis_route_info *route_info)
+{
+       struct zapi_route api;
+       int count = 0;
+
+       if (zclient->sock < 0 || list_isempty(route_info->nexthops))
                return;
 
+       memset(&api, 0, sizeof(api));
+       api.vrf_id = isis->vrf_id;
+       api.type = PROTO_TYPE;
+       api.safi = SAFI_UNICAST;
+       api.prefix = *prefix;
+       if (src_p && src_p->prefixlen) {
+               api.src_prefix = *src_p;
+               SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
+       }
+       SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
+       SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
+       api.metric = route_info->cost;
+
+       /* Add backup nexthops first. */
+       if (route_info->backup) {
+               count = isis_zebra_add_nexthops(
+                       isis, route_info->backup->nexthops, api.backup_nexthops,
+                       ISIS_NEXTHOP_BACKUP, false, 0);
+               if (count > 0) {
+                       SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
+                       api.backup_nexthop_num = count;
+               }
+       }
+
+       /* Add primary nexthops. */
+       count = isis_zebra_add_nexthops(isis, route_info->nexthops,
+                                       api.nexthops, ISIS_NEXTHOP_MAIN, false,
+                                       count);
+       if (!count)
+               return;
        api.nexthop_num = count;
 
        zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
@@ -259,30 +325,39 @@ void isis_zebra_route_del_route(struct isis *isis,
 }
 
 /**
- * Install Prefix-SID in the forwarding plane through Zebra.
+ * Install Prefix-SID label entry in the forwarding plane through Zebra.
  *
- * @param srp  Segment Routing Prefix-SID
+ * @param area         IS-IS area
+ * @param prefix       Route prefix
+ * @param rinfo                Route information
+ * @param psid         Prefix-SID information
  */
-static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
+void isis_zebra_prefix_sid_install(struct isis_area *area,
+                                  struct prefix *prefix,
+                                  struct isis_route_info *rinfo,
+                                  struct isis_sr_psid_info *psid)
 {
        struct zapi_labels zl;
-       struct zapi_nexthop *znh;
-       struct listnode *node;
-       struct isis_nexthop *nexthop;
-       struct interface *ifp;
+       int count = 0;
+
+       sr_debug("ISIS-Sr (%s): update label %u for prefix %pFX",
+                area->area_tag, psid->label, prefix);
 
        /* Prepare message. */
        memset(&zl, 0, sizeof(zl));
        zl.type = ZEBRA_LSP_ISIS_SR;
-       zl.local_label = srp->input_label;
+       zl.local_label = psid->label;
+
+       /* Local routes don't have any nexthop and require special handling. */
+       if (list_isempty(rinfo->nexthops)) {
+               struct zapi_nexthop *znh;
+               struct interface *ifp;
 
-       switch (srp->type) {
-       case ISIS_SR_PREFIX_LOCAL:
                ifp = if_lookup_by_name("lo", VRF_DEFAULT);
                if (!ifp) {
                        zlog_warn(
                                "%s: couldn't install Prefix-SID %pFX: loopback interface not found",
-                               __func__, &srp->prefix);
+                               __func__, prefix);
                        return;
                }
 
@@ -291,32 +366,26 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
                znh->ifindex = ifp->ifindex;
                znh->label_num = 1;
                znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
-               break;
-       case ISIS_SR_PREFIX_REMOTE:
-               /* Update route in the RIB too. */
-               SET_FLAG(zl.message, ZAPI_LABELS_FTN);
-               zl.route.prefix = srp->prefix;
-               zl.route.type = ZEBRA_ROUTE_ISIS;
-               zl.route.instance = 0;
-
-               for (ALL_LIST_ELEMENTS_RO(srp->u.remote.rinfo->nexthops, node,
-                                         nexthop)) {
-                       if (nexthop->sr.label == MPLS_INVALID_LABEL)
-                               continue;
-
-                       if (zl.nexthop_num >= MULTIPATH_NUM)
-                               break;
-
-                       znh = &zl.nexthops[zl.nexthop_num++];
-                       znh->type = (srp->prefix.family == AF_INET)
-                                           ? NEXTHOP_TYPE_IPV4_IFINDEX
-                                           : NEXTHOP_TYPE_IPV6_IFINDEX;
-                       znh->gate = nexthop->ip;
-                       znh->ifindex = nexthop->ifindex;
-                       znh->label_num = 1;
-                       znh->labels[0] = nexthop->sr.label;
+       } else {
+               /* Add backup nexthops first. */
+               if (rinfo->backup) {
+                       count = isis_zebra_add_nexthops(
+                               area->isis, rinfo->backup->nexthops,
+                               zl.backup_nexthops, ISIS_NEXTHOP_BACKUP, true,
+                               0);
+                       if (count > 0) {
+                               SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
+                               zl.backup_nexthop_num = count;
+                       }
                }
-               break;
+
+               /* Add primary nexthops. */
+               count = isis_zebra_add_nexthops(area->isis, rinfo->nexthops,
+                                               zl.nexthops, ISIS_NEXTHOP_MAIN,
+                                               true, count);
+               if (!count)
+                       return;
+               zl.nexthop_num = count;
        }
 
        /* Send message to zebra. */
@@ -324,57 +393,32 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
 }
 
 /**
- * Uninstall Prefix-SID from the forwarding plane through Zebra.
+ * Uninstall Prefix-SID label entry from the forwarding plane through Zebra.
  *
- * @param srp  Segment Routing Prefix-SID
+ * @param area         IS-IS area
+ * @param prefix       Route prefix
+ * @param rinfo                Route information
+ * @param psid         Prefix-SID information
  */
-static void isis_zebra_uninstall_prefix_sid(const struct sr_prefix *srp)
+void isis_zebra_prefix_sid_uninstall(struct isis_area *area,
+                                    struct prefix *prefix,
+                                    struct isis_route_info *rinfo,
+                                    struct isis_sr_psid_info *psid)
 {
        struct zapi_labels zl;
 
+       sr_debug("ISIS-Sr (%s): delete label %u for prefix %pFX",
+                area->area_tag, psid->label, prefix);
+
        /* Prepare message. */
        memset(&zl, 0, sizeof(zl));
        zl.type = ZEBRA_LSP_ISIS_SR;
-       zl.local_label = srp->input_label;
-
-       if (srp->type == ISIS_SR_PREFIX_REMOTE) {
-               /* Update route in the RIB too. */
-               SET_FLAG(zl.message, ZAPI_LABELS_FTN);
-               zl.route.prefix = srp->prefix;
-               zl.route.type = ZEBRA_ROUTE_ISIS;
-               zl.route.instance = 0;
-       }
+       zl.local_label = psid->label;
 
        /* Send message to zebra. */
        (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
 }
 
-/**
- * Send Prefix-SID to ZEBRA for installation or deletion.
- *
- * @param cmd  ZEBRA_MPLS_LABELS_REPLACE or ZEBRA_ROUTE_DELETE
- * @param srp  Segment Routing Prefix-SID
- */
-void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp)
-{
-
-       if (cmd != ZEBRA_MPLS_LABELS_REPLACE
-           && cmd != ZEBRA_MPLS_LABELS_DELETE) {
-               flog_warn(EC_LIB_DEVELOPMENT, "%s: wrong ZEBRA command",
-                         __func__);
-               return;
-       }
-
-       sr_debug("  |- %s label %u for prefix %pFX",
-                cmd == ZEBRA_MPLS_LABELS_REPLACE ? "Update" : "Delete",
-                srp->input_label, &srp->prefix);
-
-       if (cmd == ZEBRA_MPLS_LABELS_REPLACE)
-               isis_zebra_prefix_install_prefix_sid(srp);
-       else
-               isis_zebra_uninstall_prefix_sid(srp);
-}
-
 /**
  * Send (LAN)-Adjacency-SID to ZEBRA for installation or deletion.
  *
@@ -383,6 +427,7 @@ void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp)
  */
 void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
 {
+       struct isis *isis = sra->adj->circuit->area->isis;
        struct zapi_labels zl;
        struct zapi_nexthop *znh;
 
@@ -394,11 +439,11 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
 
        sr_debug("  |- %s label %u for interface %s",
                 cmd == ZEBRA_MPLS_LABELS_ADD ? "Add" : "Delete",
-                sra->nexthop.label, sra->adj->circuit->interface->name);
+                sra->input_label, sra->adj->circuit->interface->name);
 
        memset(&zl, 0, sizeof(zl));
        zl.type = ZEBRA_LSP_ISIS_SR;
-       zl.local_label = sra->nexthop.label;
+       zl.local_label = sra->input_label;
        zl.nexthop_num = 1;
        znh = &zl.nexthops[0];
        znh->gate = sra->nexthop.address;
@@ -409,6 +454,24 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
        znh->label_num = 1;
        znh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
 
+       /* Set backup nexthops. */
+       if (sra->type == ISIS_SR_LAN_BACKUP) {
+               int count;
+
+               count = isis_zebra_add_nexthops(isis, sra->backup_nexthops,
+                                               zl.backup_nexthops,
+                                               ISIS_NEXTHOP_BACKUP, true, 0);
+               if (count > 0) {
+                       SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
+                       zl.backup_nexthop_num = count;
+
+                       SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_HAS_BACKUP);
+                       znh->backup_num = count;
+                       for (int i = 0; i < count; i++)
+                               znh->backup_idx[i] = i;
+               }
+       }
+
        (void)zebra_send_mpls_labels(zclient, cmd, &zl);
 }
 
index 768919ff466bae529e3681c7aeed64bc649e4291..c5c52a6bc6bd262deca9944cd3108d0e86bef968 100644 (file)
@@ -37,7 +37,6 @@ void isis_zebra_init(struct thread_master *master, int instance);
 void isis_zebra_stop(void);
 
 struct isis_route_info;
-struct sr_prefix;
 struct sr_adjacency;
 
 void isis_zebra_route_add_route(struct isis *isis,
@@ -48,7 +47,14 @@ void isis_zebra_route_del_route(struct isis *isis,
                                struct prefix *prefix,
                                struct prefix_ipv6 *src_p,
                                struct isis_route_info *route_info);
-void isis_zebra_send_prefix_sid(int cmd, const struct sr_prefix *srp);
+void isis_zebra_prefix_sid_install(struct isis_area *area,
+                                  struct prefix *prefix,
+                                  struct isis_route_info *rinfo,
+                                  struct isis_sr_psid_info *psid);
+void isis_zebra_prefix_sid_uninstall(struct isis_area *area,
+                                    struct prefix *prefix,
+                                    struct isis_route_info *rinfo,
+                                    struct isis_sr_psid_info *psid);
 void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra);
 int isis_distribute_list_update(int routetype);
 void isis_zebra_redistribute_set(afi_t afi, int type);
index 8d73c0571dc3c76ed319bbfdbc40818e31634ea4..057ede0e38b683a73445787f3b02e2aa9ccfe14a 100644 (file)
@@ -77,6 +77,7 @@ unsigned long debug_bfd;
 unsigned long debug_tx_queue;
 unsigned long debug_sr;
 unsigned long debug_ldp_sync;
+unsigned long debug_tilfa;
 
 DEFINE_QOBJ_TYPE(isis_area)
 
@@ -441,8 +442,8 @@ void isis_area_destroy(struct isis_area *area)
 
        spftree_area_del(area);
 
-       THREAD_TIMER_OFF(area->spf_timer[0]);
-       THREAD_TIMER_OFF(area->spf_timer[1]);
+       thread_cancel(&area->spf_timer[0]);
+       thread_cancel(&area->spf_timer[1]);
 
        spf_backoff_free(area->spf_delay_ietf[0]);
        spf_backoff_free(area->spf_delay_ietf[1]);
@@ -456,9 +457,9 @@ void isis_area_destroy(struct isis_area *area)
        }
        area->area_addrs = NULL;
 
-       THREAD_TIMER_OFF(area->t_tick);
-       THREAD_TIMER_OFF(area->t_lsp_refresh[0]);
-       THREAD_TIMER_OFF(area->t_lsp_refresh[1]);
+       thread_cancel(&area->t_tick);
+       thread_cancel(&area->t_lsp_refresh[0]);
+       thread_cancel(&area->t_lsp_refresh[1]);
 
        thread_cancel_event(master, area);
 
@@ -582,6 +583,8 @@ void isis_finish(struct isis *isis)
                        isis_vrf_unlink(isis, vrf);
        }
 
+       list_delete(&isis->area_list);
+       list_delete(&isis->init_circ_list);
        XFREE(MTYPE_ISIS, isis);
 }
 
@@ -1191,6 +1194,8 @@ void print_debug(struct vty *vty, int flags, int onoff)
        if (flags & DEBUG_SR)
                vty_out(vty, "IS-IS Segment Routing events debugging is %s\n",
                        onoffs);
+       if (flags & DEBUG_TILFA)
+               vty_out(vty, "IS-IS TI-LFA events debugging is %s\n", onoffs);
        if (flags & DEBUG_UPDATE_PACKETS)
                vty_out(vty, "IS-IS Update related packet debugging is %s\n",
                        onoffs);
@@ -1285,6 +1290,10 @@ static int config_write_debug(struct vty *vty)
                vty_out(vty, "debug " PROTO_NAME " sr-events\n");
                write++;
        }
+       if (IS_DEBUG_TILFA) {
+               vty_out(vty, "debug " PROTO_NAME " ti-lfa\n");
+               write++;
+       }
        if (IS_DEBUG_UPDATE_PACKETS) {
                vty_out(vty, "debug " PROTO_NAME " update-packets\n");
                write++;
@@ -1515,6 +1524,33 @@ DEFUN (no_debug_isis_srevents,
        return CMD_SUCCESS;
 }
 
+DEFUN (debug_isis_tilfa,
+       debug_isis_tilfa_cmd,
+       "debug " PROTO_NAME " ti-lfa",
+       DEBUG_STR
+       PROTO_HELP
+       "IS-IS TI-LFA Events\n")
+{
+       debug_tilfa |= DEBUG_TILFA;
+       print_debug(vty, DEBUG_TILFA, 1);
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_isis_tilfa,
+       no_debug_isis_tilfa_cmd,
+       "no debug " PROTO_NAME " ti-lfa",
+       NO_STR
+       UNDEBUG_STR
+       PROTO_HELP
+       "IS-IS TI-LFA Events\n")
+{
+       debug_tilfa &= ~DEBUG_TILFA;
+       print_debug(vty, DEBUG_TILFA, 0);
+
+       return CMD_SUCCESS;
+}
+
 DEFUN (debug_isis_rtevents,
        debug_isis_rtevents_cmd,
        "debug " PROTO_NAME " route-events",
@@ -2339,12 +2375,12 @@ static void area_resign_level(struct isis_area *area, int level)
                }
        }
 
-       THREAD_TIMER_OFF(area->spf_timer[level - 1]);
+       thread_cancel(&area->spf_timer[level - 1]);
 
        sched_debug(
                "ISIS (%s): Resigned from L%d - canceling LSP regeneration timer.",
                area->area_tag, level);
-       THREAD_TIMER_OFF(area->t_lsp_refresh[level - 1]);
+       thread_cancel(&area->t_lsp_refresh[level - 1]);
        area->lsp_regenerate_pending[level - 1] = 0;
 }
 
@@ -2848,6 +2884,8 @@ void isis_init(void)
        install_element(ENABLE_NODE, &no_debug_isis_spfevents_cmd);
        install_element(ENABLE_NODE, &debug_isis_srevents_cmd);
        install_element(ENABLE_NODE, &no_debug_isis_srevents_cmd);
+       install_element(ENABLE_NODE, &debug_isis_tilfa_cmd);
+       install_element(ENABLE_NODE, &no_debug_isis_tilfa_cmd);
        install_element(ENABLE_NODE, &debug_isis_rtevents_cmd);
        install_element(ENABLE_NODE, &no_debug_isis_rtevents_cmd);
        install_element(ENABLE_NODE, &debug_isis_events_cmd);
@@ -2877,6 +2915,8 @@ void isis_init(void)
        install_element(CONFIG_NODE, &no_debug_isis_spfevents_cmd);
        install_element(CONFIG_NODE, &debug_isis_srevents_cmd);
        install_element(CONFIG_NODE, &no_debug_isis_srevents_cmd);
+       install_element(CONFIG_NODE, &debug_isis_tilfa_cmd);
+       install_element(CONFIG_NODE, &no_debug_isis_tilfa_cmd);
        install_element(CONFIG_NODE, &debug_isis_rtevents_cmd);
        install_element(CONFIG_NODE, &no_debug_isis_rtevents_cmd);
        install_element(CONFIG_NODE, &debug_isis_events_cmd);
index d8df6eead90e1a288662caef0b248a7b61d7c125..921df4d7ef14aca48d054019013f45705e6bc225 100644 (file)
@@ -188,6 +188,8 @@ struct isis_area {
        struct isis_sr_db srdb;
        int ipv6_circuits;
        bool purge_originator;
+       /* Fast Re-Route information. */
+       size_t lfa_protected_links[ISIS_LEVELS];
        /* Counters */
        uint32_t circuit_state_changes;
        struct isis_redist redist_settings[REDIST_PROTOCOL_COUNT]
@@ -278,6 +280,7 @@ extern unsigned long debug_bfd;
 extern unsigned long debug_tx_queue;
 extern unsigned long debug_sr;
 extern unsigned long debug_ldp_sync;
+extern unsigned long debug_tilfa;
 
 #define DEBUG_ADJ_PACKETS                (1<<0)
 #define DEBUG_SNP_PACKETS                (1<<1)
@@ -292,7 +295,8 @@ extern unsigned long debug_ldp_sync;
 #define DEBUG_BFD                        (1<<10)
 #define DEBUG_TX_QUEUE                   (1<<11)
 #define DEBUG_SR                         (1<<12)
-#define DEBUG_LDP_SYNC (1 << 13)
+#define DEBUG_LDP_SYNC                   (1<<13)
+#define DEBUG_TILFA                      (1<<14)
 
 /* Debug related macro. */
 #define IS_DEBUG_ADJ_PACKETS (debug_adj_pkt & DEBUG_ADJ_PACKETS)
@@ -309,6 +313,7 @@ extern unsigned long debug_ldp_sync;
 #define IS_DEBUG_TX_QUEUE (debug_tx_queue & DEBUG_TX_QUEUE)
 #define IS_DEBUG_SR (debug_sr & DEBUG_SR)
 #define IS_DEBUG_LDP_SYNC (debug_ldp_sync & DEBUG_LDP_SYNC)
+#define IS_DEBUG_TILFA (debug_tilfa & DEBUG_TILFA)
 
 #define lsp_debug(...)                                                         \
        do {                                                                   \
index 1d59592626728ead44101e7eed3463ae6d20509d..4be4efc118a385cea84e481f30dca9ae668be02f 100644 (file)
@@ -52,6 +52,7 @@ noinst_HEADERS += \
        isisd/isis_events.h \
        isisd/isis_flags.h \
        isisd/isis_ldp_sync.h \
+       isisd/isis_lfa.h \
        isisd/isis_lsp.h \
        isisd/isis_memory.h \
        isisd/isis_misc.h \
@@ -86,6 +87,7 @@ LIBISIS_SOURCES = \
        isisd/isis_events.c \
        isisd/isis_flags.c \
        isisd/isis_ldp_sync.c \
+       isisd/isis_lfa.c \
        isisd/isis_lsp.c \
        isisd/isis_memory.c \
        isisd/isis_misc.c \
index 323558d7fd2581b6bb0a1e6f67294656115eaee6..9bba0f5ddd134e217c65adcca8947a86a6d14e80 100644 (file)
@@ -74,7 +74,7 @@ accept_del(int fd)
        LIST_FOREACH(av, &accept_queue.queue, entry)
                if (av->fd == fd) {
                        log_debug("%s: %d removed from queue", __func__, fd);
-                       THREAD_READ_OFF(av->ev);
+                       thread_cancel(&av->ev);
                        LIST_REMOVE(av, entry);
                        free(av);
                        return;
@@ -95,7 +95,7 @@ accept_unpause(void)
 {
        if (accept_queue.evt != NULL) {
                log_debug(__func__);
-               THREAD_TIMER_OFF(accept_queue.evt);
+               thread_cancel(&accept_queue.evt);
                accept_arm();
        }
 }
@@ -115,7 +115,7 @@ accept_unarm(void)
 {
        struct accept_ev        *av;
        LIST_FOREACH(av, &accept_queue.queue, entry)
-               THREAD_READ_OFF(av->ev);
+               thread_cancel(&av->ev);
 }
 
 static int
index 74a3f5a309953f75b0ad837b3d22c357d5810c0b..c3e27357b5b91b59a627fc7c1d2791b31cc1c846 100644 (file)
@@ -410,8 +410,8 @@ static void
 log_msg_address(int out, uint16_t msg_type, struct nbr *nbr, int af,
     union ldpd_addr *addr)
 {
-       debug_msg(out, "%s: lsr-id %s, address %s", msg_name(msg_type),
-           inet_ntoa(nbr->id), log_addr(af, addr));
+       debug_msg(out, "%s: lsr-id %pI4, address %s", msg_name(msg_type),
+           &nbr->id, log_addr(af, addr));
 }
 
 static void
@@ -419,7 +419,7 @@ log_msg_mac_withdrawal(int out, struct nbr *nbr, uint8_t *mac)
 {
        char buf[ETHER_ADDR_STRLEN];
 
-       debug_msg(out, "mac withdrawal: lsr-id %s, mac %s", inet_ntoa(nbr->id),
+       debug_msg(out, "mac withdrawal: lsr-id %pI4, mac %s", &nbr->id,
            (mac) ? prefix_mac2str((struct ethaddr *)mac, buf, sizeof(buf)) :
            "wildcard");
 }
index 4e09a6c4c9e16a470613daaeca3816f210ad35df..795a41491cd4fe9ade5f0093f46695104e6d4538 100644 (file)
@@ -84,7 +84,7 @@ adj_new(struct in_addr lsr_id, struct hello_source *source,
 {
        struct adj      *adj;
 
-       log_debug("%s: lsr-id %s, %s", __func__, inet_ntoa(lsr_id),
+       log_debug("%s: lsr-id %pI4, %s", __func__, &lsr_id,
            log_hello_src(source));
 
        if ((adj = calloc(1, sizeof(*adj))) == NULL)
@@ -114,7 +114,7 @@ adj_del(struct adj *adj, uint32_t notif_status)
 {
        struct nbr      *nbr = adj->nbr;
 
-       log_debug("%s: lsr-id %s, %s (%s)", __func__, inet_ntoa(adj->lsr_id),
+       log_debug("%s: lsr-id %pI4, %s (%s)", __func__, &adj->lsr_id,
            log_hello_src(&adj->source), af_name(adj_get_af(adj)));
 
        adj_stop_itimer(adj);
@@ -179,7 +179,7 @@ adj_itimer(struct thread *thread)
 
        adj->inactivity_timer = NULL;
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(adj->lsr_id));
+       log_debug("%s: lsr-id %pI4", __func__, &adj->lsr_id);
 
        if (adj->source.type == HELLO_TARGETED) {
                if (!(adj->source.target->flags & F_TNBR_CONFIGURED) &&
@@ -198,7 +198,7 @@ adj_itimer(struct thread *thread)
 void
 adj_start_itimer(struct adj *adj)
 {
-       THREAD_TIMER_OFF(adj->inactivity_timer);
+       thread_cancel(&adj->inactivity_timer);
        adj->inactivity_timer = NULL;
        thread_add_timer(master, adj_itimer, adj, adj->holdtime,
                         &adj->inactivity_timer);
@@ -207,7 +207,7 @@ adj_start_itimer(struct adj *adj)
 void
 adj_stop_itimer(struct adj *adj)
 {
-       THREAD_TIMER_OFF(adj->inactivity_timer);
+       thread_cancel(&adj->inactivity_timer);
 }
 
 /* targeted neighbors */
@@ -359,7 +359,7 @@ tnbr_hello_timer(struct thread *thread)
 static void
 tnbr_start_hello_timer(struct tnbr *tnbr)
 {
-       THREAD_TIMER_OFF(tnbr->hello_timer);
+       thread_cancel(&tnbr->hello_timer);
        tnbr->hello_timer = NULL;
        thread_add_timer(master, tnbr_hello_timer, tnbr, tnbr_get_hello_interval(tnbr),
                         &tnbr->hello_timer);
@@ -368,7 +368,7 @@ tnbr_start_hello_timer(struct tnbr *tnbr)
 static void
 tnbr_stop_hello_timer(struct tnbr *tnbr)
 {
-       THREAD_TIMER_OFF(tnbr->hello_timer);
+       thread_cancel(&tnbr->hello_timer);
 }
 
 struct ctl_adj *
index 6554f0a6f18ce87e6999699437f86b168e219105..3b77765952408aa5f1a34dc654d3949c0369ddf6 100644 (file)
@@ -183,8 +183,8 @@ control_close(int fd)
        msgbuf_clear(&c->iev.ibuf.w);
        TAILQ_REMOVE(&ctl_conns, c, entry);
 
-       THREAD_READ_OFF(c->iev.ev_read);
-       THREAD_WRITE_OFF(c->iev.ev_write);
+       thread_cancel(&c->iev.ev_read);
+       thread_cancel(&c->iev.ev_write);
        close(c->iev.ibuf.fd);
        accept_unpause();
        free(c);
index caf63c13d7b959b08ba682691ff90a901106764a..327cb32434afb0578a7999babf341ba3ed7d92a9 100644 (file)
@@ -179,24 +179,24 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
 
        r = tlv_decode_hello_prms(buf, len, &holdtime, &flags);
        if (r == -1) {
-               log_debug("%s: lsr-id %s: failed to decode params", __func__,
-                   inet_ntoa(lsr_id));
+               log_debug("%s: lsr-id %pI4: failed to decode params", __func__,
+                   &lsr_id);
                return;
        }
        /* safety checks */
        if (holdtime != 0 && holdtime < MIN_HOLDTIME) {
-               log_debug("%s: lsr-id %s: invalid hello holdtime (%u)",
-                   __func__, inet_ntoa(lsr_id), holdtime);
+               log_debug("%s: lsr-id %pI4: invalid hello holdtime (%u)",
+                   __func__, &lsr_id, holdtime);
                return;
        }
        if (multicast && (flags & F_HELLO_TARGETED)) {
-               log_debug("%s: lsr-id %s: multicast targeted hello", __func__,
-                   inet_ntoa(lsr_id));
+               log_debug("%s: lsr-id %pI4: multicast targeted hello", __func__,
+                   &lsr_id);
                return;
        }
        if (!multicast && !((flags & F_HELLO_TARGETED))) {
-               log_debug("%s: lsr-id %s: unicast link hello", __func__,
-                   inet_ntoa(lsr_id));
+               log_debug("%s: lsr-id %pI4: unicast link hello", __func__,
+                   &lsr_id);
                return;
        }
        buf += r;
@@ -205,13 +205,13 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
        r = tlv_decode_opt_hello_prms(buf, len, &tlvs_rcvd, af, &trans_addr,
            &conf_seqnum, &trans_pref);
        if (r == -1) {
-               log_debug("%s: lsr-id %s: failed to decode optional params",
-                   __func__, inet_ntoa(lsr_id));
+               log_debug("%s: lsr-id %pI4: failed to decode optional params",
+                   __func__, &lsr_id);
                return;
        }
        if (r != len) {
-               log_debug("%s: lsr-id %s: unexpected data in message",
-                   __func__, inet_ntoa(lsr_id));
+               log_debug("%s: lsr-id %pI4: unexpected data in message",
+                   __func__, &lsr_id);
                return;
        }
        ds_tlv = (tlvs_rcvd & F_HELLO_TLV_RCVD_DS) ? 1 : 0;
@@ -220,8 +220,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
        if (!(tlvs_rcvd & F_HELLO_TLV_RCVD_ADDR))
                trans_addr = *src;
        if (bad_addr(af, &trans_addr)) {
-               log_debug("%s: lsr-id %s: invalid transport address %s",
-                   __func__, inet_ntoa(lsr_id), log_addr(af, &trans_addr));
+               log_debug("%s: lsr-id %pI4: invalid transport address %s",
+                   __func__, &lsr_id, log_addr(af, &trans_addr));
                return;
        }
        if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&trans_addr.v6)) {
@@ -234,7 +234,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                 * check)".
                 */
                if (flags & F_HELLO_TARGETED) {
-                       log_debug("%s: lsr-id %s: invalid targeted hello transport address %s", __func__, inet_ntoa(lsr_id),
+                       log_debug("%s: lsr-id %pI4: invalid targeted hello transport address %s", __func__, &lsr_id,
                             log_addr(af, &trans_addr));
                        return;
                }
@@ -249,8 +249,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                * targeted LDP Hello packet's source or destination addresses".
                */
                if (af == AF_INET6 && IN6_IS_SCOPE_EMBED(&src->v6)) {
-                       log_debug("%s: lsr-id %s: targeted hello with link-local source address", __func__,
-                           inet_ntoa(lsr_id));
+                       log_debug("%s: lsr-id %pI4: targeted hello with link-local source address", __func__,
+                           &lsr_id);
                        return;
                }
 
@@ -290,8 +290,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                source.link.src_addr = *src;
        }
 
-       debug_hello_recv("%s lsr-id %s transport-address %s holdtime %u%s",
-           log_hello_src(&source), inet_ntoa(lsr_id), log_addr(af, &trans_addr),
+       debug_hello_recv("%s lsr-id %pI4 transport-address %s holdtime %u%s",
+           log_hello_src(&source), &lsr_id, log_addr(af, &trans_addr),
             holdtime, (ds_tlv) ? " (dual stack TLV present)" : "");
 
        adj = adj_find(lsr_id, &source);
@@ -316,7 +316,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
                 * send a fatal Notification message with status code of
                 * 'Transport Connection Mismatch' and reset the session".
                 */
-               log_debug("%s: lsr-id %s: remote transport preference does not match the local preference", __func__, inet_ntoa(lsr_id));
+               log_debug("%s: lsr-id %pI4: remote transport preference does not match the local preference", __func__, &lsr_id);
                if (nbr)
                        session_shutdown(nbr, S_TRANS_MISMTCH, msg->id,
                            msg->type);
@@ -356,7 +356,7 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
        if (nbr && nbr->af == af &&
            (ldp_addrcmp(af, &nbr->raddr, &trans_addr) ||
            nbr->raddr_scope != scope_id)) {
-               log_warnx("%s: lsr-id %s: hello packet advertising a different transport address", __func__, inet_ntoa(lsr_id));
+               log_warnx("%s: lsr-id %pI4: hello packet advertising a different transport address", __func__, &lsr_id);
                if (adj)
                        adj_del(adj, S_SHUTDOWN);
                return;
@@ -364,8 +364,8 @@ recv_hello(struct in_addr lsr_id, struct ldp_msg *msg, int af,
        if (nbr == NULL) {
                nbrt = nbr_find_addr(af, &trans_addr);
                if (nbrt) {
-                       log_debug("%s: transport address %s is already being used by lsr-id %s", __func__, log_addr(af,
-                           &trans_addr), inet_ntoa(nbrt->id));
+                       log_debug("%s: transport address %s is already being used by lsr-id %pI4", __func__, log_addr(af,
+                           &trans_addr), &nbrt->id);
                        if (adj)
                                adj_del(adj, S_SHUTDOWN);
                        return;
index 30b78315f9818eb5e3281c896676409b534b768d..d394fb08ead83c3f1e49ab4dd5c08e5773299c83 100644 (file)
@@ -35,7 +35,7 @@ send_init(struct nbr *nbr)
        uint16_t                 size;
        int                      err = 0;
 
-       debug_msg_send("initialization: lsr-id %s", inet_ntoa(nbr->id));
+       debug_msg_send("initialization: lsr-id %pI4", &nbr->id);
 
        size = LDP_HDR_SIZE + LDP_MSG_SIZE + SESS_PRMS_SIZE +
            CAP_TLV_DYNAMIC_SIZE + CAP_TLV_TWCARD_SIZE + CAP_TLV_UNOTIF_SIZE;
@@ -65,7 +65,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len)
        uint16_t                max_pdu_len;
        int                     caps_rcvd = 0;
 
-       debug_msg_recv("initialization: lsr-id %s", inet_ntoa(nbr->id));
+       debug_msg_recv("initialization: lsr-id %pI4", &nbr->id);
 
        memcpy(&msg, buf, sizeof(msg));
        buf += LDP_MSG_SIZE;
@@ -146,8 +146,8 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len)
 
                        nbr->flags |= F_NBR_CAP_DYNAMIC;
 
-                       log_debug("%s: lsr-id %s announced the Dynamic Capability Announcement capability", __func__,
-                           inet_ntoa(nbr->id));
+                       log_debug("%s: lsr-id %pI4 announced the Dynamic Capability Announcement capability", __func__,
+                           &nbr->id);
                        break;
                case TLV_TYPE_TWCARD_CAP:
                        if (tlv_len != CAP_TLV_TWCARD_LEN) {
@@ -165,7 +165,7 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len)
 
                        nbr->flags |= F_NBR_CAP_TWCARD;
 
-                       log_debug("%s: lsr-id %s announced the Typed Wildcard FEC capability", __func__, inet_ntoa(nbr->id));
+                       log_debug("%s: lsr-id %pI4 announced the Typed Wildcard FEC capability", __func__, &nbr->id);
                        break;
                case TLV_TYPE_UNOTIF_CAP:
                        if (tlv_len != CAP_TLV_UNOTIF_LEN) {
@@ -183,8 +183,8 @@ recv_init(struct nbr *nbr, char *buf, uint16_t len)
 
                        nbr->flags |= F_NBR_CAP_UNOTIF;
 
-                       log_debug("%s: lsr-id %s announced the Unrecognized Notification capability", __func__,
-                           inet_ntoa(nbr->id));
+                       log_debug("%s: lsr-id %pI4 announced the Unrecognized Notification capability", __func__,
+                           &nbr->id);
                        break;
                default:
                        if (!(ntohs(tlv.type) & UNKNOWN_FLAG))
@@ -222,7 +222,7 @@ send_capability(struct nbr *nbr, uint16_t capability, int enable)
        uint16_t                 size;
        int                      err = 0;
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
+       log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
 
        size = LDP_HDR_SIZE + LDP_MSG_SIZE + CAP_TLV_DYNAMIC_SIZE;
        if ((buf = ibuf_open(size)) == NULL)
@@ -268,7 +268,7 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len)
        int              enable = 0;
        int              caps_rcvd = 0;
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
+       log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
 
        memcpy(&msg, buf, sizeof(msg));
        buf += LDP_MSG_SIZE;
@@ -318,7 +318,7 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len)
                        else
                                nbr->flags &= ~F_NBR_CAP_TWCARD;
 
-                       log_debug("%s: lsr-id %s %s the Typed Wildcard FEC capability", __func__, inet_ntoa(nbr->id),
+                       log_debug("%s: lsr-id %pI4 %s the Typed Wildcard FEC capability", __func__, &nbr->id,
                            (enable) ? "announced" : "withdrew");
                        break;
                case TLV_TYPE_UNOTIF_CAP:
@@ -342,8 +342,8 @@ recv_capability(struct nbr *nbr, char *buf, uint16_t len)
                        else
                                nbr->flags &= ~F_NBR_CAP_UNOTIF;
 
-                       log_debug("%s: lsr-id %s %s the Unrecognized Notification capability", __func__,
-                           inet_ntoa(nbr->id), (enable) ? "announced" :
+                       log_debug("%s: lsr-id %pI4 %s the Unrecognized Notification capability", __func__,
+                           &nbr->id, (enable) ? "announced" :
                            "withdrew");
                        break;
                case TLV_TYPE_DYNAMIC_CAP:
index bc8f26bc58a68d505d65efdd0d2252b6ed3355de..3e9f2fa991b095a3806a5715b3f7854df5c5cf6c 100644 (file)
@@ -470,7 +470,7 @@ if_hello_timer(struct thread *thread)
 static void
 if_start_hello_timer(struct iface_af *ia)
 {
-       THREAD_TIMER_OFF(ia->hello_timer);
+       thread_cancel(&ia->hello_timer);
        ia->hello_timer = NULL;
        thread_add_timer(master, if_hello_timer, ia, if_get_hello_interval(ia),
                         &ia->hello_timer);
@@ -479,7 +479,7 @@ if_start_hello_timer(struct iface_af *ia)
 static void
 if_stop_hello_timer(struct iface_af *ia)
 {
-       THREAD_TIMER_OFF(ia->hello_timer);
+       thread_cancel(&ia->hello_timer);
 }
 
 struct ctl_iface *
@@ -578,15 +578,15 @@ if_join_ipv4_group(struct iface *iface, struct in_addr *addr)
 {
        struct in_addr           if_addr;
 
-       log_debug("%s: interface %s addr %s", __func__, iface->name,
-           inet_ntoa(*addr));
+       log_debug("%s: interface %s addr %pI4", __func__, iface->name,
+           addr);
 
        if_addr.s_addr = if_get_ipv4_addr(iface);
 
        if (setsockopt_ipv4_multicast(global.ipv4.ldp_disc_socket,
            IP_ADD_MEMBERSHIP, if_addr, addr->s_addr, iface->ifindex) < 0) {
-               log_warn("%s: error IP_ADD_MEMBERSHIP, interface %s address %s",
-                    __func__, iface->name, inet_ntoa(*addr));
+               log_warn("%s: error IP_ADD_MEMBERSHIP, interface %s address %pI4",
+                    __func__, iface->name, addr);
                return (-1);
        }
        return (0);
@@ -597,14 +597,14 @@ if_leave_ipv4_group(struct iface *iface, struct in_addr *addr)
 {
        struct in_addr           if_addr;
 
-       log_debug("%s: interface %s addr %s", __func__, iface->name,
-           inet_ntoa(*addr));
+       log_debug("%s: interface %s addr %pI4", __func__, iface->name,
+           addr);
 
        if_addr.s_addr = if_get_ipv4_addr(iface);
 
        if (setsockopt_ipv4_multicast(global.ipv4.ldp_disc_socket,
            IP_DROP_MEMBERSHIP, if_addr, addr->s_addr, iface->ifindex) < 0) {
-               log_warn("%s: error IP_DROP_MEMBERSHIP, interface %s address %s", __func__, iface->name, inet_ntoa(*addr));
+               log_warn("%s: error IP_DROP_MEMBERSHIP, interface %s address %pI4", __func__, iface->name, addr);
                return (-1);
        }
 
@@ -753,8 +753,7 @@ static void start_wait_for_ldp_sync_timer(struct iface *iface)
        if (iface->ldp_sync.wait_for_sync_timer)
                return;
 
-       THREAD_TIMER_OFF(iface->ldp_sync.wait_for_sync_timer);
-       iface->ldp_sync.wait_for_sync_timer = NULL;
+       THREAD_OFF(iface->ldp_sync.wait_for_sync_timer);
        thread_add_timer(master, iface_wait_for_ldp_sync_timer, iface,
                        if_get_wait_for_sync_interval(),
                        &iface->ldp_sync.wait_for_sync_timer);
@@ -762,8 +761,7 @@ static void start_wait_for_ldp_sync_timer(struct iface *iface)
 
 static void stop_wait_for_ldp_sync_timer(struct iface *iface)
 {
-       THREAD_TIMER_OFF(iface->ldp_sync.wait_for_sync_timer);
-       iface->ldp_sync.wait_for_sync_timer = NULL;
+       THREAD_OFF(iface->ldp_sync.wait_for_sync_timer);
 }
 
 static int
@@ -828,14 +826,14 @@ ldp_sync_fsm_adj_event(struct adj *adj, enum ldp_sync_event event)
        }
 
        debug_evt_ldp_sync("%s: event %s, "
-               "adj iface %s (%d) lsr-id %s "
-               "source address %s transport address %s",
-               __func__, ldp_sync_event_names[event],
-               adj->source.link.ia->iface->name,
-               adj->source.link.ia->iface->ifindex,
-               inet_ntoa(adj->lsr_id),
-               log_addr(adj_get_af(adj), &adj->source.link.src_addr),
-               log_addr(adj_get_af(adj), &adj->trans_addr));
+                          "adj iface %s (%d) lsr-id %pI4 "
+                          "source address %s transport address %s",
+                          __func__, ldp_sync_event_names[event],
+                          adj->source.link.ia->iface->name,
+                          adj->source.link.ia->iface->ifindex,
+                          &adj->lsr_id,
+                          log_addr(adj_get_af(adj), &adj->source.link.src_addr),
+                          log_addr(adj_get_af(adj), &adj->trans_addr));
 
        return ldp_sync_fsm(iface, event);
 }
@@ -861,9 +859,9 @@ ldp_sync_fsm_nbr_event(struct nbr *nbr, enum ldp_sync_event event)
                         */
                        continue;
 
-               debug_evt_ldp_sync("%s: event %s, iface %s, lsr-id %s",
+               debug_evt_ldp_sync("%s: event %s, iface %s, lsr-id %pI4",
                        __func__, ldp_sync_event_names[event],
-                       iface->name, inet_ntoa(nbr->id));
+                       iface->name, &nbr->id);
 
                ldp_sync_fsm(iface, event);
        }
index ba5f2233162da9637c3def43eeee0a09beb679df..b03127109f4867aa1ebd35a421f02708856b9cef 100644 (file)
@@ -37,7 +37,7 @@ send_keepalive(struct nbr *nbr)
        size -= LDP_HDR_SIZE;
        gen_msg_hdr(buf, MSG_TYPE_KEEPALIVE, size);
 
-       debug_kalive_send("keepalive: lsr-id %s", inet_ntoa(nbr->id));
+       debug_kalive_send("keepalive: lsr-id %pI4", &nbr->id);
 
        evbuf_enqueue(&nbr->tcp->wbuf, buf);
        nbr->stats.kalive_sent++;
@@ -54,7 +54,7 @@ recv_keepalive(struct nbr *nbr, char *buf, uint16_t len)
                return (-1);
        }
 
-       debug_kalive_recv("keepalive: lsr-id %s", inet_ntoa(nbr->id));
+       debug_kalive_recv("keepalive: lsr-id %pI4", &nbr->id);
 
        if (nbr->state != NBR_STA_OPER)
                nbr_fsm(nbr, NBR_EVT_KEEPALIVE_RCVD);
index a656626356abe9a9ce8a9fbf18586bc5e38d78cb..cee9d527e859a95dd27d8ab3de21638c297cdb02 100644 (file)
@@ -910,6 +910,6 @@ tlv_decode_fec_elm(struct nbr *nbr, struct ldp_msg *msg, char *buf,
 static void
 log_msg_mapping(int out, uint16_t msg_type, struct nbr *nbr, struct map *map)
 {
-       debug_msg(out, "%s: lsr-id %s, fec %s, label %s", msg_name(msg_type),
-           inet_ntoa(nbr->id), log_map(map), log_label(map->label));
+       debug_msg(out, "%s: lsr-id %pI4, fec %s, label %s", msg_name(msg_type),
+           &nbr->id, log_map(map), log_label(map->label));
 }
index df64f908ead135277384567ab8fab4c70619eec8..67b695150e4fe72769f8dff09865ec02b1cd5093 100644 (file)
@@ -415,8 +415,8 @@ lde_dispatch_imsg(struct thread *thread)
                imsg_event_add(iev);
        else {
                /* this pipe is dead, so remove the event handlers and exit */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                lde_shutdown();
        }
 
@@ -661,8 +661,8 @@ lde_dispatch_parent(struct thread *thread)
                imsg_event_add(iev);
        else {
                /* this pipe is dead, so remove the event handlers and exit */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                lde_shutdown();
        }
 
index bed276c7b1ec3b887d849dff7153bfebbb1446bb..9db931677dc38072639150dc7dc4919d436cfbe4 100644 (file)
@@ -1060,7 +1060,7 @@ lde_gc_timer(struct thread *thread)
 void
 lde_gc_start_timer(void)
 {
-       THREAD_TIMER_OFF(gc_timer);
+       thread_cancel(&gc_timer);
        gc_timer = NULL;
        thread_add_timer(master, lde_gc_timer, NULL, LDE_GC_INTERVAL,
                         &gc_timer);
@@ -1069,5 +1069,5 @@ lde_gc_start_timer(void)
 void
 lde_gc_stop_timer(void)
 {
-       THREAD_TIMER_OFF(gc_timer);
+       thread_cancel(&gc_timer);
 }
index c217cfc78ab50cffe3297eb76dabe795822a5565..d21e3c0409970bc1335b24690ef7586e208237d7 100644 (file)
@@ -255,7 +255,7 @@ ldp_config_write(struct vty *vty)
        vty_out (vty, "mpls ldp\n");
 
        if (ldpd_conf->rtr_id.s_addr != INADDR_ANY)
-               vty_out(vty, " router-id %s\n", inet_ntoa(ldpd_conf->rtr_id));
+               vty_out(vty, " router-id %pI4\n", &ldpd_conf->rtr_id);
 
        if (ldpd_conf->lhello_holdtime != LINK_DFLT_HOLDTIME &&
            ldpd_conf->lhello_holdtime != 0)
@@ -292,20 +292,20 @@ ldp_config_write(struct vty *vty)
 
        RB_FOREACH(nbrp, nbrp_head, &ldpd_conf->nbrp_tree) {
                if (nbrp->flags & F_NBRP_KEEPALIVE)
-                       vty_out (vty, " neighbor %s session holdtime %u\n",
-                           inet_ntoa(nbrp->lsr_id),nbrp->keepalive);
+                       vty_out (vty, " neighbor %pI4 session holdtime %u\n",
+                           &nbrp->lsr_id,nbrp->keepalive);
 
                if (nbrp->flags & F_NBRP_GTSM) {
                        if (nbrp->gtsm_enabled)
-                               vty_out (vty, " neighbor %s ttl-security hops %u\n",  inet_ntoa(nbrp->lsr_id),
+                               vty_out (vty, " neighbor %pI4 ttl-security hops %u\n",  &nbrp->lsr_id,
                                    nbrp->gtsm_hops);
                        else
-                               vty_out (vty, " neighbor %s ttl-security disable\n",inet_ntoa(nbrp->lsr_id));
+                               vty_out (vty, " neighbor %pI4 ttl-security disable\n",&nbrp->lsr_id);
                }
 
                if (nbrp->auth.method == AUTH_MD5SIG)
-                       vty_out (vty, " neighbor %s password %s\n",
-                           inet_ntoa(nbrp->lsr_id),nbrp->auth.md5key);
+                       vty_out (vty, " neighbor %pI4 password %s\n",
+                           &nbrp->lsr_id,nbrp->auth.md5key);
        }
 
        ldp_af_config_write(vty, AF_INET, ldpd_conf, &ldpd_conf->ipv4);
@@ -326,7 +326,7 @@ ldp_l2vpn_pw_config_write(struct vty *vty, struct l2vpn_pw *pw)
        vty_out (vty, " member pseudowire %s\n", pw->ifname);
 
        if (pw->lsr_id.s_addr != INADDR_ANY)
-               vty_out (vty, "  neighbor lsr-id %s\n",inet_ntoa(pw->lsr_id));
+               vty_out (vty, "  neighbor lsr-id %pI4\n",&pw->lsr_id);
                else
                        missing_lsrid = 1;
 
index 609598a7681722c5f5aaeed2850156bf15e6e04d..09b820e3f6b6ebcb4e11516dd8add815b0760a31 100644 (file)
@@ -19,6 +19,7 @@
 
 #include <zebra.h>
 #include <sys/un.h>
+#include "lib/printfrr.h"
 
 #include "ldpd.h"
 #include "ldpe.h"
@@ -237,8 +238,8 @@ show_ldp_sync_msg(struct vty *vty, struct imsg *imsg,
                }
 
                if (iface->peer_ldp_id.s_addr)
-                       vty_out (vty, "    Peer LDP Identifier: %s:0\n",
-                               inet_ntoa(iface->peer_ldp_id));
+                       vty_out (vty, "    Peer LDP Identifier: %pI4:0\n",
+                               &iface->peer_ldp_id);
 
                break;
        case IMSG_CTL_END:
@@ -256,6 +257,7 @@ show_ldp_sync_msg_json(struct imsg *imsg, struct show_params *params,
 {
        struct ctl_ldp_sync     *iface;
        json_object             *json_iface;
+       char buf[PREFIX_STRLEN];
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LDP_SYNC:
@@ -278,7 +280,8 @@ show_ldp_sync_msg_json(struct imsg *imsg, struct show_params *params,
 
                json_object_string_add(json_iface, "peerLdpId",
                    iface->peer_ldp_id.s_addr ?
-                   inet_ntoa(iface->peer_ldp_id) : "");
+                   inet_ntop(AF_INET, &iface->peer_ldp_id, buf, sizeof(buf)) :
+                             "");
 
                json_object_object_add(json, iface->name, json_iface);
                break;
@@ -305,8 +308,7 @@ show_discovery_msg(struct vty *vty, struct imsg *imsg,
                if (params->family != AF_UNSPEC && params->family != adj->af)
                        break;
 
-               vty_out(vty, "%-4s %-15s ", af_name(adj->af),
-                   inet_ntoa(adj->id));
+               vty_out(vty, "%-4s %-15pI4 ", af_name(adj->af), &adj->id);
                switch(adj->type) {
                case HELLO_LINK:
                        vty_out(vty, "%-8s %-15s ", "Link", adj->ifname);
@@ -336,8 +338,8 @@ show_discovery_detail_adj(struct vty *vty, char *buffer, struct ctl_adj *adj)
 {
        size_t   buflen = strlen(buffer);
 
-       snprintf(buffer + buflen, LDPBUFSIZ - buflen,
-           "      LSR Id: %s:0\n", inet_ntoa(adj->id));
+       snprintfrr(buffer + buflen, LDPBUFSIZ - buflen,
+                  "      LSR Id: %pI4:0\n", &adj->id);
        buflen = strlen(buffer);
        snprintf(buffer + buflen, LDPBUFSIZ - buflen,
            "          Source address: %s\n",
@@ -419,7 +421,7 @@ show_discovery_detail_msg(struct vty *vty, struct imsg *imsg,
        case IMSG_CTL_END:
                rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf);
                vty_out (vty, "Local:\n");
-               vty_out (vty, "  LSR Id: %s:0\n",inet_ntoa(rtr_id));
+               vty_out (vty, "  LSR Id: %pI4:0\n",&rtr_id);
                if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
                        vty_out (vty, "  Transport Address (IPv4): %s\n",
                            log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr));
@@ -445,6 +447,7 @@ show_discovery_msg_json(struct imsg *imsg, struct show_params *params,
     json_object *json)
 {
        struct ctl_adj          *adj;
+       char                    buf[PREFIX_STRLEN];
        json_object             *json_array;
        json_object             *json_adj;
 
@@ -465,7 +468,8 @@ show_discovery_msg_json(struct imsg *imsg, struct show_params *params,
                json_object_string_add(json_adj, "addressFamily",
                    af_name(adj->af));
                json_object_string_add(json_adj, "neighborId",
-                   inet_ntoa(adj->id));
+                                      inet_ntop(AF_INET, &adj->id, buf,
+                                                sizeof(buf)));
                switch(adj->type) {
                case HELLO_LINK:
                        json_object_string_add(json_adj, "type", "link");
@@ -494,6 +498,7 @@ show_discovery_msg_json(struct imsg *imsg, struct show_params *params,
 static void
 show_discovery_detail_adj_json(json_object *json, struct ctl_adj *adj)
 {
+       char buf[PREFIX_STRLEN];
        json_object *json_adj;
        json_object *json_array;
 
@@ -504,7 +509,8 @@ show_discovery_detail_adj_json(json_object *json, struct ctl_adj *adj)
        }
 
        json_adj = json_object_new_object();
-       json_object_string_add(json_adj, "lsrId", inet_ntoa(adj->id));
+       json_object_string_add(json_adj, "lsrId", inet_ntop(AF_INET, &adj->id,
+                                                           buf, sizeof(buf)));
        json_object_string_add(json_adj, "sourceAddress", log_addr(adj->af,
            &adj->src_addr));
        json_object_string_add(json_adj, "transportAddress", log_addr(adj->af,
@@ -526,6 +532,7 @@ show_discovery_detail_msg_json(struct imsg *imsg, struct show_params *params,
        struct ctl_disc_tnbr    *tnbr;
        struct in_addr           rtr_id;
        union ldpd_addr         *trans_addr;
+       char buf[PREFIX_STRLEN];
        json_object             *json_interface;
        json_object             *json_target;
        static json_object      *json_interfaces;
@@ -535,7 +542,9 @@ show_discovery_detail_msg_json(struct imsg *imsg, struct show_params *params,
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_DISCOVERY:
                rtr_id.s_addr = ldp_rtr_id_get(ldpd_conf);
-               json_object_string_add(json, "lsrId", inet_ntoa(rtr_id));
+               json_object_string_add(json, "lsrId",
+                                      inet_ntop(AF_INET, &rtr_id, buf,
+                                                sizeof(buf)));
                if (ldpd_conf->ipv4.flags & F_LDPD_AF_ENABLED)
                        json_object_string_add(json, "transportAddressIPv4",
                            log_addr(AF_INET, &ldpd_conf->ipv4.trans_addr));
@@ -612,9 +621,9 @@ show_nbr_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
 
                addr = log_addr(nbr->af, &nbr->raddr);
 
-               vty_out(vty, "%-4s %-15s %-11s %-15s",
-                   af_name(nbr->af), inet_ntoa(nbr->id),
-                   nbr_state_name(nbr->nbr_state), addr);
+               vty_out(vty, "%-4s %-15pI4 %-11s %-15s",
+                       af_name(nbr->af), &nbr->id,
+                       nbr_state_name(nbr->nbr_state), addr);
                if (strlen(addr) > 15)
                        vty_out(vty, "\n%48s", " ");
                vty_out (vty, " %8s\n", log_time(nbr->uptime));
@@ -662,8 +671,8 @@ show_nbr_detail_msg(struct vty *vty, struct imsg *imsg,
 
                v4adjs_buffer[0] = '\0';
                v6adjs_buffer[0] = '\0';
-               vty_out (vty, "Peer LDP Identifier: %s:0\n",
-                         inet_ntoa(nbr->id));
+               vty_out (vty, "Peer LDP Identifier: %pI4:0\n",
+                         &nbr->id);
                vty_out (vty, "  TCP connection: %s:%u - %s:%u\n",
                    log_addr(nbr->af, &nbr->laddr), ntohs(nbr->lport),
                    log_addr(nbr->af, &nbr->raddr),ntohs(nbr->rport));
@@ -740,6 +749,7 @@ show_nbr_msg_json(struct imsg *imsg, struct show_params *params,
     json_object *json)
 {
        struct ctl_nbr          *nbr;
+       char buf[PREFIX_STRLEN];
        json_object             *json_array;
        json_object             *json_nbr;
 
@@ -757,7 +767,8 @@ show_nbr_msg_json(struct imsg *imsg, struct show_params *params,
                json_object_string_add(json_nbr, "addressFamily",
                    af_name(nbr->af));
                json_object_string_add(json_nbr, "neighborId",
-                   inet_ntoa(nbr->id));
+                                      inet_ntop(AF_INET, &nbr->id, buf,
+                                                sizeof(buf)));
                json_object_string_add(json_nbr, "state",
                    nbr_state_name(nbr->nbr_state));
                json_object_string_add(json_nbr, "transportAddress",
@@ -803,6 +814,7 @@ show_nbr_detail_msg_json(struct imsg *imsg, struct show_params *params,
        struct ctl_nbr          *nbr;
        struct ldp_stats        *stats;
        struct ctl_adj          *adj;
+       char buf[PREFIX_STRLEN];
        json_object             *json_nbr;
        json_object             *json_array;
        json_object             *json_counter;
@@ -815,9 +827,12 @@ show_nbr_detail_msg_json(struct imsg *imsg, struct show_params *params,
                nbr = imsg->data;
 
                json_nbr = json_object_new_object();
-               json_object_object_add(json, inet_ntoa(nbr->id), json_nbr);
-
-               json_object_string_add(json_nbr, "peerId", inet_ntoa(nbr->id));
+               json_object_object_add(json,
+                                      inet_ntop(AF_INET, &nbr->id, buf,
+                                                sizeof(buf)), json_nbr);
+               json_object_string_add(json_nbr, "peerId",
+                                      inet_ntop(AF_INET, &nbr->id, buf,
+                                                sizeof(buf)));
                json_object_string_add(json_nbr, "tcpLocalAddress",
                    log_addr(nbr->af, &nbr->laddr));
                json_object_int_add(json_nbr, "tcpLocalPort",
@@ -998,8 +1013,8 @@ show_nbr_capabilities_msg(struct vty *vty, struct imsg *imsg, struct show_params
                if (nbr->nbr_state != NBR_STA_OPER)
                        break;
 
-               vty_out (vty, "Peer LDP Identifier: %s:0\n",
-                         inet_ntoa(nbr->id));
+               vty_out (vty, "Peer LDP Identifier: %pI4:0\n",
+                         &nbr->id);
                show_nbr_capabilities(vty, nbr);
                vty_out (vty, "\n");
                break;
@@ -1079,6 +1094,7 @@ show_nbr_capabilities_msg_json(struct imsg *imsg, struct show_params *params,
     json_object *json)
 {
        struct ctl_nbr          *nbr;
+       char buf[PREFIX_STRLEN];
        json_object             *json_nbr;
 
        switch (imsg->hdr.type) {
@@ -1089,7 +1105,8 @@ show_nbr_capabilities_msg_json(struct imsg *imsg, struct show_params *params,
                        break;
 
                json_nbr = json_object_new_object();
-               json_object_object_add(json, inet_ntoa(nbr->id), json_nbr);
+               json_object_object_add(json, inet_ntop(AF_INET, &nbr->id, buf,
+                                                      sizeof(buf)), json_nbr);
                show_nbr_capabilities_json(nbr, json_nbr);
                break;
        case IMSG_CTL_END:
@@ -1128,9 +1145,10 @@ show_lib_msg(struct vty *vty, struct imsg *imsg, struct show_params *params)
                vty_out(vty, "%-4s %-20s", af_name(rt->af), dstnet);
                if (strlen(dstnet) > 20)
                        vty_out(vty, "\n%25s", " ");
-               vty_out (vty, " %-15s %-11s %-13s %6s\n", inet_ntoa(rt->nexthop),
-                   log_label(rt->local_label), log_label(rt->remote_label),
-                   rt->in_use ? "yes" : "no");
+               vty_out (vty, " %-15pI4 %-11s %-13s %6s\n",
+                        &rt->nexthop, log_label(rt->local_label),
+                        log_label(rt->remote_label),
+                        rt->in_use ? "yes" : "no");
                break;
        case IMSG_CTL_END:
                vty_out (vty, "\n");
@@ -1168,17 +1186,17 @@ show_lib_detail_msg(struct vty *vty, struct imsg *imsg, struct show_params *para
 
                upstream = 1;
                buflen = strlen(sent_buffer);
-               snprintf(sent_buffer + buflen, LDPBUFSIZ - buflen,
-                   "%12s%s:0\n", "", inet_ntoa(rt->nexthop));
+               snprintfrr(sent_buffer + buflen, LDPBUFSIZ - buflen,
+                          "%12s%pI4:0\n", "", &rt->nexthop);
                break;
        case IMSG_CTL_SHOW_LIB_RCVD:
                rt = imsg->data;
                downstream = 1;
                buflen = strlen(rcvd_buffer);
-               snprintf(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
-                   "%12s%s:0, label %s%s\n", "", inet_ntoa(rt->nexthop),
-                   log_label(rt->remote_label),
-                   rt->in_use ? " (in use)" : "");
+               snprintfrr(rcvd_buffer + buflen, LDPBUFSIZ - buflen,
+                          "%12s%pI4:0, label %s%s\n", "", &rt->nexthop,
+                          log_label(rt->remote_label),
+                          rt->in_use ? " (in use)" : "");
                break;
        case IMSG_CTL_SHOW_LIB_END:
                rt = imsg->data;
@@ -1217,6 +1235,7 @@ show_lib_msg_json(struct imsg *imsg, struct show_params *params,
        json_object     *json_array;
        json_object     *json_lib_entry;
        char             dstnet[BUFSIZ];
+       char buf[PREFIX_STRLEN];
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_LIB_BEGIN:
@@ -1240,11 +1259,12 @@ show_lib_msg_json(struct imsg *imsg, struct show_params *params,
                    log_addr(rt->af, &rt->prefix), rt->prefixlen);
                json_object_string_add(json_lib_entry, "prefix", dstnet);
                json_object_string_add(json_lib_entry, "neighborId",
-                   inet_ntoa(rt->nexthop));
+                                      inet_ntop(AF_INET, &rt->nexthop, buf,
+                                                sizeof(buf)));
                json_object_string_add(json_lib_entry, "localLabel",
-                   log_label(rt->local_label));
+                                      log_label(rt->local_label));
                json_object_string_add(json_lib_entry, "remoteLabel",
-                   log_label(rt->remote_label));
+                                      log_label(rt->remote_label));
                json_object_int_add(json_lib_entry, "inUse", rt->in_use);
 
                json_object_array_add(json_array, json_lib_entry);
@@ -1264,6 +1284,7 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
 {
        struct ctl_rt           *rt = NULL;
        char                     dstnet[BUFSIZ];
+       char buf[PREFIX_STRLEN];
        static json_object      *json_lib_entry;
        static json_object      *json_adv_labels;
        json_object             *json_adv_label;
@@ -1296,7 +1317,8 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
 
                json_adv_label = json_object_new_object();
                json_object_string_add(json_adv_label, "neighborId",
-                   inet_ntoa(rt->nexthop));
+                                      inet_ntop(AF_INET, &rt->nexthop, buf,
+                                                sizeof(buf)));
                json_object_array_add(json_adv_labels, json_adv_label);
                break;
        case IMSG_CTL_SHOW_LIB_RCVD:
@@ -1304,9 +1326,10 @@ show_lib_detail_msg_json(struct imsg *imsg, struct show_params *params,
 
                json_remote_label = json_object_new_object();
                json_object_string_add(json_remote_label, "neighborId",
-                   inet_ntoa(rt->nexthop));
+                                      inet_ntop(AF_INET, &rt->nexthop,
+                                                buf, sizeof(buf)));
                json_object_string_add(json_remote_label, "label",
-                   log_label(rt->remote_label));
+                                      log_label(rt->remote_label));
                json_object_int_add(json_remote_label, "inUse", rt->in_use);
                json_object_array_add(json_remote_labels, json_remote_label);
                break;
@@ -1329,8 +1352,8 @@ show_l2vpn_binding_msg(struct vty *vty, struct imsg *imsg,
        case IMSG_CTL_SHOW_L2VPN_BINDING:
                pw = imsg->data;
 
-               vty_out (vty, "  Destination Address: %s, VC ID: %u\n",
-                   inet_ntoa(pw->lsr_id), pw->pwid);
+               vty_out (vty, "  Destination Address: %pI4, VC ID: %u\n",
+                   &pw->lsr_id, pw->pwid);
 
                /* local binding */
                if (pw->local_label != NO_LABEL) {
@@ -1371,6 +1394,7 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params,
        struct ctl_pw   *pw;
        json_object     *json_pw;
        char             key_name[64];
+       char buf[PREFIX_STRLEN];
 
        switch (imsg->hdr.type) {
        case IMSG_CTL_SHOW_L2VPN_BINDING:
@@ -1378,7 +1402,8 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params,
 
                json_pw = json_object_new_object();
                json_object_string_add(json_pw, "destination",
-                   inet_ntoa(pw->lsr_id));
+                                      inet_ntop(AF_INET, &pw->lsr_id, buf,
+                                                sizeof(buf)));
                json_object_int_add(json_pw, "vcId", pw->pwid);
 
                /* local binding */
@@ -1415,8 +1440,8 @@ show_l2vpn_binding_msg_json(struct imsg *imsg, struct show_params *params,
                        json_object_string_add(json_pw, "remoteLabel",
                            "unassigned");
 
-               snprintf(key_name, sizeof(key_name), "%s: %u",
-                        inet_ntoa(pw->lsr_id), pw->pwid);
+               snprintfrr(key_name, sizeof(key_name), "%pI4: %u",
+                          &pw->lsr_id, pw->pwid);
                json_object_object_add(json, key_name, json_pw);
                break;
        case IMSG_CTL_END:
@@ -1437,9 +1462,9 @@ show_l2vpn_pw_msg(struct vty *vty, struct imsg *imsg, struct show_params *params
        case IMSG_CTL_SHOW_L2VPN_PW:
                pw = imsg->data;
 
-               vty_out (vty, "%-9s %-15s %-10u %-16s %-10s\n", pw->ifname,
-                   inet_ntoa(pw->lsr_id), pw->pwid, pw->l2vpn_name,
-                   (pw->status == PW_FORWARDING ? "UP" : "DOWN"));
+               vty_out (vty, "%-9s %-15pI4 %-10u %-16s %-10s\n", pw->ifname,
+                        &pw->lsr_id, pw->pwid, pw->l2vpn_name,
+                        (pw->status == PW_FORWARDING ? "UP" : "DOWN"));
                break;
        case IMSG_CTL_END:
                vty_out (vty, "\n");
@@ -1456,6 +1481,7 @@ show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params,
     json_object *json)
 {
        struct ctl_pw   *pw;
+       char buf[PREFIX_STRLEN];
        json_object     *json_pw;
 
        switch (imsg->hdr.type) {
@@ -1463,7 +1489,9 @@ show_l2vpn_pw_msg_json(struct imsg *imsg, struct show_params *params,
                pw = imsg->data;
 
                json_pw = json_object_new_object();
-               json_object_string_add(json_pw, "peerId", inet_ntoa(pw->lsr_id));
+               json_object_string_add(json_pw, "peerId",
+                                      inet_ntop(AF_INET, &pw->lsr_id,
+                                                buf, sizeof(buf)));
                json_object_int_add(json_pw, "vcId", pw->pwid);
                json_object_string_add(json_pw, "VpnName", pw->l2vpn_name);
                if (pw->status == PW_FORWARDING)
index 16e9adc9d97da49c4009c7e9edaaf9356c641cf9..3852d8d23b3072d52c0147908f584281d07599f5 100644 (file)
@@ -359,7 +359,7 @@ ldp_router_id_update(ZAPI_CALLBACK_ARGS)
        if (bad_addr_v4(router_id.u.prefix4))
                return (0);
 
-       debug_zebra_in("router-id update %s", inet_ntoa(router_id.u.prefix4));
+       debug_zebra_in("router-id update %pI4", &router_id.u.prefix4);
 
        global.rtr_id.s_addr = router_id.u.prefix4.s_addr;
        main_imsg_compose_ldpe(IMSG_RTRID_UPDATE, 0, &global.rtr_id,
index 940333f83ca4a005329d0b36031bec2ba681bdf7..d6da45c8624ab9b71ae7ea2a819b1353fc2ad717 100644 (file)
@@ -604,8 +604,8 @@ main_dispatch_ldpe(struct thread *thread)
                imsg_event_add(iev);
        else {
                /* this pipe is dead, so remove the event handlers and exit */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                ldpe_pid = 0;
                if (lde_pid == 0)
                        ldpd_shutdown();
@@ -702,8 +702,8 @@ main_dispatch_lde(struct thread *thread)
                imsg_event_add(iev);
        else {
                /* this pipe is dead, so remove the event handlers and exit */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                lde_pid = 0;
                if (ldpe_pid == 0)
                        ldpd_shutdown();
@@ -728,8 +728,8 @@ ldp_write_handler(struct thread *thread)
                fatal("msgbuf_write");
        if (n == 0) {
                /* this pipe is dead, so remove the event handlers */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                return (0);
        }
 
@@ -816,7 +816,7 @@ evbuf_init(struct evbuf *eb, int fd, int (*handler)(struct thread *),
 void
 evbuf_clear(struct evbuf *eb)
 {
-       THREAD_WRITE_OFF(eb->ev);
+       thread_cancel(&eb->ev);
        msgbuf_clear(&eb->wbuf);
        eb->wbuf.fd = -1;
 }
index d3374a62db38d8745ecc1822cbc589d4da471401..ffc1d17f517aaa788cf30aded91740b29e1f5f17 100644 (file)
@@ -208,7 +208,7 @@ ldpe_shutdown(void)
 
 #ifdef __OpenBSD__
        if (sysdep.no_pfkey == 0) {
-               THREAD_READ_OFF(pfkey_ev);
+               thread_cancel(&pfkey_ev);
                close(global.pfkeysock);
        }
 #endif
@@ -580,8 +580,8 @@ ldpe_dispatch_main(struct thread *thread)
                imsg_event_add(iev);
        else {
                /* this pipe is dead, so remove the event handlers and exit */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                ldpe_shutdown();
        }
 
@@ -719,8 +719,8 @@ ldpe_dispatch_lde(struct thread *thread)
                imsg_event_add(iev);
        else {
                /* this pipe is dead, so remove the event handlers and exit */
-               THREAD_READ_OFF(iev->ev_read);
-               THREAD_WRITE_OFF(iev->ev_write);
+               thread_cancel(&iev->ev_read);
+               thread_cancel(&iev->ev_write);
                ldpe_shutdown();
        }
 
@@ -778,14 +778,14 @@ ldpe_close_sockets(int af)
        af_global = ldp_af_global_get(&global, af);
 
        /* discovery socket */
-       THREAD_READ_OFF(af_global->disc_ev);
+       thread_cancel(&af_global->disc_ev);
        if (af_global->ldp_disc_socket != -1) {
                close(af_global->ldp_disc_socket);
                af_global->ldp_disc_socket = -1;
        }
 
        /* extended discovery socket */
-       THREAD_READ_OFF(af_global->edisc_ev);
+       thread_cancel(&af_global->edisc_ev);
        if (af_global->ldp_edisc_socket != -1) {
                close(af_global->ldp_edisc_socket);
                af_global->ldp_edisc_socket = -1;
index 6427d0e13b106073267b3a7fc688b281831fb02b..ff9294f9d24d305031f20712ebfb48711385222a 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #include <zebra.h>
+#include "lib/printfrr.h"
 
 #include "mpls.h"
 
@@ -254,10 +255,10 @@ log_fec(const struct fec *fec)
                        return ("???");
                break;
        case FEC_TYPE_PWID:
-               if (snprintf(buf, sizeof(buf),
-                   "pwid %u (%s) - %s",
-                   fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
-                   inet_ntoa(fec->u.pwid.lsr_id)) == -1)
+               if (snprintfrr(buf, sizeof(buf),
+                              "pwid %u (%s) - %pI4",
+                              fec->u.pwid.pwid, pw_type_name(fec->u.pwid.type),
+                              &fec->u.pwid.lsr_id) == -1)
                        return ("???");
                break;
        default:
index 236d3eaa58a317867e2e84ae8caee5a431acd04a..75deaad2c04bfc398e8438891105fb6296817696 100644 (file)
@@ -143,7 +143,7 @@ nbr_fsm(struct nbr *nbr, enum nbr_event event)
 
        if (nbr_fsm_tbl[i].state == -1) {
                /* event outside of the defined fsm, ignore it. */
-               log_warnx("%s: lsr-id %s, event %s not expected in state %s", __func__, inet_ntoa(nbr->id),
+               log_warnx("%s: lsr-id %pI4, event %s not expected in state %s", __func__, &nbr->id,
                    nbr_event_names[event], nbr_state_name(old_state));
                return (0);
        }
@@ -152,10 +152,10 @@ nbr_fsm(struct nbr *nbr, enum nbr_event event)
                nbr->state = new_state;
 
        if (old_state != nbr->state) {
-               log_debug("%s: event %s resulted in action %s and changing state for lsr-id %s from %s to %s",
+               log_debug("%s: event %s resulted in action %s and changing state for lsr-id %pI4 from %s to %s",
                    __func__, nbr_event_names[event],
                    nbr_action_names[nbr_fsm_tbl[i].action],
-                   inet_ntoa(nbr->id), nbr_state_name(old_state),
+                   &nbr->id, nbr_state_name(old_state),
                    nbr_state_name(nbr->state));
 
                if (nbr->state == NBR_STA_OPER) {
@@ -223,8 +223,8 @@ nbr_new(struct in_addr id, int af, int ds_tlv, union ldpd_addr *addr,
        struct adj              *adj;
        struct pending_conn     *pconn;
 
-       log_debug("%s: lsr-id %s transport-address %s", __func__,
-           inet_ntoa(id), log_addr(af, addr));
+       log_debug("%s: lsr-id %pI4 transport-address %s", __func__,
+           &id, log_addr(af, addr));
 
        if ((nbr = calloc(1, sizeof(*nbr))) == NULL)
                fatal(__func__);
@@ -289,7 +289,7 @@ nbr_del(struct nbr *nbr)
 {
        struct adj              *adj;
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
+       log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
 
        nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
 #ifdef __OpenBSD__
@@ -302,7 +302,7 @@ nbr_del(struct nbr *nbr)
        nbr->auth.method = AUTH_NONE;
 
        if (nbr_pending_connect(nbr))
-               THREAD_WRITE_OFF(nbr->ev_connect);
+               thread_cancel(&nbr->ev_connect);
        nbr_stop_ktimer(nbr);
        nbr_stop_ktimeout(nbr);
        nbr_stop_itimeout(nbr);
@@ -416,7 +416,7 @@ nbr_start_ktimer(struct nbr *nbr)
 
        /* send three keepalives per period */
        secs = nbr->keepalive / KEEPALIVE_PER_PERIOD;
-       THREAD_TIMER_OFF(nbr->keepalive_timer);
+       thread_cancel(&nbr->keepalive_timer);
        nbr->keepalive_timer = NULL;
        thread_add_timer(master, nbr_ktimer, nbr, secs, &nbr->keepalive_timer);
 }
@@ -424,7 +424,7 @@ nbr_start_ktimer(struct nbr *nbr)
 void
 nbr_stop_ktimer(struct nbr *nbr)
 {
-       THREAD_TIMER_OFF(nbr->keepalive_timer);
+       thread_cancel(&nbr->keepalive_timer);
 }
 
 /* Keepalive timeout: if the nbr hasn't sent keepalive */
@@ -436,7 +436,7 @@ nbr_ktimeout(struct thread *thread)
 
        nbr->keepalive_timeout = NULL;
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
+       log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
 
        session_shutdown(nbr, S_KEEPALIVE_TMR, 0, 0);
 
@@ -446,7 +446,7 @@ nbr_ktimeout(struct thread *thread)
 static void
 nbr_start_ktimeout(struct nbr *nbr)
 {
-       THREAD_TIMER_OFF(nbr->keepalive_timeout);
+       thread_cancel(&nbr->keepalive_timeout);
        nbr->keepalive_timeout = NULL;
        thread_add_timer(master, nbr_ktimeout, nbr, nbr->keepalive,
                         &nbr->keepalive_timeout);
@@ -455,7 +455,7 @@ nbr_start_ktimeout(struct nbr *nbr)
 void
 nbr_stop_ktimeout(struct nbr *nbr)
 {
-       THREAD_TIMER_OFF(nbr->keepalive_timeout);
+       thread_cancel(&nbr->keepalive_timeout);
 }
 
 /* Session initialization timeout: if nbr got stuck in the initialization FSM */
@@ -465,7 +465,7 @@ nbr_itimeout(struct thread *thread)
 {
        struct nbr      *nbr = THREAD_ARG(thread);
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
+       log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
 
        nbr_fsm(nbr, NBR_EVT_CLOSE_SESSION);
 
@@ -478,7 +478,7 @@ nbr_start_itimeout(struct nbr *nbr)
        int              secs;
 
        secs = INIT_FSM_TIMEOUT;
-       THREAD_TIMER_OFF(nbr->init_timeout);
+       thread_cancel(&nbr->init_timeout);
        nbr->init_timeout = NULL;
        thread_add_timer(master, nbr_itimeout, nbr, secs, &nbr->init_timeout);
 }
@@ -486,7 +486,7 @@ nbr_start_itimeout(struct nbr *nbr)
 void
 nbr_stop_itimeout(struct nbr *nbr)
 {
-       THREAD_TIMER_OFF(nbr->init_timeout);
+       thread_cancel(&nbr->init_timeout);
 }
 
 /* Init delay timer: timer to retry to iniziatize session */
@@ -498,7 +498,7 @@ nbr_idtimer(struct thread *thread)
 
        nbr->initdelay_timer = NULL;
 
-       log_debug("%s: lsr-id %s", __func__, inet_ntoa(nbr->id));
+       log_debug("%s: lsr-id %pI4", __func__, &nbr->id);
 
        nbr_establish_connection(nbr);
 
@@ -527,7 +527,7 @@ nbr_start_idtimer(struct nbr *nbr)
                break;
        }
 
-       THREAD_TIMER_OFF(nbr->initdelay_timer);
+       thread_cancel(&nbr->initdelay_timer);
        nbr->initdelay_timer = NULL;
        thread_add_timer(master, nbr_idtimer, nbr, secs,
                         &nbr->initdelay_timer);
@@ -536,7 +536,7 @@ nbr_start_idtimer(struct nbr *nbr)
 void
 nbr_stop_idtimer(struct nbr *nbr)
 {
-       THREAD_TIMER_OFF(nbr->initdelay_timer);
+       thread_cancel(&nbr->initdelay_timer);
 }
 
 int
@@ -619,12 +619,12 @@ nbr_establish_connection(struct nbr *nbr)
 
        if (nbr->af == AF_INET) {
                if (sock_set_ipv4_tos(nbr->fd, IPTOS_PREC_INTERNETCONTROL) == -1)
-                       log_warn("%s: lsr-id %s, sock_set_ipv4_tos error",
-                               __func__, inet_ntoa(nbr->id));
+                       log_warn("%s: lsr-id %pI4, sock_set_ipv4_tos error",
+                               __func__, &nbr->id);
        } else if (nbr->af == AF_INET6) {
                if (sock_set_ipv6_dscp(nbr->fd, IPTOS_PREC_INTERNETCONTROL) == -1)
-                       log_warn("%s: lsr-id %s, sock_set_ipv6_dscp error",
-                               __func__, inet_ntoa(nbr->id));
+                       log_warn("%s: lsr-id %pI4, sock_set_ipv6_dscp error",
+                               __func__, &nbr->id);
        }
 
        addr2sa(nbr->af, &nbr->laddr, 0, &local_su);
@@ -746,8 +746,8 @@ nbr_gtsm_check(int fd, struct nbr *nbr, struct nbr_params *nbrp)
        }
 
        if (nbr_gtsm_setup(fd, nbr->af, nbrp) == -1) {
-               log_warnx("%s: error enabling GTSM for lsr-id %s", __func__,
-                   inet_ntoa(nbr->id));
+               log_warnx("%s: error enabling GTSM for lsr-id %pI4", __func__,
+                   &nbr->id);
                return (-1);
        }
 
index 93be9d3cb03996c59dc04d3d35f19ee6fb524876..f84e0f893b8787c3ea5c3de02402a399f4124e30 100644 (file)
@@ -309,13 +309,13 @@ void
 log_msg_notification(int out, struct nbr *nbr, struct notify_msg *nm)
 {
        if (nm->status_code & STATUS_FATAL) {
-               debug_msg(out, "notification: lsr-id %s, status %s (fatal error)", inet_ntoa(nbr->id),
+               debug_msg(out, "notification: lsr-id %pI4, status %s (fatal error)", &nbr->id,
                    status_code_name(nm->status_code));
                return;
        }
 
-       debug_msg(out, "notification: lsr-id %s, status %s",
-           inet_ntoa(nbr->id), status_code_name(nm->status_code));
+       debug_msg(out, "notification: lsr-id %pI4, status %s",
+           &nbr->id, status_code_name(nm->status_code));
        if (nm->flags & F_NOTIF_FEC)
                debug_msg(out, "notification:   fec %s", log_map(&nm->fec));
        if (nm->flags & F_NOTIF_PW_STATUS)
index 3f73f8cd8850d0c4fc358de24b5c5cc41bfc5b91..fdcaa79d2396015c1d32b921aff4eefe35ba2792 100644 (file)
@@ -366,7 +366,7 @@ session_accept(struct thread *thread)
                return (0);
        }
        if (nbr->state != NBR_STA_PRESENT) {
-               log_debug("%s: lsr-id %s: rejecting additional transport connection", __func__, inet_ntoa(nbr->id));
+               log_debug("%s: lsr-id %pI4: rejecting additional transport connection", __func__, &nbr->id);
                close(newfd);
                return (0);
        }
@@ -558,8 +558,8 @@ session_read(struct thread *thread)
                                    type);
                                break;
                        default:
-                               log_debug("%s: unknown LDP message from nbr %s",
-                                   __func__, inet_ntoa(nbr->id));
+                               log_debug("%s: unknown LDP message from nbr %pI4",
+                                   __func__, &nbr->id);
                                if (!(ntohs(msg->type) & UNKNOWN_FLAG))
                                        send_notification(nbr->tcp,
                                            S_UNKNOWN_MSG, msg->id, msg->type);
@@ -662,7 +662,7 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
        switch (nbr->state) {
        case NBR_STA_PRESENT:
                if (nbr_pending_connect(nbr))
-                       THREAD_WRITE_OFF(nbr->ev_connect);
+                       thread_cancel(&nbr->ev_connect);
                break;
        case NBR_STA_INITIAL:
        case NBR_STA_OPENREC:
@@ -680,8 +680,8 @@ session_shutdown(struct nbr *nbr, uint32_t status, uint32_t msg_id,
 void
 session_close(struct nbr *nbr)
 {
-       log_debug("%s: closing session with lsr-id %s", __func__,
-           inet_ntoa(nbr->id));
+       log_debug("%s: closing session with lsr-id %pI4", __func__,
+           &nbr->id);
 
        ldp_sync_fsm_nbr_event(nbr, LDP_SYNC_EVT_SESSION_CLOSE);
 
@@ -762,7 +762,7 @@ tcp_close(struct tcp_conn *tcp)
        evbuf_clear(&tcp->wbuf);
 
        if (tcp->nbr) {
-               THREAD_READ_OFF(tcp->rev);
+               thread_cancel(&tcp->rev);
                free(tcp->rbuf);
                tcp->nbr->tcp = NULL;
        }
@@ -794,7 +794,7 @@ pending_conn_new(int fd, int af, union ldpd_addr *addr)
 void
 pending_conn_del(struct pending_conn *pconn)
 {
-       THREAD_TIMER_OFF(pconn->ev_timeout);
+       thread_cancel(&pconn->ev_timeout);
        TAILQ_REMOVE(&global.pending_conns, pconn, entry);
        free(pconn);
 }
index 7c4bdcbe27d02f565c9390b975d56831ce012d34..603d8d6172d7926f7e842d9682cc67331a60914b 100644 (file)
@@ -107,7 +107,7 @@ static void agentx_events_update(void)
        struct thread *thr;
        int fd, thr_fd;
 
-       THREAD_OFF(timeout_thr);
+       thread_cancel(&timeout_thr);
 
        FD_ZERO(&fds);
        snmp_select_info(&maxfd, &fds, &timeout, &block);
@@ -130,7 +130,7 @@ static void agentx_events_update(void)
                if (thr_fd == fd) {
                        struct listnode *nextln = listnextnode(ln);
                        if (!FD_ISSET(fd, &fds)) {
-                               thread_cancel(thr);
+                               thread_cancel(&thr);
                                list_delete_node(events, ln);
                        }
                        ln = nextln;
@@ -151,7 +151,8 @@ static void agentx_events_update(void)
         */
        while (ln) {
                struct listnode *nextln = listnextnode(ln);
-               thread_cancel(listgetdata(ln));
+               thr = listgetdata(ln);
+               thread_cancel(&thr);
                list_delete_node(events, ln);
                ln = nextln;
        }
index e98476f1b7d3e0cda389daa41c866194dcc97177..e0c06449eee22efd97c989b95b11fe1fec86797a 100644 (file)
@@ -161,6 +161,11 @@ agg_node_get_prefix(const struct agg_node *node)
        return &node->p;
 }
 
+static inline unsigned int agg_node_get_lock_count(const struct agg_node *node)
+{
+       return node->lock;
+}
+
 #ifdef _FRR_ATTRIBUTE_PRINTFRR
 #pragma FRR printfrr_ext "%pRN"  (struct agg_node *)
 #endif
index 1e950fe48334f62437557911adbd578ff45c3574..7d335e1c366a39db2d6fb5ad3d7251bb49c354e2 100644 (file)
@@ -139,6 +139,27 @@ static struct cmd_node config_node = {
        .node_exit = vty_config_node_exit,
 };
 
+static bool vty_check_node_for_xpath_decrement(enum node_type target_node,
+                                              enum node_type node)
+{
+       /* bgp afi-safi (`address-family <afi> <safi>`) node
+        * does not increment xpath_index.
+        * In order to use (`router bgp`) BGP_NODE's xpath as a base,
+        * retain xpath_index as 1 upon exiting from
+        * afi-safi node.
+        */
+
+       if (target_node == BGP_NODE
+           && (node == BGP_IPV4_NODE || node == BGP_IPV6_NODE
+               || node == BGP_IPV4M_NODE || node == BGP_IPV6M_NODE
+               || node == BGP_VPNV4_NODE || node == BGP_VPNV6_NODE
+               || node == BGP_EVPN_NODE || node == BGP_IPV4L_NODE
+               || node == BGP_IPV6L_NODE ))
+               return false;
+
+       return true;
+}
+
 /* This is called from main when a daemon is invoked with -v or --version. */
 void print_version(const char *progname)
 {
@@ -985,7 +1006,9 @@ int cmd_execute_command(vector vline, struct vty *vty,
                while (vty->node > CONFIG_NODE) {
                        try_node = node_parent(try_node);
                        vty->node = try_node;
-                       if (vty->xpath_index > 0)
+                       if (vty->xpath_index > 0
+                           && vty_check_node_for_xpath_decrement(try_node,
+                                                                 onode))
                                vty->xpath_index--;
                        ret = cmd_execute_command_real(vline, FILTER_RELAXED,
                                                       vty, cmd);
@@ -1194,7 +1217,9 @@ int command_config_read_one_line(struct vty *vty,
                       && ret != CMD_SUCCESS && ret != CMD_WARNING
                       && vty->node > CONFIG_NODE) {
                        vty->node = node_parent(vty->node);
-                       if (vty->xpath_index > 0)
+                       if (vty->xpath_index > 0
+                           && vty_check_node_for_xpath_decrement(vty->node,
+                                                                 saved_node))
                                vty->xpath_index--;
                        ret = cmd_execute_command_strict(vline, vty, cmd);
                }
@@ -1316,7 +1341,8 @@ void cmd_exit(struct vty *vty)
        }
        if (cnode->parent_node)
                vty->node = cnode->parent_node;
-       if (vty->xpath_index > 0)
+       if (vty->xpath_index > 0
+           && vty_check_node_for_xpath_decrement(vty->node, cnode->node))
                vty->xpath_index--;
 }
 
index dc148a92a80ceccfa4d35e23d8f5fd7a531d260c..bb007b08683af952007481eaa1c04da5df104a4c 100644 (file)
@@ -452,6 +452,25 @@ struct cmd_node {
 #define GR_NEIGHBOR_HELPER_CMD "Graceful Restart Helper command for a neighbor\n"
 #define NO_GR_NEIGHBOR_HELPER_CMD "Undo Graceful Restart Helper command for a neighbor\n"
 
+/* EVPN help Strings */
+#define EVPN_RT_HELP_STR "EVPN route information\n"
+#define EVPN_RT_DIST_HELP_STR "Route Distinguisher\n"
+#define EVPN_ASN_IP_HELP_STR "ASN:XX or A.B.C.D:XX\n"
+#define EVPN_TYPE_HELP_STR "Specify Route type\n"
+#define EVPN_TYPE_1_HELP_STR "EAD (Type-1) route\n"
+#define EVPN_TYPE_2_HELP_STR "MAC-IP (Type-2) route\n"
+#define EVPN_TYPE_3_HELP_STR "Multicast (Type-3) route\n"
+#define EVPN_TYPE_4_HELP_STR "Ethernet Segment (Type-4) route\n"
+#define EVPN_TYPE_5_HELP_STR "Prefix (Type-5) route\n"
+#define EVPN_TYPE_ALL_LIST "<ead|1|macip|2|multicast|3|es|4|prefix|5>"
+#define EVPN_TYPE_ALL_LIST_HELP_STR                                            \
+       EVPN_TYPE_1_HELP_STR EVPN_TYPE_1_HELP_STR                              \
+       EVPN_TYPE_2_HELP_STR EVPN_TYPE_2_HELP_STR                              \
+       EVPN_TYPE_3_HELP_STR EVPN_TYPE_3_HELP_STR                              \
+       EVPN_TYPE_4_HELP_STR EVPN_TYPE_4_HELP_STR                              \
+       EVPN_TYPE_5_HELP_STR EVPN_TYPE_5_HELP_STR
+
+
 /* Prototypes. */
 extern void install_node(struct cmd_node *node);
 extern void install_default(enum node_type);
index e6add0462b9d3f93e5087d2b65d94a79ec53f262..f5ae9ee2b75e321b19f88223932a6a60b684372c 100644 (file)
@@ -576,14 +576,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
                                if (filter->addr_mask.s_addr == 0xffffffff)
                                        vty_out(vty, " any\n");
                                else {
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(filter->addr));
+                                       vty_out(vty, " %pI4", &filter->addr);
                                        if (filter->addr_mask.s_addr
                                            != INADDR_ANY)
                                                vty_out(vty,
-                                                       ", wildcard bits %s",
-                                                       inet_ntoa(
-                                                               filter->addr_mask));
+                                                       ", wildcard bits %pI4",
+                                                       &filter->addr_mask);
                                        vty_out(vty, "\n");
                                }
                        }
@@ -625,14 +623,12 @@ static int filter_show(struct vty *vty, const char *name, afi_t afi)
                                if (filter->addr_mask.s_addr == 0xffffffff)
                                        vty_out(vty, " any\n");
                                else {
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(filter->addr));
+                                       vty_out(vty, " %pI4", &filter->addr);
                                        if (filter->addr_mask.s_addr
                                            != INADDR_ANY)
                                                vty_out(vty,
-                                                       ", wildcard bits %s",
-                                                       inet_ntoa(
-                                                               filter->addr_mask));
+                                                       ", wildcard bits %pI4",
+                                                       &filter->addr_mask);
                                        vty_out(vty, "\n");
                                }
                        }
@@ -722,29 +718,28 @@ static void config_write_access_cisco(struct vty *vty, struct filter *mfilter)
                if (filter->addr_mask.s_addr == 0xffffffff)
                        vty_out(vty, " any");
                else if (filter->addr_mask.s_addr == INADDR_ANY)
-                       vty_out(vty, " host %s", inet_ntoa(filter->addr));
+                       vty_out(vty, " host %pI4", &filter->addr);
                else {
-                       vty_out(vty, " %s", inet_ntoa(filter->addr));
-                       vty_out(vty, " %s", inet_ntoa(filter->addr_mask));
+                       vty_out(vty, " %pI4", &filter->addr);
+                       vty_out(vty, " %pI4", &filter->addr_mask);
                }
 
                if (filter->mask_mask.s_addr == 0xffffffff)
                        vty_out(vty, " any");
                else if (filter->mask_mask.s_addr == INADDR_ANY)
-                       vty_out(vty, " host %s", inet_ntoa(filter->mask));
+                       vty_out(vty, " host %pI4", &filter->mask);
                else {
-                       vty_out(vty, " %s", inet_ntoa(filter->mask));
-                       vty_out(vty, " %s", inet_ntoa(filter->mask_mask));
+                       vty_out(vty, " %pI4", &filter->mask);
+                       vty_out(vty, " %pI4", &filter->mask_mask);
                }
                vty_out(vty, "\n");
        } else {
                if (filter->addr_mask.s_addr == 0xffffffff)
                        vty_out(vty, " any\n");
                else {
-                       vty_out(vty, " %s", inet_ntoa(filter->addr));
+                       vty_out(vty, " %pI4", &filter->addr);
                        if (filter->addr_mask.s_addr != INADDR_ANY)
-                               vty_out(vty, " %s",
-                                       inet_ntoa(filter->addr_mask));
+                               vty_out(vty, " %pI4", &filter->addr_mask);
                        vty_out(vty, "\n");
                }
        }
index 09fc3289cea8178793f78cc28bf11494832fa315..a8230f3a9a7f86d9b8fa20fc0ea352bcadcdfa0d 100644 (file)
@@ -114,21 +114,6 @@ static int64_t acl_zebra_get_seq(struct access_list *acl, const char *action,
        return fn->seq;
 }
 
-/*
- * Helper function to concatenate address with mask in Cisco style.
- */
-static void concat_addr_mask_v4(const char *addr, const char *mask, char *dst,
-                               size_t dstlen)
-{
-       struct in_addr ia;
-       int plen;
-
-       assert(inet_pton(AF_INET, mask, &ia) == 1);
-       ia.s_addr = ~ia.s_addr;
-       plen = ip_masklen(ia);
-       snprintf(dst, dstlen, "%s/%d", addr, plen);
-}
-
 /*
  * Helper function to generate a sequence number for legacy commands.
  */
@@ -177,7 +162,6 @@ DEFPY_YANG(
        "Wildcard bits\n")
 {
        int64_t sseq;
-       char ipmask[64];
        char xpath[XPATH_MAXLEN];
        char xpath_entry[XPATH_MAXLEN + 128];
 
@@ -203,8 +187,10 @@ DEFPY_YANG(
        if (host_str != NULL && mask_str == NULL) {
                nb_cli_enqueue_change(vty, "./host", NB_OP_MODIFY, host_str);
        } else if (host_str != NULL && mask_str != NULL) {
-               concat_addr_mask_v4(host_str, mask_str, ipmask, sizeof(ipmask));
-               nb_cli_enqueue_change(vty, "./network", NB_OP_MODIFY, ipmask);
+               nb_cli_enqueue_change(vty, "./network/address", NB_OP_MODIFY,
+                                     host_str);
+               nb_cli_enqueue_change(vty, "./network/mask", NB_OP_MODIFY,
+                                     mask_str);
        } else {
                nb_cli_enqueue_change(vty, "./source-any", NB_OP_CREATE, NULL);
        }
@@ -285,7 +271,6 @@ DEFPY_YANG(
        "Any destination host\n")
 {
        int64_t sseq;
-       char ipmask[64], ipmask_dst[64];
        char xpath[XPATH_MAXLEN];
        char xpath_entry[XPATH_MAXLEN + 128];
 
@@ -311,9 +296,10 @@ DEFPY_YANG(
        if (src_str != NULL && src_mask_str == NULL) {
                nb_cli_enqueue_change(vty, "./host", NB_OP_MODIFY, src_str);
        } else if (src_str != NULL && src_mask_str != NULL) {
-               concat_addr_mask_v4(src_str, src_mask_str, ipmask,
-                                   sizeof(ipmask));
-               nb_cli_enqueue_change(vty, "./network", NB_OP_MODIFY, ipmask);
+               nb_cli_enqueue_change(vty, "./network/address", NB_OP_MODIFY,
+                                     src_str);
+               nb_cli_enqueue_change(vty, "./network/mask", NB_OP_MODIFY,
+                                     src_mask_str);
        } else {
                nb_cli_enqueue_change(vty, "./source-any", NB_OP_CREATE, NULL);
        }
@@ -322,10 +308,10 @@ DEFPY_YANG(
                nb_cli_enqueue_change(vty, "./destination-host", NB_OP_MODIFY,
                                      dst_str);
        } else if (dst_str != NULL && dst_mask_str != NULL) {
-               concat_addr_mask_v4(dst_str, dst_mask_str, ipmask_dst,
-                                   sizeof(ipmask_dst));
-               nb_cli_enqueue_change(vty, "./destination-network",
-                                     NB_OP_MODIFY, ipmask_dst);
+               nb_cli_enqueue_change(vty, "./destination-network/address",
+                                     NB_OP_MODIFY, dst_str);
+               nb_cli_enqueue_change(vty, "./destination-network/mask",
+                                     NB_OP_MODIFY, dst_mask_str);
        } else {
                nb_cli_enqueue_change(vty, "./destination-any", NB_OP_CREATE,
                                      NULL);
@@ -947,7 +933,7 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
        bool is_exact = false;
        bool cisco_style = false;
        bool cisco_extended = false;
-       struct in_addr mask;
+       struct in_addr addr, mask;
        char macstr[PREFIX2STR_BUFFER];
 
        is_any = yang_dnode_exists(dnode, "./any");
@@ -957,11 +943,12 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
                        break;
 
                if (yang_dnode_exists(dnode, "./host")
-                   || yang_dnode_exists(dnode, "./network")
+                   || yang_dnode_exists(dnode, "./network/address")
                    || yang_dnode_exists(dnode, "./source-any")) {
                        cisco_style = true;
                        if (yang_dnode_exists(dnode, "./destination-host")
-                           || yang_dnode_exists(dnode, "./destination-network")
+                           || yang_dnode_exists(
+                                   dnode, "./destination-network/address")
                            || yang_dnode_exists(dnode, "./destination-any"))
                                cisco_extended = true;
                } else {
@@ -998,9 +985,9 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
                        vty_out(vty, " ip");
 
                if (yang_dnode_exists(dnode, "./network")) {
-                       yang_dnode_get_prefix(&p, dnode, "./network");
-                       masklen2ip(p.prefixlen, &mask);
-                       vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask);
+                       yang_dnode_get_ipv4(&addr, dnode, "./network/address");
+                       yang_dnode_get_ipv4(&mask, dnode, "./network/mask");
+                       vty_out(vty, " %pI4 %pI4", &addr, &mask);
                } else if (yang_dnode_exists(dnode, "./host")) {
                        if (cisco_extended)
                                vty_out(vty, " host");
@@ -1018,10 +1005,11 @@ void access_list_show(struct vty *vty, struct lyd_node *dnode,
 
                /* Handle destination address. */
                if (yang_dnode_exists(dnode, "./destination-network")) {
-                       yang_dnode_get_prefix(&p, dnode,
-                                             "./destination-network");
-                       masklen2ip(p.prefixlen, &mask);
-                       vty_out(vty, " %pI4 %pI4", &p.u.prefix4, &mask);
+                       yang_dnode_get_ipv4(&addr, dnode,
+                                           "./destination-network/address");
+                       yang_dnode_get_ipv4(&mask, dnode,
+                                           "./destination-network/mask");
+                       vty_out(vty, " %pI4 %pI4", &addr, &mask);
                } else if (yang_dnode_exists(dnode, "./destination-host"))
                        vty_out(vty, " host %s",
                                yang_dnode_get_string(dnode,
index 8838a48abd5504d26a8214f867514e85cca566d9..1d522bdbec56b9c890aa57b6a5dc069a709c8b28 100644 (file)
 #include "lib/routemap.h"
 
 /* Helper function. */
-static in_addr_t
-ipv4_network_addr(in_addr_t hostaddr, int masklen)
-{
-       struct in_addr mask;
-
-       masklen2ip(masklen, &mask);
-       return hostaddr & mask.s_addr;
-}
-
 static void acl_notify_route_map(struct access_list *acl, int route_map_event)
 {
        switch (route_map_event) {
@@ -86,11 +77,11 @@ static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args)
 
        /*
         * Check rule:
-        * prefix length < ge.
+        * prefix length <= ge.
         */
        if (yang_dnode_exists(args->dnode, xpath_ge)) {
                ge = yang_dnode_get_uint8(args->dnode, xpath_ge);
-               if (p.prefixlen >= ge)
+               if (p.prefixlen > ge)
                        goto log_and_fail;
        }
 
@@ -111,7 +102,7 @@ static enum nb_error prefix_list_length_validate(struct nb_cb_modify_args *args)
 log_and_fail:
        snprintfrr(
                args->errmsg, args->errmsg_len,
-               "Invalid prefix range for %pFX: Make sure that mask length < ge <= le",
+               "Invalid prefix range for %pFX: Make sure that mask length <= ge <= le",
                &p);
        return NB_ERR_VALIDATION;
 }
@@ -411,14 +402,13 @@ lib_access_list_entry_host_destroy(struct nb_cb_destroy_args *args)
 }
 
 /*
- * XPath: /frr-filter:lib/access-list/entry/network
+ * XPath: /frr-filter:lib/access-list/entry/network/address
  */
 static int
-lib_access_list_entry_network_modify(struct nb_cb_modify_args *args)
+lib_access_list_entry_network_address_modify(struct nb_cb_modify_args *args)
 {
        struct filter_cisco *fc;
        struct filter *f;
-       struct prefix p;
 
        if (args->event != NB_EV_APPLY)
                return NB_OK;
@@ -426,18 +416,18 @@ lib_access_list_entry_network_modify(struct nb_cb_modify_args *args)
        f = nb_running_get_entry(args->dnode, NULL, true);
        f->cisco = 1;
        fc = &f->u.cfilter;
-       yang_dnode_get_prefix(&p, args->dnode, NULL);
-       fc->addr.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
-       masklen2ip(p.prefixlen, &fc->addr_mask);
-       fc->addr_mask.s_addr = ~fc->addr_mask.s_addr;
+       yang_dnode_get_ipv4(&fc->addr, args->dnode, NULL);
 
        acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
 
        return NB_OK;
 }
 
+/*
+ * XPath: /frr-filter:lib/access-list/entry/network/mask
+ */
 static int
-lib_access_list_entry_network_destroy(struct nb_cb_destroy_args *args)
+lib_access_list_entry_network_mask_modify(struct nb_cb_modify_args *args)
 {
        struct filter_cisco *fc;
        struct filter *f;
@@ -446,10 +436,11 @@ lib_access_list_entry_network_destroy(struct nb_cb_destroy_args *args)
                return NB_OK;
 
        f = nb_running_get_entry(args->dnode, NULL, true);
+       f->cisco = 1;
        fc = &f->u.cfilter;
-       cisco_unset_addr_mask(&fc->addr, &fc->addr_mask);
+       yang_dnode_get_ipv4(&fc->addr_mask, args->dnode, NULL);
 
-       acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
+       acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
 
        return NB_OK;
 }
@@ -538,14 +529,13 @@ static int lib_access_list_entry_destination_host_destroy(
 }
 
 /*
- * XPath: /frr-filter:lib/access-list/entry/destination-network
+ * XPath: /frr-filter:lib/access-list/entry/destination-network/address
  */
-static int lib_access_list_entry_destination_network_modify(
+static int lib_access_list_entry_destination_network_address_modify(
        struct nb_cb_modify_args *args)
 {
        struct filter_cisco *fc;
        struct filter *f;
-       struct prefix p;
 
        if (args->event != NB_EV_APPLY)
                return NB_OK;
@@ -553,18 +543,18 @@ static int lib_access_list_entry_destination_network_modify(
        f = nb_running_get_entry(args->dnode, NULL, true);
        fc = &f->u.cfilter;
        fc->extended = 1;
-       yang_dnode_get_prefix(&p, args->dnode, NULL);
-       fc->mask.s_addr = ipv4_network_addr(p.u.prefix4.s_addr, p.prefixlen);
-       masklen2ip(p.prefixlen, &fc->mask_mask);
-       fc->mask_mask.s_addr = ~fc->mask_mask.s_addr;
+       yang_dnode_get_ipv4(&fc->mask, args->dnode, NULL);
 
        acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
 
        return NB_OK;
 }
 
-static int lib_access_list_entry_destination_network_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * XPath: /frr-filter:lib/access-list/entry/destination-network/mask
+ */
+static int lib_access_list_entry_destination_network_mask_modify(
+       struct nb_cb_modify_args *args)
 {
        struct filter_cisco *fc;
        struct filter *f;
@@ -574,10 +564,10 @@ static int lib_access_list_entry_destination_network_destroy(
 
        f = nb_running_get_entry(args->dnode, NULL, true);
        fc = &f->u.cfilter;
-       fc->extended = 0;
-       cisco_unset_addr_mask(&fc->mask, &fc->mask_mask);
+       fc->extended = 1;
+       yang_dnode_get_ipv4(&fc->mask_mask, args->dnode, NULL);
 
-       acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_DELETED);
+       acl_notify_route_map(f->acl, RMAP_EVENT_FILTER_ADDED);
 
        return NB_OK;
 }
@@ -1100,10 +1090,15 @@ const struct frr_yang_module_info frr_filter_info = {
                        }
                },
                {
-                       .xpath = "/frr-filter:lib/access-list/entry/network",
+                       .xpath = "/frr-filter:lib/access-list/entry/network/address",
                        .cbs = {
-                               .modify = lib_access_list_entry_network_modify,
-                               .destroy = lib_access_list_entry_network_destroy,
+                               .modify = lib_access_list_entry_network_address_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-filter:lib/access-list/entry/network/mask",
+                       .cbs = {
+                               .modify = lib_access_list_entry_network_mask_modify,
                        }
                },
                {
@@ -1121,10 +1116,15 @@ const struct frr_yang_module_info frr_filter_info = {
                        }
                },
                {
-                       .xpath = "/frr-filter:lib/access-list/entry/destination-network",
+                       .xpath = "/frr-filter:lib/access-list/entry/destination-network/address",
+                       .cbs = {
+                               .modify = lib_access_list_entry_destination_network_address_modify,
+                       }
+               },
+               {
+                       .xpath = "/frr-filter:lib/access-list/entry/destination-network/mask",
                        .cbs = {
-                               .modify = lib_access_list_entry_destination_network_modify,
-                               .destroy = lib_access_list_entry_destination_network_destroy,
+                               .modify = lib_access_list_entry_destination_network_mask_modify,
                        }
                },
                {
index da9594ed808c12d9f3b34ad33d5bee085ad902ed..3f0179fbc1386e805430ffd20c8a446b7a28ad4c 100644 (file)
@@ -28,6 +28,7 @@
 #include "memory.h"
 #include "linklist.h"
 #include "zlog.h"
+#include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, FRR_PTHREAD, "FRR POSIX Thread")
 DEFINE_MTYPE_STATIC(LIB, PTHREAD_PRIM, "POSIX sync primitives")
@@ -167,6 +168,8 @@ int frr_pthread_run(struct frr_pthread *fpt, const pthread_attr_t *attr)
        sigfillset(&blocksigs);
        pthread_sigmask(SIG_BLOCK, &blocksigs, &oldsigs);
 
+       frrtrace(1, frr_libfrr, frr_pthread_run, fpt->name);
+
        fpt->rcu_thread = rcu_thread_prepare();
        ret = pthread_create(&fpt->thread, attr, frr_pthread_inner, fpt);
 
@@ -204,6 +207,8 @@ void frr_pthread_notify_running(struct frr_pthread *fpt)
 
 int frr_pthread_stop(struct frr_pthread *fpt, void **result)
 {
+       frrtrace(1, frr_libfrr, frr_pthread_stop, fpt->name);
+
        int ret = (*fpt->attr.stop)(fpt, result);
        memset(&fpt->thread, 0x00, sizeof(fpt->thread));
        return ret;
index 565936a41026d209b920cb7a714bb46fecaade45..cc11d76700986ce4d5761f992a2d78580bf2f4a0 100644 (file)
@@ -190,10 +190,8 @@ int funcname_frrzmq_thread_add_read(struct thread_master *master,
        cb->read.cancelled = false;
 
        if (events & ZMQ_POLLIN) {
-               if (cb->read.thread) {
-                       thread_cancel(cb->read.thread);
-                       cb->read.thread = NULL;
-               }
+               thread_cancel(&cb->read.thread);
+
                funcname_thread_add_event(master, frrzmq_read_msg, cbp, fd,
                                          &cb->read.thread, funcname, schedfrom,
                                          fromln);
@@ -298,10 +296,8 @@ int funcname_frrzmq_thread_add_write(struct thread_master *master,
        cb->write.cancelled = false;
 
        if (events & ZMQ_POLLOUT) {
-               if (cb->write.thread) {
-                       thread_cancel(cb->write.thread);
-                       cb->write.thread = NULL;
-               }
+               thread_cancel(&cb->write.thread);
+
                funcname_thread_add_event(master, frrzmq_write_msg, cbp, fd,
                                          &cb->write.thread, funcname,
                                          schedfrom, fromln);
@@ -317,10 +313,8 @@ void frrzmq_thread_cancel(struct frrzmq_cb **cb, struct cb_core *core)
        if (!cb || !*cb)
                return;
        core->cancelled = true;
-       if (core->thread) {
-               thread_cancel(core->thread);
-               core->thread = NULL;
-       }
+       thread_cancel(&core->thread);
+
        if ((*cb)->read.cancelled && !(*cb)->read.thread
            && (*cb)->write.cancelled && (*cb)->write.thread)
                XFREE(MTYPE_ZEROMQ_CB, *cb);
@@ -344,8 +338,8 @@ void frrzmq_check_events(struct frrzmq_cb **cbp, struct cb_core *core,
                return;
        if (events & event && core->thread && !core->cancelled) {
                struct thread_master *tm = core->thread->master;
-               thread_cancel(core->thread);
-               core->thread = NULL;
+               thread_cancel(&core->thread);
+
                thread_add_event(tm, (event == ZMQ_POLLIN ? frrzmq_read_msg
                                                          : frrzmq_write_msg),
                                 cbp, cb->fd, &core->thread);
index 85982774ac8162c1d0c1ccdf2a9515fc44a0e303..ed429b77d079a2dbe54346dde93cf0108067d801 100644 (file)
@@ -29,6 +29,7 @@
 #include "command.h"
 #include "libfrr.h"
 #include "frr_pthread.h"
+#include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, HASH, "Hash")
 DEFINE_MTYPE_STATIC(LIB, HASH_BACKET, "Hash Bucket")
@@ -138,6 +139,8 @@ static void hash_expand(struct hash *hash)
 
 void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
 {
+       frrtrace(2, frr_libfrr, hash_get, hash, data);
+
        unsigned int key;
        unsigned int index;
        void *newdata;
@@ -172,6 +175,8 @@ void *hash_get(struct hash *hash, void *data, void *(*alloc_func)(void *))
                hash->index[index] = bucket;
                hash->count++;
 
+               frrtrace(3, frr_libfrr, hash_insert, hash, data, key);
+
                int oldlen = bucket->next ? bucket->next->len : 0;
                int newlen = oldlen + 1;
 
@@ -206,7 +211,7 @@ unsigned int string_hash_make(const char *str)
 
 void *hash_release(struct hash *hash, void *data)
 {
-       void *ret;
+       void *ret = NULL;
        unsigned int key;
        unsigned int index;
        struct hash_bucket *bucket;
@@ -236,11 +241,14 @@ void *hash_release(struct hash *hash, void *data)
                        ret = bucket->data;
                        XFREE(MTYPE_HASH_BACKET, bucket);
                        hash->count--;
-                       return ret;
+                       break;
                }
                pp = bucket;
        }
-       return NULL;
+
+       frrtrace(3, frr_libfrr, hash_release, hash, data, ret);
+
+       return ret;
 }
 
 void hash_iterate(struct hash *hash, void (*func)(struct hash_bucket *, void *),
index 304840e5b9ee4710e982d87502c4d03eff6e5bb2..c707c4c6d9040cc6794fa4c0eda291639d443ae5 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -826,7 +826,7 @@ DEFUN (show_address,
                        p = ifc->address;
 
                        if (p->family == AF_INET)
-                               vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen);
+                               vty_out (vty, "%pFX\n", p);
                }
        }
        return CMD_SUCCESS;
@@ -858,7 +858,7 @@ DEFUN (show_address_vrf_all,
                                p = ifc->address;
 
                                if (p->family == AF_INET)
-                                       vty_out (vty, "%s/%d\n", inet_ntoa (p->u.prefix4), p->prefixlen);
+                                       vty_out (vty, "%pFX\n", p);
                        }
                }
        }
@@ -929,10 +929,9 @@ connected_log(struct connected *connected, char *str)
        p = connected->address;
 
        vrf = vrf_lookup_by_id(ifp->vrf_id);
-       snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %s/%d ",
+       snprintf(logbuf, sizeof(logbuf), "%s interface %s vrf %s(%u) %s %pFX ",
                 str, ifp->name, VRF_LOGNAME(vrf), ifp->vrf_id,
-                prefix_family_str(p),
-                inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
+                prefix_family_str(p), p);
 
        p = connected->destination;
        if (p) {
@@ -949,14 +948,12 @@ nbr_connected_log(struct nbr_connected *connected, char *str)
        struct prefix *p;
        struct interface *ifp;
        char logbuf[BUFSIZ];
-       char buf[BUFSIZ];
 
        ifp = connected->ifp;
        p = connected->address;
 
-       snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %s/%d ", str,
-                ifp->name, prefix_family_str(p),
-                inet_ntop(p->family, &p->u.prefix, buf, BUFSIZ), p->prefixlen);
+       snprintf(logbuf, sizeof(logbuf), "%s interface %s %s %pFX ", str,
+                ifp->name, prefix_family_str(p), p);
 
        zlog_info("%s", logbuf);
 }
@@ -1109,8 +1106,8 @@ ifaddr_ipv4_add (struct in_addr *ifaddr, struct interface *ifp)
   if (rn)
     {
       route_unlock_node (rn);
-      zlog_info ("ifaddr_ipv4_add(): address %s is already added",
-                inet_ntoa (*ifaddr));
+      zlog_info("ifaddr_ipv4_add(): address %pI4 is already added",
+                               ifaddr);
       return;
     }
   rn->info = ifp;
@@ -1129,8 +1126,7 @@ ifaddr_ipv4_delete (struct in_addr *ifaddr, struct interface *ifp)
   rn = route_node_lookup (ifaddr_ipv4_table, (struct prefix *) &p);
   if (! rn)
     {
-      zlog_info ("ifaddr_ipv4_delete(): can't find address %s",
-                inet_ntoa (*ifaddr));
+      zlog_info("%s: can't find address %pI4", __func__, ifaddr);
       return;
     }
   rn->info = NULL;
index 6bea3982e3e47a7d9011a47eec9b5c3b08f54695..cfba6ea3b61ed4e1c669a82cbfa08456063cc402 100644 (file)
@@ -39,6 +39,11 @@ bool use_json(const int argc, struct cmd_token *argv[])
        return false;
 }
 
+void json_array_string_add(json_object *json, const char *str)
+{
+       json_object_array_add(json, json_object_new_string(str));
+}
+
 void json_object_string_add(struct json_object *obj, const char *key,
                            const char *s)
 {
index afe0b175da79618d64cbbbc47bc96bfd00f2b36a..fe208f4fa9c2856200e34c63826cf8a2e32e75d3 100644 (file)
@@ -57,6 +57,7 @@ extern void json_object_boolean_true_add(struct json_object *obj,
                                         const char *key);
 extern struct json_object *json_object_lock(struct json_object *obj);
 extern void json_object_free(struct json_object *obj);
+extern void json_array_string_add(json_object *json, const char *str);
 
 #define JSON_STR "JavaScript Object Notation\n"
 
index 5dd045d88d85538d34c2aeffd9c085a71dbc46f6..c9d7eb37cfd2d0ba9fa551b46882095c0999c761 100644 (file)
@@ -79,10 +79,8 @@ bool ldp_sync_if_down(struct ldp_sync_info *ldp_sync_info)
         *   update state
         */
        if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
-               if (ldp_sync_info->t_holddown != NULL) {
-                       THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-                       ldp_sync_info->t_holddown = NULL;
-               }
+               THREAD_OFF(ldp_sync_info->t_holddown);
+
                if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP)
                        ldp_sync_info->state =
                                LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
diff --git a/lib/libfrr_trace.c b/lib/libfrr_trace.c
new file mode 100644 (file)
index 0000000..2f300e6
--- /dev/null
@@ -0,0 +1,4 @@
+#define TRACEPOINT_CREATE_PROBES
+#define TRACEPOINT_DEFINE
+
+#include "libfrr_trace.h"
diff --git a/lib/libfrr_trace.h b/lib/libfrr_trace.h
new file mode 100644 (file)
index 0000000..7215007
--- /dev/null
@@ -0,0 +1,240 @@
+/* Tracing
+ *
+ * Copyright (C) 2020  NVIDIA Corporation
+ * Quentin Young
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined(_LIBFRR_TRACE_H_) || defined(TRACEPOINT_HEADER_MULTI_READ)
+#define _LIBFRR_TRACE_H_
+
+#include "trace.h"
+
+#ifdef HAVE_LTTNG
+
+#undef TRACEPOINT_PROVIDER
+#define TRACEPOINT_PROVIDER frr_libfrr
+
+#undef TRACEPOINT_INCLUDE
+#define TRACEPOINT_INCLUDE "./libfrr_trace.h"
+
+#include <lttng/tracepoint.h>
+
+#include "hash.h"
+#include "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "table.h"
+
+/* clang-format off */
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       hash_get,
+       TP_ARGS(struct hash *, hash, void *, data),
+       TP_FIELDS(
+               ctf_string(name, hash->name ? hash->name : "(unnamed)")
+               ctf_integer(unsigned int, index_size, hash->size)
+               ctf_integer(unsigned long, item_count, hash->count)
+               ctf_integer_hex(intptr_t, data_ptr, data)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_get, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       hash_insert,
+       TP_ARGS(struct hash *, hash, void *, data, unsigned int, key),
+       TP_FIELDS(
+               ctf_string(name, hash->name ? hash->name : "(unnamed)")
+               ctf_integer(unsigned int, key, hash->size)
+               ctf_integer(unsigned int, index_size, hash->size)
+               ctf_integer(unsigned long, item_count, hash->count)
+               ctf_integer_hex(intptr_t, data_ptr, data)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_insert, TRACE_INFO)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       hash_release,
+       TP_ARGS(struct hash *, hash, void *, data, void *, released_item),
+       TP_FIELDS(
+               ctf_string(name, hash->name ? hash->name : "(unnamed)")
+               ctf_integer(unsigned int, index_size, hash->size)
+               ctf_integer(unsigned long, item_count, hash->count)
+               ctf_integer_hex(intptr_t, data_ptr, data)
+               ctf_integer_hex(intptr_t, released_item, data)
+       )
+)
+
+TRACEPOINT_LOGLEVEL(frr_libfrr, hash_release, TRACE_INFO)
+
+#define THREAD_SCHEDULE_ARGS                                                   \
+       TP_ARGS(struct thread_master *, master, const char *, funcname,        \
+               const char *, schedfrom, int, fromln, struct thread **,        \
+               thread_ptr, int, fd, int, val, void *, arg, long, time)
+
+TRACEPOINT_EVENT_CLASS(
+       frr_libfrr,
+       thread_operation,
+       THREAD_SCHEDULE_ARGS,
+       TP_FIELDS(
+               ctf_string(threadmaster_name, master->name)
+               ctf_string(function_name, funcname ? funcname : "(unknown function)")
+               ctf_string(scheduled_from, schedfrom ? schedfrom : "(unknown file)")
+               ctf_integer(int, scheduled_on_line, fromln)
+               ctf_integer_hex(intptr_t, thread_addr, thread_ptr ? *thread_ptr : NULL)
+               ctf_integer(int, file_descriptor, fd)
+               ctf_integer(int, event_value, val)
+               ctf_integer_hex(intptr_t, argument_ptr, arg)
+               ctf_integer(long, timer, time)
+       )
+)
+
+#define THREAD_OPERATION_TRACEPOINT_INSTANCE(name)                             \
+       TRACEPOINT_EVENT_INSTANCE(frr_libfrr, thread_operation, name,          \
+                                 THREAD_SCHEDULE_ARGS)                        \
+       TRACEPOINT_LOGLEVEL(frr_libfrr, name, TRACE_INFO)
+
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_timer)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_event)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_read)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(schedule_write)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_cancel_async)
+THREAD_OPERATION_TRACEPOINT_INSTANCE(thread_call)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       frr_pthread_run,
+       TP_ARGS(
+               char *, name
+       ),
+       TP_FIELDS(
+               ctf_string(frr_pthread_name, name)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       frr_pthread_stop,
+       TP_ARGS(
+               char *, name
+       ),
+       TP_FIELDS(
+               ctf_string(frr_pthread_name, name)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       memalloc,
+       TP_ARGS(
+               struct memtype *, mt, void *, ptr, size_t, size
+       ),
+       TP_FIELDS(
+               ctf_string(memtype, mt->name)
+               ctf_integer(size_t, size, size)
+               ctf_integer_hex(intptr_t, ptr, ptr)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       memfree,
+       TP_ARGS(
+               struct memtype *, mt, void *, ptr
+       ),
+       TP_FIELDS(
+               ctf_string(memtype, mt->name)
+               ctf_integer_hex(intptr_t, ptr, ptr)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       list_add,
+       TP_ARGS(
+               struct list *, list, const void *, ptr
+       ),
+       TP_FIELDS(
+               ctf_integer_hex(intptr_t, list, list)
+               ctf_integer(unsigned int, count, list->count)
+               ctf_integer_hex(intptr_t, ptr, ptr)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       list_remove,
+       TP_ARGS(
+               struct list *, list, const void *, ptr
+       ),
+       TP_FIELDS(
+               ctf_integer_hex(intptr_t, list, list)
+               ctf_integer(unsigned int, count, list->count)
+               ctf_integer_hex(intptr_t, ptr, ptr)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       list_delete_node,
+       TP_ARGS(
+               struct list *, list, const void *, node
+       ),
+       TP_FIELDS(
+               ctf_integer_hex(intptr_t, list, list)
+               ctf_integer(unsigned int, count, list->count)
+               ctf_integer_hex(intptr_t, node, node)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       list_sort,
+       TP_ARGS(
+               struct list *, list
+       ),
+       TP_FIELDS(
+               ctf_integer_hex(intptr_t, list, list)
+               ctf_integer(unsigned int, count, list->count)
+       )
+)
+
+TRACEPOINT_EVENT(
+       frr_libfrr,
+       route_node_get,
+       TP_ARGS(
+               struct route_table *, table, char *, prefix
+       ),
+       TP_FIELDS(
+               ctf_integer_hex(intptr_t, table, table)
+               ctf_string(prefix, prefix)
+       )
+)
+
+/* clang-format on */
+
+#include <lttng/tracepoint-event.h>
+#include <lttng/tracelog.h>
+
+#endif /* HAVE_LTTNG */
+
+#endif /* _LIBFRR_TRACE_H_ */
index 84dc6e1419705f3d3a5666c27fc9520f2b56852b..43c2002231d6b7c58c608eadfc04ea5419838be8 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "linklist.h"
 #include "memory.h"
+#include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, LINK_LIST, "Link List")
 DEFINE_MTYPE_STATIC(LIB, LINK_NODE, "Link Node")
@@ -66,6 +67,8 @@ static void listnode_free(struct list *list, struct listnode *node)
 
 struct listnode *listnode_add(struct list *list, void *val)
 {
+       frrtrace(2, frr_libfrr, list_add, list, val);
+
        struct listnode *node;
 
        assert(val != NULL);
@@ -281,6 +284,8 @@ void listnode_move_to_tail(struct list *l, struct listnode *n)
 
 void listnode_delete(struct list *list, const void *val)
 {
+       frrtrace(2, frr_libfrr, list_remove, list, val);
+
        struct listnode *node = listnode_lookup(list, val);
 
        if (node)
@@ -360,6 +365,8 @@ struct listnode *listnode_lookup_nocheck(struct list *list, void *data)
 
 void list_delete_node(struct list *list, struct listnode *node)
 {
+       frrtrace(2, frr_libfrr, list_delete_node, list, node);
+
        if (node->prev)
                node->prev->next = node->next;
        else
@@ -374,6 +381,8 @@ void list_delete_node(struct list *list, struct listnode *node)
 
 void list_sort(struct list *list, int (*cmp)(const void **, const void **))
 {
+       frrtrace(1, frr_libfrr, list_sort, list);
+
        struct listnode *ln, *nn;
        int i = -1;
        void *data;
index 2c902d123b5826bffe85701047e435eec77195db..f715044ea302c2ef6766be310518c4072830d4e2 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "memory.h"
 #include "log.h"
+#include "libfrr_trace.h"
 
 static struct memgroup *mg_first = NULL;
 struct memgroup **mg_insert = &mg_first;
@@ -77,6 +78,8 @@ static inline void mt_count_alloc(struct memtype *mt, size_t size, void *ptr)
 
 static inline void mt_count_free(struct memtype *mt, void *ptr)
 {
+       frrtrace(2, frr_libfrr, memfree, mt, ptr);
+
        assert(mt->n_alloc);
        atomic_fetch_sub_explicit(&mt->n_alloc, 1, memory_order_relaxed);
 
@@ -89,6 +92,8 @@ static inline void mt_count_free(struct memtype *mt, void *ptr)
 
 static inline void *mt_checkalloc(struct memtype *mt, void *ptr, size_t size)
 {
+       frrtrace(3, frr_libfrr, memalloc, mt, ptr, size);
+
        if (__builtin_expect(ptr == NULL, 0)) {
                if (size) {
                        /* malloc(0) is allowed to return NULL */
index 0ea72d03e16a857e2c8f0c32bb2ff4c4860ad92b..b2fa9456909fe802834a5d1c225bf1ce3385aa33 100644 (file)
@@ -202,43 +202,6 @@ int nexthop_cmp(const struct nexthop *next1, const struct nexthop *next2)
        return ret;
 }
 
-bool nexthop_same_firsthop(const struct nexthop *next1,
-                          const struct nexthop *next2)
-{
-       /* Map the TYPE_IPx types to TYPE_IPx_IFINDEX */
-       int type1 = NEXTHOP_FIRSTHOPTYPE(next1->type);
-       int type2 = NEXTHOP_FIRSTHOPTYPE(next2->type);
-
-       if (type1 != type2)
-               return false;
-
-       if (next1->vrf_id != next2->vrf_id)
-               return false;
-
-       switch (type1) {
-       case NEXTHOP_TYPE_IPV4_IFINDEX:
-               if (!IPV4_ADDR_SAME(&next1->gate.ipv4, &next2->gate.ipv4))
-                       return false;
-               if (next1->ifindex != next2->ifindex)
-                       return false;
-               break;
-       case NEXTHOP_TYPE_IFINDEX:
-               if (next1->ifindex != next2->ifindex)
-                       return false;
-               break;
-       case NEXTHOP_TYPE_IPV6_IFINDEX:
-               if (!IPV6_ADDR_SAME(&next1->gate.ipv6, &next2->gate.ipv6))
-                       return false;
-               if (next1->ifindex != next2->ifindex)
-                       return false;
-               break;
-       default:
-               /* do nothing */
-               break;
-       }
-       return true;
-}
-
 /*
  * nexthop_type_to_str
  */
@@ -468,13 +431,13 @@ const char *nexthop2str(const struct nexthop *nexthop, char *str, int size)
                break;
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               snprintf(str, size, "%s if %u", inet_ntoa(nexthop->gate.ipv4),
-                        nexthop->ifindex);
+               snprintfrr(str, size, "%pI4 if %u", &nexthop->gate.ipv4,
+                          nexthop->ifindex);
                break;
        case NEXTHOP_TYPE_IPV6:
        case NEXTHOP_TYPE_IPV6_IFINDEX:
-               snprintf(str, size, "%s if %u", inet6_ntoa(nexthop->gate.ipv6),
-                        nexthop->ifindex);
+               snprintfrr(str, size, "%pI6 if %u", &nexthop->gate.ipv6,
+                          nexthop->ifindex);
                break;
        case NEXTHOP_TYPE_BLACKHOLE:
                snprintf(str, size, "blackhole");
index cadcea1f41a97508c675926b14f52aedd0e122e7..f1ad195cf4cfbe67b9efe5553d2aa1fe500cab3b 100644 (file)
@@ -55,12 +55,6 @@ enum blackhole_type {
        BLACKHOLE_ADMINPROHIB,
 };
 
-/* IPV[46] -> IPV[46]_IFINDEX */
-#define NEXTHOP_FIRSTHOPTYPE(type)                                             \
-       ((type) == NEXTHOP_TYPE_IFINDEX || (type) == NEXTHOP_TYPE_BLACKHOLE)   \
-               ? (type)                                                       \
-               : ((type) | 1)
-
 enum nh_encap_type {
        NET_VXLAN = 100, /* value copied from FPM_NH_ENCAP_VXLAN. */
 };
@@ -216,8 +210,6 @@ extern int nexthop_g_addr_cmp(enum nexthop_types_t type,
 extern const char *nexthop_type_to_str(enum nexthop_types_t nh_type);
 extern bool nexthop_labels_match(const struct nexthop *nh1,
                                 const struct nexthop *nh2);
-extern bool nexthop_same_firsthop(const struct nexthop *next1,
-                                 const struct nexthop *next2);
 
 extern const char *nexthop2str(const struct nexthop *nexthop,
                               char *str, int size);
index 83905abe4363c37d544245323408cbc4eac8d5db..dee98ad8d73ab7ee06b25e50483102ad01ef70e6 100644 (file)
@@ -481,7 +481,7 @@ void nexthop_group_mark_duplicates(struct nexthop_group *nhg)
                for (ALL_NEXTHOPS_PTR(nhg, prev)) {
                        if (prev == nexthop)
                                break;
-                       if (nexthop_same_firsthop(nexthop, prev)) {
+                       if (nexthop_same(nexthop, prev)) {
                                SET_FLAG(nexthop->flags,
                                         NEXTHOP_FLAG_DUPLICATE);
                                break;
@@ -975,7 +975,6 @@ void nexthop_group_write_nexthop_simple(struct vty *vty,
                                        const struct nexthop *nh,
                                        char *altifname)
 {
-       char buf[100];
        char *ifname;
 
        vty_out(vty, "nexthop ");
@@ -990,19 +989,16 @@ void nexthop_group_write_nexthop_simple(struct vty *vty,
                vty_out(vty, "%s", ifname);
                break;
        case NEXTHOP_TYPE_IPV4:
-               vty_out(vty, "%s", inet_ntoa(nh->gate.ipv4));
+               vty_out(vty, "%pI4", &nh->gate.ipv4);
                break;
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               vty_out(vty, "%s %s", inet_ntoa(nh->gate.ipv4), ifname);
+               vty_out(vty, "%pI4 %s", &nh->gate.ipv4, ifname);
                break;
        case NEXTHOP_TYPE_IPV6:
-               vty_out(vty, "%s",
-                       inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)));
+               vty_out(vty, "%pI6", &nh->gate.ipv6);
                break;
        case NEXTHOP_TYPE_IPV6_IFINDEX:
-               vty_out(vty, "%s %s",
-                       inet_ntop(AF_INET6, &nh->gate.ipv6, buf, sizeof(buf)),
-                       ifname);
+               vty_out(vty, "%pI6 %s", &nh->gate.ipv6, ifname);
                break;
        case NEXTHOP_TYPE_BLACKHOLE:
                break;
@@ -1056,10 +1052,14 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh)
                                       ifindex2ifname(nh->ifindex, nh->vrf_id));
                break;
        case NEXTHOP_TYPE_IPV4:
-               json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4));
+               json_object_string_add(
+                       j, "nexthop",
+                       inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf)));
                break;
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               json_object_string_add(j, "nexthop", inet_ntoa(nh->gate.ipv4));
+               json_object_string_add(
+                       j, "nexthop",
+                       inet_ntop(AF_INET, &nh->gate.ipv4, buf, sizeof(buf)));
                json_object_string_add(j, "vrfId",
                                       ifindex2ifname(nh->ifindex, nh->vrf_id));
                break;
index 5816c162d8d7072f749ca106400e186d5cc7ab1f..ecfa2c9d11c0bd66f294b0dae3d7a26ca1d51dc4 100644 (file)
@@ -152,20 +152,22 @@ static int nb_node_del_cb(const struct lys_node *snode, void *arg)
        struct nb_node *nb_node;
 
        nb_node = snode->priv;
-       lys_set_private(snode, NULL);
-       XFREE(MTYPE_NB_NODE, nb_node);
+       if (nb_node) {
+               lys_set_private(snode, NULL);
+               XFREE(MTYPE_NB_NODE, nb_node);
+       }
 
        return YANG_ITER_CONTINUE;
 }
 
 void nb_nodes_create(void)
 {
-       yang_snodes_iterate_all(nb_node_new_cb, 0, NULL);
+       yang_snodes_iterate(NULL, nb_node_new_cb, 0, NULL);
 }
 
 void nb_nodes_delete(void)
 {
-       yang_snodes_iterate_all(nb_node_del_cb, 0, NULL);
+       yang_snodes_iterate(NULL, nb_node_del_cb, 0, NULL);
 }
 
 struct nb_node *nb_node_find(const char *xpath)
@@ -273,8 +275,10 @@ static int nb_node_validate(const struct lys_node *snode, void *arg)
        unsigned int *errors = arg;
 
        /* Validate callbacks and priority. */
-       *errors += nb_node_validate_cbs(nb_node);
-       *errors += nb_node_validate_priority(nb_node);
+       if (nb_node) {
+               *errors += nb_node_validate_cbs(nb_node);
+               *errors += nb_node_validate_priority(nb_node);
+       }
 
        return YANG_ITER_CONTINUE;
 }
@@ -1142,7 +1146,8 @@ const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
 }
 
 int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
-                   const struct list *input, struct list *output)
+                   const struct list *input, struct list *output, char *errmsg,
+                   size_t errmsg_len)
 {
        struct nb_cb_rpc_args args = {};
 
@@ -1151,6 +1156,8 @@ int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
        args.xpath = xpath;
        args.input = input;
        args.output = output;
+       args.errmsg = errmsg;
+       args.errmsg_len = errmsg_len;
        return nb_node->cbs.rpc(&args);
 }
 
@@ -2229,25 +2236,11 @@ static void nb_load_callbacks(const struct frr_yang_module_info *module)
        }
 }
 
-void nb_init(struct thread_master *tm,
-            const struct frr_yang_module_info *const modules[],
-            size_t nmodules, bool db_enabled)
+void nb_validate_callbacks(void)
 {
        unsigned int errors = 0;
 
-       /* Load YANG modules. */
-       for (size_t i = 0; i < nmodules; i++)
-               yang_module_load(modules[i]->name);
-
-       /* Create a nb_node for all YANG schema nodes. */
-       nb_nodes_create();
-
-       /* Load northbound callbacks. */
-       for (size_t i = 0; i < nmodules; i++)
-               nb_load_callbacks(modules[i]);
-
-       /* Validate northbound callbacks. */
-       yang_snodes_iterate_all(nb_node_validate, 0, &errors);
+       yang_snodes_iterate(NULL, nb_node_validate, 0, &errors);
        if (errors > 0) {
                flog_err(
                        EC_LIB_NB_CBS_VALIDATION,
@@ -2255,9 +2248,33 @@ void nb_init(struct thread_master *tm,
                        __func__, errors);
                exit(1);
        }
+}
 
+void nb_load_module(const struct frr_yang_module_info *module_info)
+{
+       struct yang_module *module;
+
+       DEBUGD(&nb_dbg_events, "northbound: loading %s.yang",
+              module_info->name);
+
+       module = yang_module_load(module_info->name);
+       yang_snodes_iterate(module->info, nb_node_new_cb, 0, NULL);
+       nb_load_callbacks(module_info);
+}
+
+void nb_init(struct thread_master *tm,
+            const struct frr_yang_module_info *const modules[],
+            size_t nmodules, bool db_enabled)
+{
        nb_db_enabled = db_enabled;
 
+       /* Load YANG modules and their corresponding northbound callbacks. */
+       for (size_t i = 0; i < nmodules; i++)
+               nb_load_module(modules[i]);
+
+       /* Validate northbound callbacks. */
+       nb_validate_callbacks();
+
        /* Create an empty running configuration. */
        running_config = nb_config_new(NULL);
        running_config_entries = hash_create(running_config_entry_key_make,
index 7b481273cb94345cdc5eb2c96065a42aa8490a0d..3f6e4dc46e5a7af494d904bcee60a5181994c91e 100644 (file)
@@ -258,6 +258,12 @@ struct nb_cb_rpc_args {
 
        /* List of output parameters to be populated by the callback. */
        struct list *output;
+
+       /* Buffer to store human-readable error message in case of error. */
+       char *errmsg;
+
+       /* Size of errmsg. */
+       size_t errmsg_len;
 };
 
 /*
@@ -546,7 +552,7 @@ struct nb_node {
  * from working properly on shared libraries. For those compilers, use a fixed
  * size array to work around the problem.
  */
-#define YANG_MODULE_MAX_NODES 1024
+#define YANG_MODULE_MAX_NODES 1400
 
 struct frr_yang_module_info {
        /* YANG module name. */
@@ -689,7 +695,8 @@ extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
                                            const void *parent_list_entry,
                                            const struct yang_list_keys *keys);
 extern int nb_callback_rpc(const struct nb_node *nb_node, const char *xpath,
-                          const struct list *input, struct list *output);
+                          const struct list *input, struct list *output,
+                          char *errmsg, size_t errmsg_len);
 
 /*
  * Create a northbound node for all YANG schema nodes.
@@ -1230,6 +1237,29 @@ extern const char *nb_err_name(enum nb_error error);
  */
 extern const char *nb_client_name(enum nb_client client);
 
+/*
+ * Validate all northbound callbacks.
+ *
+ * Some errors, like missing callbacks or invalid priorities, are fatal and
+ * can't be recovered from. Other errors, like unneeded callbacks, are logged
+ * but otherwise ignored.
+ *
+ * Whenever a YANG module is loaded after startup, *all* northbound callbacks
+ * need to be validated and not only the callbacks from the newly loaded module.
+ * This is because augmentations can change the properties of the augmented
+ * module, making mandatory the implementation of additional callbacks.
+ */
+void nb_validate_callbacks(void);
+
+/*
+ * Load a YANG module with its corresponding northbound callbacks.
+ *
+ * module_info
+ *    Pointer to structure containing the module name and its northbound
+ *    callbacks.
+ */
+void nb_load_module(const struct frr_yang_module_info *module_info);
+
 /*
  * Initialize the northbound layer. Should be called only once during the
  * daemon initialization process.
index 6ce520149ab058756860d6274b91ac5d4ee1a9f4..7048df99fba4b09470620fb454f32ce225169c36 100644 (file)
@@ -89,7 +89,7 @@ static int nb_cli_classic_commit(struct vty *vty)
 
 static void nb_cli_pending_commit_clear(struct vty *vty)
 {
-       THREAD_TIMER_OFF(vty->t_pending_commit);
+       THREAD_OFF(vty->t_pending_commit);
        vty->backoff_cmd_count = 0;
        XFREE(MTYPE_TMP, vty->pending_cmds_buf);
        vty->pending_cmds_buflen = 0;
@@ -154,7 +154,7 @@ static int nb_cli_schedule_command(struct vty *vty)
                                           vty->pending_cmds_buflen);
 
        /* Schedule the commit operation. */
-       THREAD_TIMER_OFF(vty->t_pending_commit);
+       THREAD_OFF(vty->t_pending_commit);
        thread_add_timer_msec(master, nb_cli_pending_commit_cb, vty, 100,
                              &vty->t_pending_commit);
 
@@ -284,10 +284,12 @@ int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt, ...)
        return CMD_SUCCESS;
 }
 
-int nb_cli_rpc(const char *xpath, struct list *input, struct list *output)
+int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input,
+              struct list *output)
 {
        struct nb_node *nb_node;
        int ret;
+       char errmsg[BUFSIZ] = {0};
 
        nb_node = nb_node_find(xpath);
        if (!nb_node) {
@@ -296,18 +298,21 @@ int nb_cli_rpc(const char *xpath, struct list *input, struct list *output)
                return CMD_WARNING;
        }
 
-       ret = nb_callback_rpc(nb_node, xpath, input, output);
+       ret = nb_callback_rpc(nb_node, xpath, input, output, errmsg,
+                             sizeof(errmsg));
        switch (ret) {
        case NB_OK:
                return CMD_SUCCESS;
        default:
+               if (strlen(errmsg))
+                       vty_show_nb_errors(vty, ret, errmsg);
                return CMD_WARNING;
        }
 }
 
 void nb_cli_confirmed_commit_clean(struct vty *vty)
 {
-       THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout);
+       thread_cancel(&vty->t_confirmed_commit_timeout);
        nb_config_free(vty->confirmed_commit_rollback);
        vty->confirmed_commit_rollback = NULL;
 }
@@ -372,7 +377,7 @@ static int nb_cli_commit(struct vty *vty, bool force,
                                "%% Resetting confirmed-commit timeout to %u minute(s)\n\n",
                                confirmed_timeout);
 
-                       THREAD_TIMER_OFF(vty->t_confirmed_commit_timeout);
+                       thread_cancel(&vty->t_confirmed_commit_timeout);
                        thread_add_timer(master,
                                         nb_cli_confirmed_commit_timeout, vty,
                                         confirmed_timeout * 60,
index 112d62efda7d670b778138b51e1ecede18d8dc13..2290a76b8d41402b11388bd8b066fafaba7c6fd3 100644 (file)
@@ -75,6 +75,9 @@ extern int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt,
 /*
  * Execute a YANG RPC or Action.
  *
+ * vty
+ *    The vty terminal to dump any error.
+ *
  * xpath
  *    XPath of the YANG RPC or Action node.
  *
@@ -90,7 +93,7 @@ extern int nb_cli_apply_changes(struct vty *vty, const char *xpath_base_fmt,
  * Returns:
  *    CMD_SUCCESS on success, CMD_WARNING otherwise.
  */
-extern int nb_cli_rpc(const char *xpath, struct list *input,
+extern int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input,
                      struct list *output);
 
 /*
index 1f480f3d02e4f94de6d7b93f13b08be64ed02225..8acba9fd2bef01c1c78b3962fc40b3f74d5991c1 100644 (file)
@@ -550,6 +550,9 @@ static int frr_confd_init_cdb(void)
                                continue;
 
                        nb_node = snode->priv;
+                       if (!nb_node)
+                               continue;
+
                        DEBUGD(&nb_dbg_client_confd, "%s: subscribing to '%s'",
                               __func__, nb_node->xpath);
 
@@ -1068,6 +1071,7 @@ static int frr_confd_action_execute(struct confd_user_info *uinfo,
        struct yang_data *data;
        confd_tag_value_t *reply;
        int ret = CONFD_OK;
+       char errmsg[BUFSIZ] = {0};
 
        /* Getting the XPath is tricky. */
        if (kp) {
@@ -1115,7 +1119,9 @@ static int frr_confd_action_execute(struct confd_user_info *uinfo,
        }
 
        /* Execute callback registered for this XPath. */
-       if (nb_callback_rpc(nb_node, xpath, input, output) != NB_OK) {
+       if (nb_callback_rpc(nb_node, xpath, input, output, errmsg,
+                           sizeof(errmsg))
+           != NB_OK) {
                flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s",
                          __func__, xpath);
                ret = CONFD_ERR;
@@ -1186,7 +1192,7 @@ static int frr_confd_subscribe_state(const struct lys_node *snode, void *arg)
        struct nb_node *nb_node = snode->priv;
        struct confd_data_cbs *data_cbs = arg;
 
-       if (!CHECK_FLAG(snode->flags, LYS_CONFIG_R))
+       if (!nb_node || !CHECK_FLAG(snode->flags, LYS_CONFIG_R))
                return YANG_ITER_CONTINUE;
        /* We only need to subscribe to the root of the state subtrees. */
        if (snode->parent && CHECK_FLAG(snode->parent->flags, LYS_CONFIG_R))
@@ -1273,7 +1279,7 @@ static int frr_confd_init_dp(const char *program_name)
         * Iterate over all loaded YANG modules and subscribe to the paths
         * referent to state data.
         */
-       yang_snodes_iterate_all(frr_confd_subscribe_state, 0, &data_cbs);
+       yang_snodes_iterate(NULL, frr_confd_subscribe_state, 0, &data_cbs);
 
        /* Register notification stream. */
        memset(&ncbs, 0, sizeof(ncbs));
@@ -1390,7 +1396,8 @@ static int frr_confd_calculate_snode_hash(const struct lys_node *snode,
 {
        struct nb_node *nb_node = snode->priv;
 
-       nb_node->confd_hash = confd_str2hash(snode->name);
+       if (nb_node)
+               nb_node->confd_hash = confd_str2hash(snode->name);
 
        return YANG_ITER_CONTINUE;
 }
@@ -1423,7 +1430,7 @@ static int frr_confd_init(const char *program_name)
                goto error;
        }
 
-       yang_snodes_iterate_all(frr_confd_calculate_snode_hash, 0, NULL);
+       yang_snodes_iterate(NULL, frr_confd_calculate_snode_hash, 0, NULL);
 
        hook_register(nb_notification_send, frr_confd_notification_send);
 
index f35b4bb31b2d6b469610dd4ce106b915e62c9d25..abdae993b10fe55ededc88f323a62a32e7f237ff 100644 (file)
@@ -962,6 +962,7 @@ class NorthboundImpl
                struct listnode *node;
                struct yang_data *data;
                const char *xpath;
+               char errmsg[BUFSIZ] = {0};
 
                switch (tag->state) {
                case CREATE:
@@ -1012,7 +1013,7 @@ class NorthboundImpl
 
                        // Execute callback registered for this XPath.
                        if (nb_callback_rpc(nb_node, xpath, input_list,
-                                           output_list)
+                                           output_list, errmsg, sizeof(errmsg))
                            != NB_OK) {
                                flog_warn(EC_LIB_NB_CB_RPC,
                                          "%s: rpc callback failed: %s",
index b5ef040a3fe2cf4d5d3bf4b738f2ddfeccd046e3..c027f4de726f6677fce214f267922737a70debcb 100644 (file)
@@ -414,6 +414,7 @@ static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, const char *xpath,
        struct yang_data *data;
        size_t cb_output_cnt;
        int ret = SR_ERR_OK;
+       char errmsg[BUFSIZ] = {0};
 
        nb_node = nb_node_find(xpath);
        if (!nb_node) {
@@ -436,7 +437,9 @@ static int frr_sr_config_rpc_cb(sr_session_ctx_t *session, const char *xpath,
        }
 
        /* Execute callback registered for this XPath. */
-       if (nb_callback_rpc(nb_node, xpath, input, output) != NB_OK) {
+       if (nb_callback_rpc(nb_node, xpath, input, output, errmsg,
+                           sizeof(errmsg))
+           != NB_OK) {
                flog_warn(EC_LIB_NB_CB_RPC, "%s: rpc callback failed: %s",
                          __func__, xpath);
                ret = SR_ERR_OPERATION_FAILED;
@@ -572,6 +575,8 @@ static int frr_sr_subscribe_state(const struct lys_node *snode, void *arg)
                return YANG_ITER_CONTINUE;
 
        nb_node = snode->priv;
+       if (!nb_node)
+               return YANG_ITER_CONTINUE;
 
        DEBUGD(&nb_dbg_client_sysrepo, "sysrepo: providing data to '%s'",
               nb_node->xpath);
@@ -596,6 +601,8 @@ static int frr_sr_subscribe_rpc(const struct lys_node *snode, void *arg)
                return YANG_ITER_CONTINUE;
 
        nb_node = snode->priv;
+       if (!nb_node)
+               return YANG_ITER_CONTINUE;
 
        DEBUGD(&nb_dbg_client_sysrepo, "sysrepo: providing RPC to '%s'",
               nb_node->xpath);
@@ -683,10 +690,10 @@ static int frr_sr_init(void)
                int event_pipe;
 
                frr_sr_subscribe_config(module);
-               yang_snodes_iterate_module(module->info, frr_sr_subscribe_state,
-                                          0, module);
-               yang_snodes_iterate_module(module->info, frr_sr_subscribe_rpc,
-                                          0, module);
+               yang_snodes_iterate(module->info, frr_sr_subscribe_state, 0,
+                                   module);
+               yang_snodes_iterate(module->info, frr_sr_subscribe_rpc, 0,
+                                   module);
 
                /* Watch subscriptions. */
                ret = sr_get_event_pipe(module->sr_subscription, &event_pipe);
index 981e86e2acb787209579a28d36f95ff1e98bda01..4588dfe1d36d4a30b3de06d0e31010bf14f0eeb6 100644 (file)
@@ -901,14 +901,11 @@ static void __attribute__((unused)) prefix_list_print(struct prefix_list *plist)
                        printf("any %s\n", prefix_list_type_str(pentry));
                else {
                        struct prefix *p;
-                       char buf[BUFSIZ];
 
                        p = &pentry->prefix;
 
-                       printf("  seq %lld %s %s/%d", (long long)pentry->seq,
-                              prefix_list_type_str(pentry),
-                              inet_ntop(p->family, p->u.val, buf, BUFSIZ),
-                              p->prefixlen);
+                       printf("  seq %lld %s %pFX", (long long)pentry->seq,
+                              prefix_list_type_str(pentry), p);
                        if (pentry->ge)
                                printf(" ge %d", pentry->ge);
                        if (pentry->le)
@@ -1014,12 +1011,8 @@ static void vty_show_prefix_entry(struct vty *vty, afi_t afi,
                                vty_out(vty, "any");
                        else {
                                struct prefix *p = &pentry->prefix;
-                               char buf[BUFSIZ];
 
-                               vty_out(vty, "%s/%d",
-                                       inet_ntop(p->family, p->u.val, buf,
-                                                 BUFSIZ),
-                                       p->prefixlen);
+                               vty_out(vty, "%pFX", p);
 
                                if (pentry->ge)
                                        vty_out(vty, " ge %d", pentry->ge);
@@ -1121,12 +1114,8 @@ static int vty_show_prefix_list_prefix(struct vty *vty, afi_t afi,
                                vty_out(vty, "any");
                        else {
                                struct prefix *pf = &pentry->prefix;
-                               char buf[BUFSIZ];
 
-                               vty_out(vty, "%s/%d",
-                                       inet_ntop(pf->family, pf->u.val, buf,
-                                                 BUFSIZ),
-                                       pf->prefixlen);
+                               vty_out(vty, "%pFX", pf);
 
                                if (pentry->ge)
                                        vty_out(vty, " ge %d", pentry->ge);
@@ -1491,11 +1480,8 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
                for (pentry = plist->head; pentry; pentry = pentry->next) {
                        struct prefix *p = &pentry->prefix;
                        char buf_a[BUFSIZ];
-                       char buf_b[BUFSIZ];
 
-                       snprintf(buf_a, sizeof(buf_a), "%s/%d",
-                                inet_ntop(p->family, p->u.val, buf_b, BUFSIZ),
-                                p->prefixlen);
+                       snprintf(buf_a, sizeof(buf_a), "%pFX", p);
 
                        json_object_int_add(json_list, "seq", pentry->seq);
                        json_object_string_add(json_list, "seqPrefixListType",
@@ -1526,13 +1512,9 @@ int prefix_bgp_show_prefix_list(struct vty *vty, afi_t afi, char *name,
 
                for (pentry = plist->head; pentry; pentry = pentry->next) {
                        struct prefix *p = &pentry->prefix;
-                       char buf[BUFSIZ];
 
-                       vty_out(vty, "   seq %" PRId64 " %s %s/%d",
-                               pentry->seq,
-                               prefix_list_type_str(pentry),
-                               inet_ntop(p->family, p->u.val, buf, BUFSIZ),
-                               p->prefixlen);
+                       vty_out(vty, "   seq %" PRId64 " %s %pFX", pentry->seq,
+                               prefix_list_type_str(pentry), p);
 
                        if (pentry->ge)
                                vty_out(vty, " ge %d", pentry->ge);
index 0a88f9eca6892590bf330b2aceeb505e47113f59..663a87afde26c1c7cb2e64de6477cb24f94fa662 100644 (file)
@@ -30,6 +30,7 @@
 #include "jhash.h"
 #include "lib_errors.h"
 #include "printfrr.h"
+#include "vxlan.h"
 
 DEFINE_MTYPE_STATIC(LIB, PREFIX, "Prefix")
 DEFINE_MTYPE_STATIC(LIB, PREFIX_FLOWSPEC, "Prefix Flowspec")
@@ -909,7 +910,17 @@ int str2prefix(const char *str, struct prefix *p)
 static const char *prefixevpn_ead2str(const struct prefix_evpn *p, char *str,
                                      int size)
 {
-       snprintf(str, size, "Unsupported EVPN prefix");
+       uint8_t family;
+       char buf[ESI_STR_LEN];
+       char buf1[INET6_ADDRSTRLEN];
+
+       family = IS_IPADDR_V4(&p->prefix.ead_addr.ip) ? AF_INET : AF_INET6;
+       snprintf(str, size, "[%d]:[%u]:[%s]:[%d]:[%s]", p->prefix.route_type,
+                p->prefix.ead_addr.eth_tag,
+                esi_to_str(&p->prefix.ead_addr.esi, buf, sizeof(buf)),
+                (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
+                inet_ntop(family, &p->prefix.ead_addr.ip.ipaddr_v4, buf1,
+                          sizeof(buf1)));
        return str;
 }
 
@@ -917,27 +928,24 @@ static const char *prefixevpn_macip2str(const struct prefix_evpn *p, char *str,
                                        int size)
 {
        uint8_t family;
-       char buf[PREFIX2STR_BUFFER];
-       char buf2[ETHER_ADDR_STRLEN];
+       char buf1[ETHER_ADDR_STRLEN];
+       char buf2[PREFIX2STR_BUFFER];
 
        if (is_evpn_prefix_ipaddr_none(p))
-               snprintf(str, size, "[%d]:[%s]/%d",
-                        p->prefix.route_type,
-                        prefix_mac2str(&p->prefix.macip_addr.mac,
-                                       buf2, sizeof(buf2)),
-                        p->prefixlen);
+               snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
+                        p->prefix.macip_addr.eth_tag, 8 * ETH_ALEN,
+                        prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
+                                       sizeof(buf1)));
        else {
-               family = is_evpn_prefix_ipaddr_v4(p)
-                                ? AF_INET
-                                : AF_INET6;
-               snprintf(str, size, "[%d]:[%s]:[%s]/%d",
-                        p->prefix.route_type,
-                        prefix_mac2str(&p->prefix.macip_addr.mac,
-                                       buf2, sizeof(buf2)),
-                        inet_ntop(family,
-                                  &p->prefix.macip_addr.ip.ip.addr,
-                                  buf, PREFIX2STR_BUFFER),
-                        p->prefixlen);
+               family = is_evpn_prefix_ipaddr_v4(p) ? AF_INET : AF_INET6;
+               snprintf(str, size, "[%d]:[%d]:[%d]:[%s]:[%d]:[%s]",
+                        p->prefix.route_type, p->prefix.macip_addr.eth_tag,
+                        8 * ETH_ALEN,
+                        prefix_mac2str(&p->prefix.macip_addr.mac, buf1,
+                                       sizeof(buf1)),
+                        family == AF_INET ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
+                        inet_ntop(family, &p->prefix.macip_addr.ip.ip.addr,
+                                  buf2, PREFIX2STR_BUFFER));
        }
        return str;
 }
@@ -946,28 +954,32 @@ static const char *prefixevpn_imet2str(const struct prefix_evpn *p, char *str,
                                       int size)
 {
        uint8_t family;
-       char buf[PREFIX2STR_BUFFER];
+       char buf[INET6_ADDRSTRLEN];
+
+       family = IS_IPADDR_V4(&p->prefix.imet_addr.ip) ? AF_INET : AF_INET6;
+       snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
+                p->prefix.imet_addr.eth_tag,
+                (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
+                inet_ntop(family, &p->prefix.imet_addr.ip.ipaddr_v4, buf,
+                          sizeof(buf)));
 
-       family = is_evpn_prefix_ipaddr_v4(p)
-                        ? AF_INET
-                        : AF_INET6;
-       snprintf(str, size, "[%d]:[%s]/%d", p->prefix.route_type,
-                inet_ntop(family,
-                          &p->prefix.imet_addr.ip.ip.addr, buf,
-                          PREFIX2STR_BUFFER),
-                p->prefixlen);
        return str;
 }
 
 static const char *prefixevpn_es2str(const struct prefix_evpn *p, char *str,
                                     int size)
 {
+       uint8_t family;
        char buf[ESI_STR_LEN];
+       char buf1[INET6_ADDRSTRLEN];
 
-       snprintf(str, size, "[%d]:[%s]:[%s]/%d", p->prefix.route_type,
+       family = IS_IPADDR_V4(&p->prefix.es_addr.ip) ? AF_INET : AF_INET6;
+       snprintf(str, size, "[%d]:[%s]:[%d]:[%s]", p->prefix.route_type,
                 esi_to_str(&p->prefix.es_addr.esi, buf, sizeof(buf)),
-                inet_ntoa(p->prefix.es_addr.ip.ipaddr_v4),
-                p->prefixlen);
+                (family == AF_INET) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN,
+                inet_ntop(family, &p->prefix.es_addr.ip.ipaddr_v4, buf1,
+                          sizeof(buf1)));
+
        return str;
 }
 
@@ -975,19 +987,14 @@ static const char *prefixevpn_prefix2str(const struct prefix_evpn *p, char *str,
                                         int size)
 {
        uint8_t family;
-       char buf[PREFIX2STR_BUFFER];
+       char buf[INET6_ADDRSTRLEN];
 
-       family = is_evpn_prefix_ipaddr_v4(p)
-                        ? AF_INET
-                        : AF_INET6;
-       snprintf(str, size, "[%d]:[%u]:[%s/%d]/%d",
-                p->prefix.route_type,
+       family = IS_IPADDR_V4(&p->prefix.prefix_addr.ip) ? AF_INET : AF_INET6;
+       snprintf(str, size, "[%d]:[%d]:[%d]:[%s]", p->prefix.route_type,
                 p->prefix.prefix_addr.eth_tag,
-                inet_ntop(family,
-                          &p->prefix.prefix_addr.ip.ip.addr, buf,
-                          PREFIX2STR_BUFFER),
                 p->prefix.prefix_addr.ip_prefix_length,
-                p->prefixlen);
+                inet_ntop(family, &p->prefix.prefix_addr.ip.ipaddr_v4, buf,
+                          sizeof(buf)));
        return str;
 }
 
@@ -995,15 +1002,15 @@ static const char *prefixevpn2str(const struct prefix_evpn *p, char *str,
                                  int size)
 {
        switch (p->prefix.route_type) {
-       case 1:
+       case BGP_EVPN_AD_ROUTE:
                return prefixevpn_ead2str(p, str, size);
-       case 2:
+       case BGP_EVPN_MAC_IP_ROUTE:
                return prefixevpn_macip2str(p, str, size);
-       case 3:
+       case BGP_EVPN_IMET_ROUTE:
                return prefixevpn_imet2str(p, str, size);
-       case 4:
+       case BGP_EVPN_ES_ROUTE:
                return prefixevpn_es2str(p, str, size);
-       case 5:
+       case BGP_EVPN_IP_PREFIX_ROUTE:
                return prefixevpn_prefix2str(p, str, size);
        default:
                snprintf(str, size, "Unsupported EVPN prefix");
@@ -1330,6 +1337,29 @@ char *esi_to_str(const esi_t *esi, char *buf, int size)
        return ptr;
 }
 
+char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len)
+{
+       switch (df_alg) {
+       case EVPN_MH_DF_ALG_SERVICE_CARVING:
+               snprintf(buf, buf_len, "service-carving");
+               break;
+
+       case EVPN_MH_DF_ALG_HRW:
+               snprintf(buf, buf_len, "HRW");
+               break;
+
+       case EVPN_MH_DF_ALG_PREF:
+               snprintf(buf, buf_len, "preference");
+               break;
+
+       default:
+               snprintf(buf, buf_len, "unknown %u", df_alg);
+               break;
+       }
+
+       return buf;
+}
+
 printfrr_ext_autoreg_p("EA", printfrr_ea)
 static ssize_t printfrr_ea(char *buf, size_t bsz, const char *fmt,
                           int prec, const void *ptr)
index 471978ed28e61e0303ca33240c9397a2381481ee..d2cabf3104dd712f2f04c6476cdedb322d85d9ea 100644 (file)
@@ -62,6 +62,7 @@ typedef enum {
 #define EVPN_ETH_TAG_BYTES 4
 #define ESI_BYTES 10
 #define ESI_STR_LEN (3 * ESI_BYTES)
+#define EVPN_DF_ALG_STR_LEN 24
 
 /* Maximum number of VTEPs per-ES -
  * XXX - temporary limit for allocating strings etc.
@@ -515,6 +516,7 @@ extern unsigned prefix_hash_key(const void *pp);
 
 extern int str_to_esi(const char *str, esi_t *esi);
 extern char *esi_to_str(const esi_t *esi, char *buf, int size);
+extern char *evpn_es_df_alg2str(uint8_t df_alg, char *buf, int buf_len);
 extern void prefix_evpn_hexdump(const struct prefix_evpn *p);
 
 static inline int ipv6_martian(struct in6_addr *addr)
index fb70860024d0b0af3a1ede3eaf9db392ebc665f1..0eb54a4794cb1c5f6e48f2fa611063b7be7d9050 100644 (file)
@@ -2377,7 +2377,6 @@ route_map_result_t route_map_apply(struct route_map *map,
        route_map_result_t ret = RMAP_PERMITMATCH;
        struct route_map_index *index = NULL;
        struct route_map_rule *set = NULL;
-       char buf[PREFIX_STRLEN];
        bool skip_match_clause = false;
 
        if (recursion > RMAP_RECURSION_LIMIT) {
@@ -2403,16 +2402,14 @@ route_map_result_t route_map_apply(struct route_map *map,
                if (index) {
                        if (rmap_debug)
                                zlog_debug(
-                                       "Best match route-map: %s, sequence: %d for pfx: %s, result: %s",
-                                       map->name, index->pref,
-                                       prefix2str(prefix, buf, sizeof(buf)),
+                                       "Best match route-map: %s, sequence: %d for pfx: %pFX, result: %s",
+                                       map->name, index->pref, prefix,
                                        route_map_cmd_result_str(match_ret));
                } else {
                        if (rmap_debug)
                                zlog_debug(
-                                       "No best match sequence for pfx: %s in route-map: %s, result: %s",
-                                       prefix2str(prefix, buf, sizeof(buf)),
-                                       map->name,
+                                       "No best match sequence for pfx: %pFX in route-map: %s, result: %s",
+                                       prefix, map->name,
                                        route_map_cmd_result_str(match_ret));
                        /*
                         * No index matches this prefix. Return deny unless,
@@ -2437,9 +2434,8 @@ route_map_result_t route_map_apply(struct route_map *map,
                                                          prefix, type, object);
                        if (rmap_debug) {
                                zlog_debug(
-                                       "Route-map: %s, sequence: %d, prefix: %s, result: %s",
-                                       map->name, index->pref,
-                                       prefix2str(prefix, buf, sizeof(buf)),
+                                       "Route-map: %s, sequence: %d, prefix: %pFX, result: %s",
+                                       map->name, index->pref, prefix,
                                        route_map_cmd_result_str(match_ret));
                        }
                } else
@@ -2549,12 +2545,10 @@ route_map_result_t route_map_apply(struct route_map *map,
        }
 
 route_map_apply_end:
-       if (rmap_debug) {
-               zlog_debug("Route-map: %s, prefix: %s, result: %s",
-                          (map ? map->name : "null"),
-                          prefix2str(prefix, buf, sizeof(buf)),
+       if (rmap_debug)
+               zlog_debug("Route-map: %s, prefix: %pFX, result: %s",
+                          (map ? map->name : "null"), prefix,
                           route_map_result_str(ret));
-       }
 
        return (ret);
 }
@@ -3156,8 +3150,6 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
        struct list *rmap_index_list = NULL;
        struct listnode *ln = NULL, *nln = NULL;
        struct route_map_index *index = NULL;
-       struct prefix *p = NULL, *pp = NULL;
-       char buf[SU_ADDRSTRLEN], pbuf[SU_ADDRSTRLEN];
        uint8_t len = 54;
 
        vty_out(vty, "%s:\n", frr_protonameinst);
@@ -3171,22 +3163,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
                                "____________________");
                        for (rn = route_top(rm_pfx_tbl4); rn;
                             rn = route_next(rn)) {
-                               p = &rn->p;
-
-                               vty_out(vty, "    %s/%d (%d)\n",
-                                       inet_ntop(p->family, &p->u.prefix, buf,
-                                                 SU_ADDRSTRLEN),
-                                       p->prefixlen, rn->lock);
+                               vty_out(vty, "    %pRN (%d)\n", rn,
+                                       route_node_get_lock_count(rn));
 
                                vty_out(vty, "(P) ");
                                prn = rn->parent;
                                if (prn) {
-                                       pp = &prn->p;
-                                       vty_out(vty, "%s/%d\n",
-                                               inet_ntop(pp->family,
-                                                         &pp->u.prefix, pbuf,
-                                                         SU_ADDRSTRLEN),
-                                               pp->prefixlen);
+                                       vty_out(vty, "%pRN\n", prn);
                                }
 
                                vty_out(vty, "\n");
@@ -3215,22 +3198,13 @@ DEFUN_HIDDEN(show_route_map_pfx_tbl, show_route_map_pfx_tbl_cmd,
                                "____________________");
                        for (rn = route_top(rm_pfx_tbl6); rn;
                             rn = route_next(rn)) {
-                               p = &rn->p;
-
-                               vty_out(vty, "    %s/%d (%d)\n",
-                                       inet_ntop(p->family, &p->u.prefix, buf,
-                                                 SU_ADDRSTRLEN),
-                                       p->prefixlen, rn->lock);
+                               vty_out(vty, "    %pRN (%d)\n", rn,
+                                       route_node_get_lock_count(rn));
 
                                vty_out(vty, "(P) ");
                                prn = rn->parent;
                                if (prn) {
-                                       pp = &prn->p;
-                                       vty_out(vty, "%s/%d\n",
-                                               inet_ntop(pp->family,
-                                                         &pp->u.prefix, pbuf,
-                                                         SU_ADDRSTRLEN),
-                                               pp->prefixlen);
+                                       vty_out(vty, "%pRN\n", prn);
                                }
 
                                vty_out(vty, "\n");
index 04fcc814ef17f3ad00e6c950207c1ef001f1e0e0..de9e1f54100ad28a57a2ff5dd29aa9d061e9b925 100644 (file)
@@ -63,6 +63,33 @@ static void quagga_signal_handler(int signo)
        sigmaster.caught = 1;
 }
 
+/*
+ * Check whether any signals have been received and are pending. This is done
+ * with the application's key signals blocked. The complete set of signals
+ * is returned in 'setp', so the caller can restore them when appropriate.
+ * If there are pending signals, returns 'true', 'false' otherwise.
+ */
+bool frr_sigevent_check(sigset_t *setp)
+{
+       sigset_t blocked;
+       int i;
+       bool ret;
+
+       sigemptyset(setp);
+       sigemptyset(&blocked);
+
+       /* Set up mask of application's signals */
+       for (i = 0; i < sigmaster.sigc; i++)
+               sigaddset(&blocked, sigmaster.signals[i].signal);
+
+       pthread_sigmask(SIG_BLOCK, &blocked, setp);
+
+       /* Now that the application's signals are blocked, test. */
+       ret = (sigmaster.caught != 0);
+
+       return ret;
+}
+
 /* check if signals have been caught and run appropriate handlers */
 int quagga_sigevent_process(void)
 {
index a0ad88fcaaaa2b10026f19813cbdd42dd3b4b6b3..4a39b22889724d4c50144e684705b6d18ea16d59 100644 (file)
@@ -48,6 +48,15 @@ struct quagga_signal_t {
 extern void signal_init(struct thread_master *m, int sigc,
                        struct quagga_signal_t *signals);
 
+
+/*
+ * Check whether any signals have been received and are pending. This is done
+ * with the application's key signals blocked. The complete set of signals
+ * is returned in 'setp', so the caller can restore them when appropriate.
+ * If there are pending signals, returns 'true', 'false' otherwise.
+ */
+bool frr_sigevent_check(sigset_t *setp);
+
 /* check whether there are signals to handle, process any found */
 extern int quagga_sigevent_process(void);
 
index d77229797c06b356355a2ea60e36524cce0b75b9..c9998456593bcd34b8fee12373c7e333affdbdc5 100644 (file)
@@ -587,15 +587,11 @@ static void __attribute__((unused)) sockunion_print(const union sockunion *su)
 
        switch (su->sa.sa_family) {
        case AF_INET:
-               printf("%s\n", inet_ntoa(su->sin.sin_addr));
+               printf("%pI4\n", &su->sin.sin_addr);
+               break;
+       case AF_INET6:
+               printf("%pI6\n", &su->sin6.sin6_addr);
                break;
-       case AF_INET6: {
-               char buf[SU_ADDRSTRLEN];
-
-               printf("%s\n", inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf,
-                                        sizeof(buf)));
-       } break;
-
 #ifdef AF_LINK
        case AF_LINK: {
                struct sockaddr_dl *sdl;
index 4e747144892adcb666f1eea80fdf269118cf6775..ac6dd29f06bd4832d090d1ad833ca9546b720d44 100644 (file)
@@ -110,8 +110,8 @@ void spf_backoff_free(struct spf_backoff *backoff)
        if (!backoff)
                return;
 
-       THREAD_TIMER_OFF(backoff->t_holddown);
-       THREAD_TIMER_OFF(backoff->t_timetolearn);
+       thread_cancel(&backoff->t_holddown);
+       thread_cancel(&backoff->t_timetolearn);
        XFREE(MTYPE_SPF_BACKOFF_NAME, backoff->name);
 
        XFREE(MTYPE_SPF_BACKOFF, backoff);
@@ -121,7 +121,6 @@ static int spf_backoff_timetolearn_elapsed(struct thread *thread)
 {
        struct spf_backoff *backoff = THREAD_ARG(thread);
 
-       backoff->t_timetolearn = NULL;
        backoff->state = SPF_BACKOFF_LONG_WAIT;
        backoff_debug("SPF Back-off(%s) TIMETOLEARN elapsed, move to state %s",
                      backoff->name, spf_backoff_state2str(backoff->state));
@@ -132,8 +131,7 @@ static int spf_backoff_holddown_elapsed(struct thread *thread)
 {
        struct spf_backoff *backoff = THREAD_ARG(thread);
 
-       backoff->t_holddown = NULL;
-       THREAD_TIMER_OFF(backoff->t_timetolearn);
+       THREAD_OFF(backoff->t_timetolearn);
        timerclear(&backoff->first_event_time);
        backoff->state = SPF_BACKOFF_QUIET;
        backoff_debug("SPF Back-off(%s) HOLDDOWN elapsed, move to state %s",
@@ -167,7 +165,7 @@ long spf_backoff_schedule(struct spf_backoff *backoff)
                break;
        case SPF_BACKOFF_SHORT_WAIT:
        case SPF_BACKOFF_LONG_WAIT:
-               THREAD_TIMER_OFF(backoff->t_holddown);
+               thread_cancel(&backoff->t_holddown);
                thread_add_timer_msec(backoff->m, spf_backoff_holddown_elapsed,
                                      backoff, backoff->holddown,
                                      &backoff->t_holddown);
index 23f85d809b5e787df0bc01ba4627e036fb4c2585..4f75f121ca25a6ad3034f51fdd800686933e256e 100644 (file)
@@ -386,6 +386,16 @@ static inline const uint8_t *ptr_get_be32(const uint8_t *ptr, uint32_t *out)
        return ptr + 4;
 }
 
+static inline uint8_t *ptr_get_be16(uint8_t *ptr, uint16_t *out)
+{
+       uint16_t tmp;
+
+       memcpy(&tmp, ptr, sizeof(tmp));
+       *out = ntohs(tmp);
+
+       return ptr + 2;
+}
+
 /*
  * so Normal stream_getX functions assert.  Which is anathema
  * to keeping a daemon up and running when something goes south
index b8bcee139bf448db847f84c2d22a42ab1326c7c0..ed3c30799d9afd57eb6c65ffc3456ae4209823ba 100644 (file)
@@ -3,7 +3,7 @@
 #
 lib_LTLIBRARIES += lib/libfrr.la
 lib_libfrr_la_LDFLAGS = -version-info 0:0:0 -Xlinker -e_libfrr_version
-lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(LIBM)
+lib_libfrr_la_LIBADD = $(LIBCAP) $(UNWIND_LIBS) $(LIBYANG_LIBS) $(LUA_LIB) $(UST_LIBS) $(LIBM)
 
 lib_libfrr_la_SOURCES = \
        lib/agg_table.c \
@@ -46,6 +46,7 @@ lib_libfrr_la_SOURCES = \
        lib/lib_errors.c \
        lib/lib_vty.c \
        lib/libfrr.c \
+       lib/libfrr_trace.c \
        lib/linklist.c \
        lib/log.c \
        lib/log_filter.c \
@@ -123,6 +124,7 @@ nodist_lib_libfrr_la_SOURCES = \
        yang/frr-nexthop.yang.c \
        yang/ietf/ietf-routing-types.yang.c \
        yang/ietf/ietf-interfaces.yang.c \
+       yang/ietf/ietf-bgp-types.yang.c \
        yang/frr-module-translator.yang.c \
        yang/frr-nexthop.yang.c \
        # end
@@ -203,6 +205,7 @@ pkginclude_HEADERS += \
        lib/lib_errors.h \
        lib/lib_vty.h \
        lib/libfrr.h \
+       lib/libfrr_trace.h \
        lib/libospf.h \
        lib/linklist.h \
        lib/log.h \
@@ -250,6 +253,7 @@ pkginclude_HEADERS += \
        lib/table.h \
        lib/termtable.h \
        lib/thread.h \
+       lib/trace.h \
        lib/typerb.h \
        lib/typesafe.h \
        lib/vector.h \
@@ -400,7 +404,7 @@ lib_grammar_sandbox_LDADD = \
 
 lib_clippy_CPPFLAGS = $(AM_CPPFLAGS) -D_GNU_SOURCE -DBUILDING_CLIPPY
 lib_clippy_CFLAGS = $(PYTHON_CFLAGS)
-lib_clippy_LDADD = $(PYTHON_LIBS)
+lib_clippy_LDADD = $(PYTHON_LIBS) $(UST_LIBS)
 lib_clippy_LDFLAGS = -export-dynamic
 lib_clippy_SOURCES = \
        lib/clippy.c \
@@ -410,6 +414,7 @@ lib_clippy_SOURCES = \
        lib/command_py.c \
        lib/defun_lex.l \
        lib/graph.c \
+       lib/libfrr_trace.c \
        lib/memory.c \
        lib/vector.c \
        # end
index 86347cbacda11cde88b0e19de42fc5cd56f92a6f..89e32182b5c14d062c46a944604a740e4c31f8f3 100644 (file)
@@ -27,6 +27,7 @@
 #include "table.h"
 #include "memory.h"
 #include "sockunion.h"
+#include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, ROUTE_TABLE, "Route table")
 DEFINE_MTYPE(LIB, ROUTE_NODE, "Route node")
@@ -119,7 +120,8 @@ static void route_table_free(struct route_table *rt)
                node = node->parent;
 
                tmp_node->table->count--;
-               tmp_node->lock = 0; /* to cause assert if unlocked after this */
+               tmp_node->lock =
+                       0; /* to cause assert if unlocked after this */
                rn_hash_node_del(&rt->hash, tmp_node);
                route_node_free(rt, tmp_node);
 
@@ -275,6 +277,12 @@ struct route_node *route_node_lookup_maynull(struct route_table *table,
 struct route_node *route_node_get(struct route_table *table,
                                  union prefixconstptr pu)
 {
+       if (frrtrace_enabled(frr_libfrr, route_node_get)) {
+               char buf[PREFIX2STR_BUFFER];
+               prefix2str(pu, buf, sizeof(buf));
+               frrtrace(2, frr_libfrr, route_node_get, table, buf);
+       }
+
        struct route_node search;
        struct prefix *p = &search.p;
 
index 9cd950337607947ede53dac465ec5250a7b6a16a..5d620d332b93379d37eeede238a6f954921ab6e5 100644 (file)
@@ -262,6 +262,11 @@ static inline void route_unlock_node(struct route_node *node)
                route_node_delete(node);
 }
 
+static inline unsigned int route_node_get_lock_count(struct route_node *node)
+{
+       return node->lock;
+}
+
 /*
  * route_table_iter_next
  *
index db35a3f031d094958725a78345fb25fbe7b77f13..db53e267f89f32d8fe7c96a00a15be2a208812c4 100644 (file)
@@ -35,6 +35,7 @@
 #include "frratomic.h"
 #include "frr_pthread.h"
 #include "lib_errors.h"
+#include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, THREAD, "Thread")
 DEFINE_MTYPE_STATIC(LIB, THREAD_MASTER, "Thread master")
@@ -727,9 +728,13 @@ static void thread_free(struct thread_master *master, struct thread *thread)
        XFREE(MTYPE_THREAD, thread);
 }
 
-static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize,
-                  nfds_t count, const struct timeval *timer_wait)
+static int fd_poll(struct thread_master *m, const struct timeval *timer_wait,
+                  bool *eintr_p)
 {
+       sigset_t origsigs;
+       unsigned char trash[64];
+       nfds_t count = m->handler.copycount;
+
        /*
         * If timer_wait is null here, that means poll() should block
         * indefinitely, unless the thread_master has overridden it by setting
@@ -760,15 +765,58 @@ static int fd_poll(struct thread_master *m, struct pollfd *pfds, nfds_t pfdsize,
        rcu_assert_read_unlocked();
 
        /* add poll pipe poker */
-       assert(count + 1 < pfdsize);
-       pfds[count].fd = m->io_pipe[0];
-       pfds[count].events = POLLIN;
-       pfds[count].revents = 0x00;
+       assert(count + 1 < m->handler.pfdsize);
+       m->handler.copy[count].fd = m->io_pipe[0];
+       m->handler.copy[count].events = POLLIN;
+       m->handler.copy[count].revents = 0x00;
+
+       /* We need to deal with a signal-handling race here: we
+        * don't want to miss a crucial signal, such as SIGTERM or SIGINT,
+        * that may arrive just before we enter poll(). We will block the
+        * key signals, then check whether any have arrived - if so, we return
+        * before calling poll(). If not, we'll re-enable the signals
+        * in the ppoll() call.
+        */
+
+       sigemptyset(&origsigs);
+       if (m->handle_signals) {
+               /* Main pthread that handles the app signals */
+               if (frr_sigevent_check(&origsigs)) {
+                       /* Signal to process - restore signal mask and return */
+                       pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
+                       num = -1;
+                       *eintr_p = true;
+                       goto done;
+               }
+       } else {
+               /* Don't make any changes for the non-main pthreads */
+               pthread_sigmask(SIG_SETMASK, NULL, &origsigs);
+       }
 
-       num = poll(pfds, count + 1, timeout);
+#if defined(HAVE_PPOLL)
+       struct timespec ts, *tsp;
 
-       unsigned char trash[64];
-       if (num > 0 && pfds[count].revents != 0 && num--)
+       if (timeout >= 0) {
+               ts.tv_sec = timeout / 1000;
+               ts.tv_nsec = (timeout % 1000) * 1000000;
+               tsp = &ts;
+       } else
+               tsp = NULL;
+
+       num = ppoll(m->handler.copy, count + 1, tsp, &origsigs);
+       pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
+#else
+       /* Not ideal - there is a race after we restore the signal mask */
+       pthread_sigmask(SIG_SETMASK, &origsigs, NULL);
+       num = poll(m->handler.copy, count + 1, timeout);
+#endif
+
+done:
+
+       if (num < 0 && errno == EINTR)
+               *eintr_p = true;
+
+       if (num > 0 && m->handler.copy[count].revents != 0 && num--)
                while (read(m->io_pipe[0], &trash, sizeof(trash)) > 0)
                        ;
 
@@ -787,6 +835,13 @@ struct thread *funcname_thread_add_read_write(int dir, struct thread_master *m,
        struct thread *thread = NULL;
        struct thread **thread_array;
 
+       if (dir == THREAD_READ)
+               frrtrace(9, frr_libfrr, schedule_read, m, funcname, schedfrom,
+                        fromln, t_ptr, fd, 0, arg, 0);
+       else
+               frrtrace(9, frr_libfrr, schedule_write, m, funcname, schedfrom,
+                        fromln, t_ptr, fd, 0, arg, 0);
+
        assert(fd >= 0 && fd < m->fd_limit);
        frr_with_mutex(&m->mtx) {
                if (t_ptr && *t_ptr)
@@ -861,6 +916,9 @@ funcname_thread_add_timer_timeval(struct thread_master *m,
        assert(type == THREAD_TIMER);
        assert(time_relative);
 
+       frrtrace(9, frr_libfrr, schedule_timer, m, funcname, schedfrom, fromln,
+                t_ptr, 0, 0, arg, (long)time_relative->tv_sec);
+
        frr_with_mutex(&m->mtx) {
                if (t_ptr && *t_ptr)
                        /* thread is already scheduled; don't reschedule */
@@ -939,6 +997,9 @@ struct thread *funcname_thread_add_event(struct thread_master *m,
 {
        struct thread *thread = NULL;
 
+       frrtrace(9, frr_libfrr, schedule_event, m, funcname, schedfrom, fromln,
+                t_ptr, 0, val, arg, 0);
+
        assert(m != NULL);
 
        frr_with_mutex(&m->mtx) {
@@ -1163,19 +1224,30 @@ void thread_cancel_event(struct thread_master *master, void *arg)
  *
  * @param thread task to cancel
  */
-void thread_cancel(struct thread *thread)
+void thread_cancel(struct thread **thread)
 {
-       struct thread_master *master = thread->master;
+       struct thread_master *master;
+
+       if (thread == NULL || *thread == NULL)
+               return;
+
+       master = (*thread)->master;
+
+       frrtrace(9, frr_libfrr, thread_cancel, master, (*thread)->funcname,
+                (*thread)->schedfrom, (*thread)->schedfrom_line, NULL, (*thread)->u.fd,
+                (*thread)->u.val, (*thread)->arg, (*thread)->u.sands.tv_sec);
 
        assert(master->owner == pthread_self());
 
        frr_with_mutex(&master->mtx) {
                struct cancel_req *cr =
                        XCALLOC(MTYPE_TMP, sizeof(struct cancel_req));
-               cr->thread = thread;
+               cr->thread = *thread;
                listnode_add(master->cancel_req, cr);
                do_thread_cancel(master);
        }
+
+       *thread = NULL;
 }
 
 /**
@@ -1206,6 +1278,17 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread,
                         void *eventobj)
 {
        assert(!(thread && eventobj) && (thread || eventobj));
+
+       if (thread && *thread)
+               frrtrace(9, frr_libfrr, thread_cancel_async, master,
+                        (*thread)->funcname, (*thread)->schedfrom,
+                        (*thread)->schedfrom_line, NULL, (*thread)->u.fd,
+                        (*thread)->u.val, (*thread)->arg,
+                        (*thread)->u.sands.tv_sec);
+       else
+               frrtrace(9, frr_libfrr, thread_cancel_async, master, NULL, NULL,
+                        0, NULL, 0, 0, eventobj, 0);
+
        assert(master->owner != pthread_self());
 
        frr_with_mutex(&master->mtx) {
@@ -1227,6 +1310,9 @@ void thread_cancel_async(struct thread_master *master, struct thread **thread,
                while (!master->canceled)
                        pthread_cond_wait(&master->cancel_cond, &master->mtx);
        }
+
+       if (thread)
+               *thread = NULL;
 }
 /* ------------------------------------------------------------------------- */
 
@@ -1395,7 +1481,7 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
        struct timeval zerotime = {0, 0};
        struct timeval tv;
        struct timeval *tw = NULL;
-
+       bool eintr_p = false;
        int num = 0;
 
        do {
@@ -1467,14 +1553,14 @@ struct thread *thread_fetch(struct thread_master *m, struct thread *fetch)
 
                pthread_mutex_unlock(&m->mtx);
                {
-                       num = fd_poll(m, m->handler.copy, m->handler.pfdsize,
-                                     m->handler.copycount, tw);
+                       eintr_p = false;
+                       num = fd_poll(m, tw, &eintr_p);
                }
                pthread_mutex_lock(&m->mtx);
 
                /* Handle any errors received in poll() */
                if (num < 0) {
-                       if (errno == EINTR) {
+                       if (eintr_p) {
                                pthread_mutex_unlock(&m->mtx);
                                /* loop around to signal handler */
                                continue;
@@ -1581,6 +1667,10 @@ void thread_call(struct thread *thread)
        GETRUSAGE(&before);
        thread->real = before.real;
 
+       frrtrace(9, frr_libfrr, thread_call, thread->master, thread->funcname,
+                thread->schedfrom, thread->schedfrom_line, NULL, thread->u.fd,
+                thread->u.val, thread->arg, thread->u.sands.tv_sec);
+
        pthread_setspecific(thread_current, thread);
        (*thread->func)(thread);
        pthread_setspecific(thread_current, NULL);
@@ -1660,3 +1750,49 @@ void funcname_thread_execute(struct thread_master *m,
        /* Give back or free thread. */
        thread_add_unuse(m, thread);
 }
+
+/* Debug signal mask - if 'sigs' is NULL, use current effective mask. */
+void debug_signals(const sigset_t *sigs)
+{
+       int i, found;
+       sigset_t tmpsigs;
+       char buf[300];
+
+       /*
+        * We're only looking at the non-realtime signals here, so we need
+        * some limit value. Platform differences mean at some point we just
+        * need to pick a reasonable value.
+        */
+#if defined SIGRTMIN
+#  define LAST_SIGNAL SIGRTMIN
+#else
+#  define LAST_SIGNAL 32
+#endif
+
+
+       if (sigs == NULL) {
+               sigemptyset(&tmpsigs);
+               pthread_sigmask(SIG_BLOCK, NULL, &tmpsigs);
+               sigs = &tmpsigs;
+       }
+
+       found = 0;
+       buf[0] = '\0';
+
+       for (i = 0; i < LAST_SIGNAL; i++) {
+               char tmp[20];
+
+               if (sigismember(sigs, i) > 0) {
+                       if (found > 0)
+                               strlcat(buf, ",", sizeof(buf));
+                       snprintf(tmp, sizeof(tmp), "%d", i);
+                       strlcat(buf, tmp, sizeof(buf));
+                       found++;
+               }
+       }
+
+       if (found == 0)
+               snprintf(buf, sizeof(buf), "<none>");
+
+       zlog_debug("%s: %s", __func__, buf);
+}
index c22b2105cd43969215d4a597fc29dcc3ed670e3f..682a17b9f302cac88308ea4128d38145030d1e3b 100644 (file)
@@ -147,18 +147,15 @@ struct cpu_thread_history {
 #define THREAD_FD(X)  ((X)->u.fd)
 #define THREAD_VAL(X) ((X)->u.val)
 
-#define THREAD_OFF(thread)                                                     \
-       do {                                                                   \
-               if (thread) {                                                  \
-                       thread_cancel(thread);                                 \
-                       thread = NULL;                                         \
-               }                                                              \
+/*
+ * Please consider this macro deprecated, and do not use it in new code.
+ */
+#define THREAD_OFF(thread)                                             \
+       do {                                                           \
+               if ((thread))                                          \
+                       thread_cancel(&(thread));                      \
        } while (0)
 
-#define THREAD_READ_OFF(thread)  THREAD_OFF(thread)
-#define THREAD_WRITE_OFF(thread)  THREAD_OFF(thread)
-#define THREAD_TIMER_OFF(thread)  THREAD_OFF(thread)
-
 #define debugargdef  const char *funcname, const char *schedfrom, int fromln
 
 #define thread_add_read(m,f,a,v,t) funcname_thread_add_read_write(THREAD_READ,m,f,a,v,t,#f,__FILE__,__LINE__)
@@ -207,7 +204,7 @@ extern void funcname_thread_execute(struct thread_master *,
                                    debugargdef);
 #undef debugargdef
 
-extern void thread_cancel(struct thread *);
+extern void thread_cancel(struct thread **event);
 extern void thread_cancel_async(struct thread_master *, struct thread **,
                                void *);
 extern void thread_cancel_event(struct thread_master *, void *);
@@ -233,6 +230,9 @@ extern pthread_key_t thread_current;
 extern char *thread_timer_to_hhmmss(char *buf, int buf_size,
                struct thread *t_timer);
 
+/* Debug signal mask */
+void debug_signals(const sigset_t *sigs);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/trace.h b/lib/trace.h
new file mode 100644 (file)
index 0000000..73fc10a
--- /dev/null
@@ -0,0 +1,80 @@
+/* Tracing macros
+ *
+ * Wraps tracepoint macros for different tracing systems to allow switching
+ * between them at compile time.
+ *
+ * This should not be included directly by source files wishing to provide
+ * tracepoints. Instead, write a header that defines LTTng tracepoints and
+ * which includes this header, and include your new header in your source. USDT
+ * probes do not need tracepoint definitions, but are less capable than LTTng
+ * tracepoints.
+ *
+ * Copyright (C) 2020  NVIDIA Corporation
+ * Quentin Young
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _TRACE_H_
+#define _TRACE_H_
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+/*
+ * Provided here:
+ * - frrtrace(n, provider, name, ...args...)
+ * - frrtrace_enabled(provider, name)
+ * - frrtracelog(level, msg, ...)
+ *
+ * Use frrtrace() to define tracepoints. n is the number of arguments; this is
+ * needed because USDT probe definitions use DTRACE_PROBEn macros, so the
+ * number of args must be passed in order to expand the correct macro.
+ *
+ * frrtrace_enabled() maps to tracepoint_enabled() under LTTng and is always
+ * true when using USDT. In the future it could be mapped to USDT semaphores
+ * but this is not implemented at present.
+ *
+ * frrtracelog() maps to tracelog() under LTTng and should only be used in zlog
+ * core code, to propagate zlog messages to LTTng. It expands to nothing
+ * otherwise.
+ */
+
+#if defined(HAVE_LTTNG)
+
+#define frrtrace(nargs, provider, name, ...) \
+       tracepoint(provider, name, ## __VA_ARGS__)
+#define frrtrace_enabled(...) tracepoint_enabled(__VA_ARGS__)
+#define frrtracelog(...) tracelog(__VA_ARGS__)
+
+#elif defined(HAVE_USDT)
+
+#include "sys/sdt.h"
+
+#define frrtrace(nargs, provider, name, ...) \
+       DTRACE_PROBE##nargs(provider, name, ## __VA_ARGS__)
+#define frrtrace_enabled(...) true
+#define frrtracelog(...)
+
+#else
+
+#define frrtrace(nargs, provider, name, ...) (void)0
+#define frrtrace_enabled(...) false
+#define frrtracelog(...) (void)0
+
+#endif
+
+#endif /* _TRACE_H_ */
index 69d3939596bb5ac05720844a8d806b5dc6c6bd6d..62963a6097d4c677668cc5a53ae2433fcbb5cf6c 100644 (file)
 extern "C" {
 #endif
 
+/* EVPN MH DF election alogorithm */
+#define EVPN_MH_DF_ALG_SERVICE_CARVING 0
+#define EVPN_MH_DF_ALG_HRW 1
+#define EVPN_MH_DF_ALG_PREF 2
+
+/* preference range for DF election */
+#define EVPN_MH_DF_PREF_MIN 0
+#define EVPN_MH_DF_PREF_DEFAULT 32767
+#define EVPN_MH_DF_PREF_MAX 65535
+
 /* VxLAN Network Identifier - 24-bit (RFC 7348) */
 typedef uint32_t vni_t;
 #define VNI_MAX 16777215 /* (2^24 - 1) */
index 54090d0d0f82720852ffa150e1786c431e3eb736..f8e4677220f77a46b305054f51b7c189466ce6e3 100644 (file)
@@ -104,7 +104,7 @@ void work_queue_free_and_null(struct work_queue **wqp)
        struct work_queue *wq = *wqp;
 
        if (wq->thread != NULL)
-               thread_cancel(wq->thread);
+               thread_cancel(&(wq->thread));
 
        while (!work_queue_empty(wq)) {
                struct work_queue_item *item = work_queue_last_item(wq);
@@ -215,7 +215,7 @@ void workqueue_cmd_init(void)
 void work_queue_plug(struct work_queue *wq)
 {
        if (wq->thread)
-               thread_cancel(wq->thread);
+               thread_cancel(&(wq->thread));
 
        wq->thread = NULL;
 
index 5bf7758e18322f8b950e4b62fbb1efe375d4b72c..c59cb642f02fbd3b1d23fab2ebd04907ec54c015 100644 (file)
@@ -227,40 +227,22 @@ next:
        return ret;
 }
 
-int yang_snodes_iterate_module(const struct lys_module *module,
-                              yang_iterate_cb cb, uint16_t flags, void *arg)
+int yang_snodes_iterate(const struct lys_module *module, yang_iterate_cb cb,
+                       uint16_t flags, void *arg)
 {
-       struct lys_node *snode;
-       int ret = YANG_ITER_CONTINUE;
-
-       LY_TREE_FOR (module->data, snode) {
-               ret = yang_snodes_iterate_subtree(snode, module, cb, flags,
-                                                 arg);
-               if (ret == YANG_ITER_STOP)
-                       return ret;
-       }
-
-       for (uint8_t i = 0; i < module->augment_size; i++) {
-               ret = yang_snodes_iterate_subtree(
-                       (const struct lys_node *)&module->augment[i], module,
-                       cb, flags, arg);
-               if (ret == YANG_ITER_STOP)
-                       return ret;
-       }
-
-       return ret;
-}
-
-int yang_snodes_iterate_all(yang_iterate_cb cb, uint16_t flags, void *arg)
-{
-       struct yang_module *module;
+       const struct lys_module *module_iter;
+       uint32_t idx = 0;
        int ret = YANG_ITER_CONTINUE;
 
-       RB_FOREACH (module, yang_modules, &yang_modules) {
+       idx = ly_ctx_internal_modules_count(ly_native_ctx);
+       while ((module_iter = ly_ctx_get_module_iter(ly_native_ctx, &idx))) {
                struct lys_node *snode;
 
-               LY_TREE_FOR (module->info->data, snode) {
-                       ret = yang_snodes_iterate_subtree(snode, NULL, cb,
+               if (!module_iter->implemented)
+                       continue;
+
+               LY_TREE_FOR (module_iter->data, snode) {
+                       ret = yang_snodes_iterate_subtree(snode, module, cb,
                                                          flags, arg);
                        if (ret == YANG_ITER_STOP)
                                return ret;
index 867ade967692f27b89e38e3c8976bba9988bc361..0cd6a4a6f236766b89471bc8ee43b68679e3db22 100644 (file)
@@ -186,29 +186,11 @@ extern int yang_snodes_iterate_subtree(const struct lys_node *snode,
                                       void *arg);
 
 /*
- * Iterate over all libyang schema nodes from the given YANG module.
+ * Iterate over all libyang schema nodes from all loeaded modules of from the
+ * given YANG module.
  *
  * module
- *    YANG module to operate on.
- *
- * cb
- *    Function to call with each schema node.
- *
- * flags
- *    YANG_ITER_* flags to control how the iteration is performed.
- *
- * arg
- *    Arbitrary argument passed as the second parameter in each call to 'cb'.
- *
- * Returns:
- *    The return value of the last called callback.
- */
-extern int yang_snodes_iterate_module(const struct lys_module *module,
-                                     yang_iterate_cb cb, uint16_t flags,
-                                     void *arg);
-
-/*
- * Iterate over all libyang schema nodes from all loaded YANG modules.
+ *    When set, iterate over all nodes of the specified module only.
  *
  * cb
  *    Function to call with each schema node.
@@ -222,8 +204,8 @@ extern int yang_snodes_iterate_module(const struct lys_module *module,
  * Returns:
  *    The return value of the last called callback.
  */
-extern int yang_snodes_iterate_all(yang_iterate_cb cb, uint16_t flags,
-                                  void *arg);
+extern int yang_snodes_iterate(const struct lys_module *module,
+                              yang_iterate_cb cb, uint16_t flags, void *arg);
 
 /*
  * Build schema path or data path of the schema node.
index 7dbb1f3f1a10bae2ffb28d5e052b3f23eecdbf9b..1f64675d6a410bbf3584d23b276b03b7d25c8d22 100644 (file)
@@ -469,12 +469,12 @@ static unsigned int yang_translator_validate(struct yang_translator *translator)
        args.errors = 0;
 
        for (ALL_LIST_ELEMENTS_RO(translator->modules, ln, tmodule)) {
-               yang_snodes_iterate_module(
-                       tmodule->module, yang_translator_validate_cb,
-                       YANG_ITER_FILTER_NPCONTAINERS
-                               | YANG_ITER_FILTER_LIST_KEYS
-                               | YANG_ITER_FILTER_INPUT_OUTPUT,
-                       &args);
+               yang_snodes_iterate(tmodule->module,
+                                   yang_translator_validate_cb,
+                                   YANG_ITER_FILTER_NPCONTAINERS
+                                           | YANG_ITER_FILTER_LIST_KEYS
+                                           | YANG_ITER_FILTER_INPUT_OUTPUT,
+                                   &args);
        }
 
        if (args.errors)
@@ -500,11 +500,11 @@ static unsigned int yang_module_nodes_count(const struct lys_module *module)
 {
        unsigned int total = 0;
 
-       yang_snodes_iterate_module(module, yang_module_nodes_count_cb,
-                                  YANG_ITER_FILTER_NPCONTAINERS
-                                          | YANG_ITER_FILTER_LIST_KEYS
-                                          | YANG_ITER_FILTER_INPUT_OUTPUT,
-                                  &total);
+       yang_snodes_iterate(module, yang_module_nodes_count_cb,
+                           YANG_ITER_FILTER_NPCONTAINERS
+                                   | YANG_ITER_FILTER_LIST_KEYS
+                                   | YANG_ITER_FILTER_INPUT_OUTPUT,
+                           &total);
 
        return total;
 }
index e50a88f40781d85910ca8079e949ff2b25bb4169..e6b254ee8d43e62d128c158e272dbde9894335bc 100644 (file)
@@ -27,6 +27,8 @@ extern void _zlog_assert_failed(const char *assertion, const char *file,
                                unsigned int line, const char *function)
        __attribute__((noreturn));
 
+#undef __ASSERT_FUNCTION
+
 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
 #define __ASSERT_FUNCTION    __func__
 #elif defined(__GNUC__)
index 914b02749e758f3b6952f974b53a40959d7a1f09..d0144279e53642412fa0668fe9b0b571af97079b 100644 (file)
@@ -1116,13 +1116,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
        if (CHECK_FLAG(api->message, ZAPI_MESSAGE_NEXTHOP)) {
                /* limit the number of nexthops if necessary */
                if (api->nexthop_num > MULTIPATH_NUM) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(&api->prefix, buf, sizeof(buf));
                        flog_err(
                                EC_LIB_ZAPI_ENCODE,
-                               "%s: prefix %s: can't encode %u nexthops (maximum is %u)",
-                               __func__, buf, api->nexthop_num, MULTIPATH_NUM);
+                               "%s: prefix %pFX: can't encode %u nexthops (maximum is %u)",
+                               __func__, &api->prefix, api->nexthop_num,
+                               MULTIPATH_NUM);
                        return -1;
                }
 
@@ -1139,15 +1137,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
 
                        /* MPLS labels for BGP-LU or Segment Routing */
                        if (api_nh->label_num > MPLS_MAX_LABELS) {
-                               char buf[PREFIX2STR_BUFFER];
-
-                               prefix2str(&api->prefix, buf, sizeof(buf));
-
-                               flog_err(EC_LIB_ZAPI_ENCODE,
-                                        "%s: prefix %s: can't encode %u labels (maximum is %u)",
-                                        __func__, buf,
-                                        api_nh->label_num,
-                                        MPLS_MAX_LABELS);
+                               flog_err(
+                                       EC_LIB_ZAPI_ENCODE,
+                                       "%s: prefix %pFX: can't encode %u labels (maximum is %u)",
+                                       __func__, &api->prefix,
+                                       api_nh->label_num, MPLS_MAX_LABELS);
                                return -1;
                        }
 
@@ -1162,13 +1156,10 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
        if (CHECK_FLAG(api->message, ZAPI_MESSAGE_BACKUP_NEXTHOPS)) {
                /* limit the number of nexthops if necessary */
                if (api->backup_nexthop_num > MULTIPATH_NUM) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(&api->prefix, buf, sizeof(buf));
                        flog_err(
                                EC_LIB_ZAPI_ENCODE,
-                               "%s: prefix %s: can't encode %u backup nexthops (maximum is %u)",
-                               __func__, buf, api->backup_nexthop_num,
+                               "%s: prefix %pFX: can't encode %u backup nexthops (maximum is %u)",
+                               __func__, &api->prefix, api->backup_nexthop_num,
                                MULTIPATH_NUM);
                        return -1;
                }
@@ -1185,15 +1176,11 @@ int zapi_route_encode(uint8_t cmd, struct stream *s, struct zapi_route *api)
 
                        /* MPLS labels for BGP-LU or Segment Routing */
                        if (api_nh->label_num > MPLS_MAX_LABELS) {
-                               char buf[PREFIX2STR_BUFFER];
-
-                               prefix2str(&api->prefix, buf, sizeof(buf));
-
-                               flog_err(EC_LIB_ZAPI_ENCODE,
-                                        "%s: prefix %s: backup: can't encode %u labels (maximum is %u)",
-                                        __func__, buf,
-                                        api_nh->label_num,
-                                        MPLS_MAX_LABELS);
+                               flog_err(
+                                       EC_LIB_ZAPI_ENCODE,
+                                       "%s: prefix %pFX: backup: can't encode %u labels (maximum is %u)",
+                                       __func__, &api->prefix,
+                                       api_nh->label_num, MPLS_MAX_LABELS);
                                return -1;
                        }
 
@@ -2319,13 +2306,10 @@ struct connected *zebra_interface_address_read(int type, struct stream *s,
                        else if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
                                /* carp interfaces on OpenBSD with 0.0.0.0/0 as
                                 * "peer" */
-                               char buf[PREFIX_STRLEN];
                                flog_err(
                                        EC_LIB_ZAPI_ENCODE,
-                                       "warning: interface %s address %s with peer flag set, but no peer address!",
-                                       ifp->name,
-                                       prefix2str(ifc->address, buf,
-                                                  sizeof(buf)));
+                                       "warning: interface %s address %pFX with peer flag set, but no peer address!",
+                                       ifp->name, ifc->address);
                                UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
                        }
                }
index 959a101395842644d805541357ad626760b7063b..80dca3fc56072fd881e393092224badd23b216a1 100644 (file)
@@ -690,6 +690,12 @@ zapi_rule_notify_owner2str(enum zapi_rule_notify_owner note)
  * to allocate past 0x80
  */
 
+/* Zebra ES VTEP flags (ZEBRA_REMOTE_ES_VTEP_ADD) */
+/* ESR has been rxed from the VTEP. Only VTEPs that have advertised the
+ * Type-4 route can participate in DF election.
+ */
+#define ZAPI_ES_VTEP_FLAG_ESR_RXED (1 << 0)
+
 enum zebra_neigh_state { ZEBRA_NEIGH_INACTIVE = 0, ZEBRA_NEIGH_ACTIVE = 1 };
 
 struct zclient_options {
index 8dfd20371b8263425d4a21feee9f9f498a96075e..e77feec5f2c7962cb540d283ba487376d881f2ff 100644 (file)
@@ -52,6 +52,7 @@
 #include "printfrr.h"
 #include "frrcu.h"
 #include "zlog.h"
+#include "libfrr_trace.h"
 
 DEFINE_MTYPE_STATIC(LIB, LOG_MESSAGE,  "log message")
 DEFINE_MTYPE_STATIC(LIB, LOG_TLSBUF,   "log thread-local buffer")
@@ -450,6 +451,34 @@ void vzlog(int prio, const char *fmt, va_list ap)
 {
        struct zlog_tls *zlog_tls = zlog_tls_get();
 
+#ifdef HAVE_LTTNG
+       va_list copy;
+       va_copy(copy, ap);
+       char *msg = vasprintfrr(MTYPE_LOG_MESSAGE, fmt, copy);
+
+       switch (prio) {
+       case LOG_ERR:
+               frrtracelog(TRACE_ERR, msg);
+               break;
+       case LOG_WARNING:
+               frrtracelog(TRACE_WARNING, msg);
+               break;
+       case LOG_DEBUG:
+               frrtracelog(TRACE_DEBUG, msg);
+               break;
+       case LOG_NOTICE:
+               frrtracelog(TRACE_DEBUG, msg);
+               break;
+       case LOG_INFO:
+       default:
+               frrtracelog(TRACE_INFO, msg);
+               break;
+       }
+
+       va_end(copy);
+       XFREE(MTYPE_LOG_MESSAGE, msg);
+#endif
+
        if (zlog_tls)
                vzlog_tls(zlog_tls, prio, fmt, ap);
        else
index 569b3f4463229aff14c6705d585c8c2184b0e059..8bb5f69bea4dc4bd82bc942e8dc71fa7bae6bb27 100644 (file)
@@ -126,7 +126,8 @@ Integration with strongSwan
 
 Contrary to opennhrp, Quagga/NHRP has tight integration with IKE daemon.
 Currently strongSwan is supported using the VICI protocol. strongSwan
-is connected using UNIX socket (hardcoded now as /var/run/charon.vici).
+is connected using UNIX socket (default /var/run/charon.vici use configure
+argument --with-vici-socket= to change).
 Thus nhrpd needs to be run as user that can open that file.
 
 Currently, you will need patched strongSwan. The working tree is at:
index cf338a08766f7d02a8fcd804b9f06ef55c83ea72..309f7335260d876eff3b8cb6326d8fb431302ce4 100644 (file)
@@ -257,7 +257,7 @@ static int netlink_log_recv(struct thread *t)
 void netlink_set_nflog_group(int nlgroup)
 {
        if (netlink_log_fd >= 0) {
-               THREAD_OFF(netlink_log_thread);
+               thread_cancel(&netlink_log_thread);
                close(netlink_log_fd);
                netlink_log_fd = -1;
        }
index 1e576fc5ac21370cfa756ef47c20f1dbeeca9efc..0ed2371eb0496402a1804a10b7292c841672ec6b 100644 (file)
@@ -220,8 +220,8 @@ static void nhrp_interface_update_address(struct interface *ifp, afi_t afi,
        /* On NHRP interfaces a host prefix is required */
        if (best && if_ad->configured
            && best->address->prefixlen != 8 * prefix_blen(best->address)) {
-               zlog_notice("%s: %s is not a host prefix", ifp->name,
-                           prefix2str(best->address, buf, sizeof(buf)));
+               zlog_notice("%s: %pFX is not a host prefix", ifp->name,
+                           best->address);
                best = NULL;
        }
 
@@ -335,14 +335,13 @@ int nhrp_ifp_down(struct interface *ifp)
 int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS)
 {
        struct connected *ifc;
-       char buf[PREFIX_STRLEN];
 
        ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
        if (ifc == NULL)
                return 0;
 
-       debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %s", ifc->ifp->name,
-              prefix2str(ifc->address, buf, sizeof(buf)));
+       debugf(NHRP_DEBUG_IF, "if-addr-add: %s: %pFX", ifc->ifp->name,
+              ifc->address);
 
        nhrp_interface_update_address(
                ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
@@ -353,14 +352,13 @@ int nhrp_interface_address_add(ZAPI_CALLBACK_ARGS)
 int nhrp_interface_address_delete(ZAPI_CALLBACK_ARGS)
 {
        struct connected *ifc;
-       char buf[PREFIX_STRLEN];
 
        ifc = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
        if (ifc == NULL)
                return 0;
 
-       debugf(NHRP_DEBUG_IF, "if-addr-del: %s: %s", ifc->ifp->name,
-              prefix2str(ifc->address, buf, sizeof(buf)));
+       debugf(NHRP_DEBUG_IF, "if-addr-del: %s: %pFX", ifc->ifp->name,
+              ifc->address);
 
        nhrp_interface_update_address(
                ifc->ifp, family2afi(PREFIX_FAMILY(ifc->address)), 0);
index 8509cedceec601dcb12c2a01c9ac8d3691440302..085cab347f722e179477c8a205cb87eb44ea84ec 100644 (file)
@@ -137,7 +137,7 @@ static void nhrp_reg_peer_notify(struct notifier_block *n, unsigned long cmd)
                debugf(NHRP_DEBUG_COMMON, "NHS: Flush timer for %s",
                       sockunion2str(&r->peer->vc->remote.nbma, buf,
                                     sizeof(buf)));
-               THREAD_TIMER_OFF(r->t_register);
+               THREAD_OFF(r->t_register);
                thread_add_timer_msec(master, nhrp_reg_send_req, r, 10,
                                      &r->t_register);
                break;
index 0c5513b89297c4a63a02fd0655985f65361878a9..2bc2d91597c681a2f873ea573f6ff480d91443ee 100644 (file)
@@ -166,14 +166,13 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type,
        }
 
        if (unlikely(debug_flags & NHRP_DEBUG_ROUTE)) {
-               char buf[2][PREFIX_STRLEN];
+               char buf[PREFIX_STRLEN];
 
-               prefix2str(&api.prefix, buf[0], sizeof(buf[0]));
                zlog_debug(
-                       "Zebra send: route %s %s nexthop %s metric %u count %d dev %s",
-                       add ? "add" : "del", buf[0],
+                       "Zebra send: route %s %pFX nexthop %s metric %u count %d dev %s",
+                       add ? "add" : "del", &api.prefix,
                        nexthop ? inet_ntop(api.prefix.family, &api_nh->gate,
-                                           buf[1], sizeof(buf[1]))
+                                           buf, sizeof(buf))
                                : "<onlink>",
                        api.metric, api.nexthop_num, ifp ? ifp->name : "none");
        }
@@ -188,7 +187,7 @@ int nhrp_route_read(ZAPI_CALLBACK_ARGS)
        struct zapi_nexthop *api_nh;
        struct interface *ifp = NULL;
        union sockunion nexthop_addr;
-       char buf[2][PREFIX_STRLEN];
+       char buf[PREFIX_STRLEN];
        int added;
 
        if (zapi_route_decode(zclient->ibuf, &api) < 0)
@@ -221,10 +220,9 @@ int nhrp_route_read(ZAPI_CALLBACK_ARGS)
        }
 
        added = (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD);
-       debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %s via %s dev %s",
-              added ? "add" : "del",
-              prefix2str(&api.prefix, buf[0], sizeof(buf[0])),
-              sockunion2str(&nexthop_addr, buf[1], sizeof(buf[1])),
+       debugf(NHRP_DEBUG_ROUTE, "if-route-%s: %pFX via %s dev %s",
+              added ? "add" : "del", &api.prefix,
+              sockunion2str(&nexthop_addr, buf, sizeof(buf)),
               ifp ? ifp->name : "(none)");
 
        nhrp_route_update_zebra(&api.prefix, &nexthop_addr, ifp);
@@ -240,7 +238,6 @@ int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p,
        struct route_info *ri;
        struct prefix lookup;
        afi_t afi = family2afi(sockunion_family(addr));
-       char buf[PREFIX_STRLEN];
 
        sockunion2hostprefix(addr, &lookup);
 
@@ -250,8 +247,7 @@ int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p,
 
        ri = rn->info;
        if (ri->nhrp_ifp) {
-               debugf(NHRP_DEBUG_ROUTE, "lookup %s: nhrp_if=%s",
-                      prefix2str(&lookup, buf, sizeof(buf)),
+               debugf(NHRP_DEBUG_ROUTE, "lookup %pFX: nhrp_if=%s", &lookup,
                       ri->nhrp_ifp->name);
 
                if (via)
@@ -259,9 +255,8 @@ int nhrp_route_get_nexthop(const union sockunion *addr, struct prefix *p,
                if (ifp)
                        *ifp = ri->nhrp_ifp;
        } else {
-               debugf(NHRP_DEBUG_ROUTE, "lookup %s: zebra route dev %s",
-                      prefix2str(&lookup, buf, sizeof(buf)),
-                      ri->ifp ? ri->ifp->name : "(none)");
+               debugf(NHRP_DEBUG_ROUTE, "lookup %pFX: zebra route dev %s",
+                      &lookup, ri->ifp ? ri->ifp->name : "(none)");
 
                if (via)
                        *via = ri->via;
index 1c2b2b28f2ff78057b73db7bca9edd3bbf71b894..9a6f77334f1868e79e4d774691452468a9035c3a 100644 (file)
@@ -28,11 +28,9 @@ static void nhrp_shortcut_send_resolution_req(struct nhrp_shortcut *s);
 
 static void nhrp_shortcut_check_use(struct nhrp_shortcut *s)
 {
-       char buf[PREFIX_STRLEN];
-
        if (s->expiring && s->cache && s->cache->used) {
-               debugf(NHRP_DEBUG_ROUTE, "Shortcut %s used and expiring",
-                      prefix2str(s->p, buf, sizeof(buf)));
+               debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX used and expiring",
+                      s->p);
                nhrp_shortcut_send_resolution_req(s);
        }
 }
@@ -53,8 +51,6 @@ static int nhrp_shortcut_do_expire(struct thread *t)
 static void nhrp_shortcut_cache_notify(struct notifier_block *n,
                                       unsigned long cmd)
 {
-       char buf[PREFIX_STRLEN];
-
        struct nhrp_shortcut *s =
                container_of(n, struct nhrp_shortcut, cache_notifier);
 
@@ -62,9 +58,8 @@ static void nhrp_shortcut_cache_notify(struct notifier_block *n,
        case NOTIFY_CACHE_UP:
                if (!s->route_installed) {
                        debugf(NHRP_DEBUG_ROUTE,
-                              "Shortcut: route install %s nh (unspec) dev %s",
-                              prefix2str(s->p, buf, sizeof(buf)),
-                              s->cache->ifp->name);
+                              "Shortcut: route install %pFX nh (unspec) dev %s",
+                              s->p, s->cache->ifp->name);
 
                        nhrp_route_announce(1, s->type, s->p, s->cache->ifp,
                                            NULL, 0);
@@ -152,13 +147,11 @@ static void nhrp_shortcut_delete(struct nhrp_shortcut *s)
 {
        struct route_node *rn;
        afi_t afi = family2afi(PREFIX_FAMILY(s->p));
-       char buf[PREFIX_STRLEN];
 
        THREAD_OFF(s->t_timer);
        nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
 
-       debugf(NHRP_DEBUG_ROUTE, "Shortcut %s purged",
-              prefix2str(s->p, buf, sizeof(buf)));
+       debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX purged", s->p);
 
        nhrp_shortcut_update_binding(s, NHRP_CACHE_INVALID, NULL, 0);
 
@@ -184,7 +177,6 @@ static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p)
 {
        struct nhrp_shortcut *s;
        struct route_node *rn;
-       char buf[PREFIX_STRLEN];
        afi_t afi = family2afi(PREFIX_FAMILY(p));
 
        if (!shortcut_rib[afi])
@@ -197,8 +189,7 @@ static struct nhrp_shortcut *nhrp_shortcut_get(struct prefix *p)
                s->type = NHRP_CACHE_INVALID;
                s->p = &rn->p;
 
-               debugf(NHRP_DEBUG_ROUTE, "Shortcut %s created",
-                      prefix2str(s->p, buf, sizeof(buf)));
+               debugf(NHRP_DEBUG_ROUTE, "Shortcut %pFX created", s->p);
        } else {
                s = rn->info;
                route_unlock_node(rn);
@@ -219,7 +210,7 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid,
        union sockunion *proto, cie_proto, *nbma, cie_nbma, nat_nbma;
        struct prefix prefix, route_prefix;
        struct zbuf extpl;
-       char bufp[PREFIX_STRLEN], buf[4][SU_ADDRSTRLEN];
+       char buf[4][SU_ADDRSTRLEN];
        int holding_time = pp->if_ad->holdtime;
 
        nhrp_reqid_free(&nhrp_packet_reqid, &s->reqid);
@@ -287,9 +278,8 @@ static void nhrp_shortcut_recv_resolution_rep(struct nhrp_reqid *reqid,
        }
 
        debugf(NHRP_DEBUG_COMMON,
-              "Shortcut: %s is at proto %s dst_proto %s cie-nbma %s nat-nbma %s cie-holdtime %d",
-              prefix2str(&prefix, bufp, sizeof(bufp)),
-              sockunion2str(proto, buf[0], sizeof(buf[0])),
+              "Shortcut: %pFX is at proto %s dst_proto %s cie-nbma %s nat-nbma %s cie-holdtime %d",
+              &prefix, sockunion2str(proto, buf[0], sizeof(buf[0])),
               sockunion2str(&pp->dst_proto, buf[1], sizeof(buf[1])),
               sockunion2str(&cie_nbma, buf[2], sizeof(buf[2])),
               sockunion2str(&nat_nbma, buf[3], sizeof(buf[3])),
index fe681b405248e79e527e3181f94262afd884d2b0..27b7bece485d3ae2029221d0415bd0eb675874ca 100644 (file)
@@ -1109,11 +1109,12 @@ void nhrp_config_init(void)
        access_list_init();
 
        /* global commands */
-       install_element(VIEW_NODE, &show_debugging_nhrp_cmd);
        install_element(VIEW_NODE, &show_ip_nhrp_cmd);
        install_element(VIEW_NODE, &show_dmvpn_cmd);
        install_element(ENABLE_NODE, &clear_nhrp_cmd);
 
+       install_element(ENABLE_NODE, &show_debugging_nhrp_cmd);
+
        install_element(ENABLE_NODE, &debug_nhrp_cmd);
        install_element(ENABLE_NODE, &no_debug_nhrp_cmd);
 
index 2dc05a4aa7305807ff8771463d880fb64b30c4ef..86554f53dc3a0748500cfc7f023325b0ad5fc5c3 100644 (file)
@@ -478,7 +478,7 @@ static int vici_reconnect(struct thread *t)
        if (vici->fd >= 0)
                return 0;
 
-       fd = sock_open_unix("/var/run/charon.vici");
+       fd = sock_open_unix(VICI_SOCKET);
        if (fd < 0) {
                debugf(NHRP_DEBUG_VICI,
                       "%s: failure connecting VICI socket: %s", __func__,
index 6fe3a289cec4fbebbd3d8d8714b43ba6c1f8f5a6..f087289df657d60416844640a82b7db041db1e0b 100644 (file)
@@ -82,10 +82,10 @@ static int ospf6_abr_nexthops_belong_to_area(struct ospf6_route *route,
 static void ospf6_abr_delete_route(struct ospf6_route *range,
                                   struct ospf6_route *summary,
                                   struct ospf6_route_table *summary_table,
-                                  struct ospf6_lsa *old)
+                                  struct ospf6_lsa *old, struct ospf6 *ospf6)
 {
        if (summary) {
-               ospf6_route_remove(summary, summary_table);
+               ospf6_route_remove(summary, summary_table, ospf6);
        }
 
        if (old && !OSPF6_LSA_IS_MAXAGE(old))
@@ -117,7 +117,7 @@ void ospf6_abr_disable_area(struct ospf6_area *area)
                                        area->ospf6->router_id, area->lsdb);
                if (old)
                        ospf6_lsa_purge(old);
-               ospf6_route_remove(ro, area->summary_prefix);
+               ospf6_route_remove(ro, area->summary_prefix, area->ospf6);
        }
 
        /* Withdraw all summary router-routes previously originated */
@@ -128,7 +128,7 @@ void ospf6_abr_disable_area(struct ospf6_area *area)
                                        area->ospf6->router_id, area->lsdb);
                if (old)
                        ospf6_lsa_purge(old);
-               ospf6_route_remove(ro, area->summary_router);
+               ospf6_route_remove(ro, area->summary_router, area->ospf6);
        }
 
        /* Schedule Router-LSA for each area (ABR status may change) */
@@ -153,7 +153,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
        struct ospf6_inter_router_lsa *router_lsa;
        struct ospf6_route_table *summary_table = NULL;
        uint16_t type;
-       char buf[PREFIX2STR_BUFFER];
        int is_debug = 0;
 
        /* Only destination type network, range or ASBR are considered */
@@ -196,12 +195,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
        if (route->type == OSPF6_DEST_TYPE_ROUTER) {
                if (ADV_ROUTER_IN_PREFIX(&route->prefix)
                    == area->ospf6->router_id) {
-                       inet_ntop(AF_INET,
-                                 &(ADV_ROUTER_IN_PREFIX(&route->prefix)), buf,
-                                 sizeof(buf));
                        zlog_debug(
-                               "%s: Skipping ASBR announcement for ABR (%s)",
-                               __func__, buf);
+                               "%s: Skipping ASBR announcement for ABR (%pFX)",
+                               __func__,
+                               &ADV_ROUTER_IN_PREFIX(&route->prefix));
                        return 0;
                }
        }
@@ -210,11 +207,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                if (IS_OSPF6_DEBUG_ABR
                    || IS_OSPF6_DEBUG_ORIGINATE(INTER_ROUTER)) {
                        is_debug++;
-                       inet_ntop(AF_INET,
-                                 &(ADV_ROUTER_IN_PREFIX(&route->prefix)), buf,
-                                 sizeof(buf));
-                       zlog_debug("Originating summary in area %s for ASBR %s",
-                                  area->name, buf);
+                       zlog_debug(
+                               "Originating summary in area %s for ASBR %pFX",
+                               area->name,
+                               &ADV_ROUTER_IN_PREFIX(&route->prefix));
                }
                summary_table = area->summary_router;
        } else {
@@ -226,16 +222,13 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                    route->path.origin.type ==
                    htons(OSPF6_LSTYPE_INTER_PREFIX)) {
                        if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST)) {
-                               if (is_debug) {
-                                       inet_ntop(AF_INET,
-                                                 &(ADV_ROUTER_IN_PREFIX(
-                                                       &route->prefix)), buf,
-                                                 sizeof(buf));
+                               if (is_debug)
                                        zlog_debug(
-                                               "%s: route %s with cost %u is not best, ignore.",
-                                               __func__, buf,
+                                               "%s: route %pFX with cost %u is not best, ignore.",
+                                               __func__,
+                                               &ADV_ROUTER_IN_PREFIX(
+                                                       &route->prefix),
                                                route->path.cost);
-                               }
                                return 0;
                        }
                }
@@ -243,23 +236,19 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                if (route->path.origin.type ==
                    htons(OSPF6_LSTYPE_INTRA_PREFIX)) {
                        if (!CHECK_FLAG(route->flag, OSPF6_ROUTE_BEST)) {
-                               if (is_debug) {
-                                       prefix2str(&route->prefix, buf,
-                                                  sizeof(buf));
+                               if (is_debug)
                                        zlog_debug(
-                                               "%s: intra-prefix route %s with cost %u is not best, ignore.",
-                                               __func__, buf,
+                                               "%s: intra-prefix route %pFX with cost %u is not best, ignore.",
+                                               __func__, &route->prefix,
                                                route->path.cost);
-                               }
                                return 0;
                        }
                }
 
-               if (is_debug) {
-                       prefix2str(&route->prefix, buf, sizeof(buf));
-                       zlog_debug("Originating summary in area %s for %s cost %u",
-                                  area->name, buf, route->path.cost);
-               }
+               if (is_debug)
+                       zlog_debug(
+                               "Originating summary in area %s for %pFX cost %u",
+                               area->name, &route->prefix, route->path.cost);
                summary_table = area->summary_prefix;
        }
 
@@ -284,10 +273,11 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                                                "The range is not active. withdraw");
 
                                ospf6_abr_delete_route(route, summary,
-                                                      summary_table, old);
+                                                      summary_table, old,
+                                                      area->ospf6);
                        }
                } else if (old) {
-                       ospf6_route_remove(summary, summary_table);
+                       ospf6_route_remove(summary, summary_table, area->ospf6);
                        ospf6_lsa_purge(old);
                }
                return 0;
@@ -298,7 +288,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                        zlog_debug(
                                "Area has been stubbed, purge Inter-Router LSA");
 
-               ospf6_abr_delete_route(route, summary, summary_table, old);
+               ospf6_abr_delete_route(route, summary, summary_table, old,
+                                      area->ospf6);
                return 0;
        }
 
@@ -307,7 +298,8 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                if (is_debug)
                        zlog_debug("Area has been stubbed, purge prefix LSA");
 
-               ospf6_abr_delete_route(route, summary, summary_table, old);
+               ospf6_abr_delete_route(route, summary, summary_table, old,
+                                      area->ospf6);
                return 0;
        }
 
@@ -343,7 +335,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                                zlog_debug(
                                        "This is the secondary path to the ASBR, ignore");
                        ospf6_abr_delete_route(route, summary, summary_table,
-                                              old);
+                                              old, area->ospf6);
                        return 0;
                }
 
@@ -369,13 +361,12 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                if (range && !CHECK_FLAG(range->flag, OSPF6_ROUTE_REMOVE)
                    && (route->path.area_id != OSPF_AREA_BACKBONE
                        || !IS_AREA_TRANSIT(area))) {
-                       if (is_debug) {
-                               prefix2str(&range->prefix, buf, sizeof(buf));
-                               zlog_debug("Suppressed by range %s of area %s",
-                                          buf, route_area->name);
-                       }
+                       if (is_debug)
+                               zlog_debug(
+                                       "Suppressed by range %pFX of area %s",
+                                       &range->prefix, route_area->name);
                        ospf6_abr_delete_route(route, summary, summary_table,
-                                              old);
+                                              old, area->ospf6);
                        return 0;
                }
        }
@@ -388,7 +379,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                                zlog_debug(
                                        "This is the range with DoNotAdvertise set. ignore");
                        ospf6_abr_delete_route(route, summary, summary_table,
-                                              old);
+                                              old, area->ospf6);
                        return 0;
                }
 
@@ -397,7 +388,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                        if (is_debug)
                                zlog_debug("The range is not active. withdraw");
                        ospf6_abr_delete_route(route, summary, summary_table,
-                                              old);
+                                              old, area->ospf6);
                        return 0;
                }
        }
@@ -411,15 +402,11 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                if (EXPORT_LIST(area))
                        if (access_list_apply(EXPORT_LIST(area), &route->prefix)
                            == FILTER_DENY) {
-                               if (is_debug) {
-                                       inet_ntop(AF_INET,
-                                                 &(ADV_ROUTER_IN_PREFIX(
-                                                         &route->prefix)),
-                                                 buf, sizeof(buf));
+                               if (is_debug)
                                        zlog_debug(
-                                               "prefix %s was denied by export list",
-                                               buf);
-                               }
+                                               "prefix %pFX was denied by export list",
+                                               &ADV_ROUTER_IN_PREFIX(
+                                                       &route->prefix));
                                return 0;
                        }
        }
@@ -428,15 +415,10 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
        if (PREFIX_LIST_OUT(area))
                if (prefix_list_apply(PREFIX_LIST_OUT(area), &route->prefix)
                    != PREFIX_PERMIT) {
-                       if (is_debug) {
-                               inet_ntop(
-                                       AF_INET,
-                                       &(ADV_ROUTER_IN_PREFIX(&route->prefix)),
-                                       buf, sizeof(buf));
+                       if (is_debug)
                                zlog_debug(
-                                       "prefix %s was denied by filter-list out",
-                                       buf);
-                       }
+                                       "prefix %pFX was denied by filter-list out",
+                                       &ADV_ROUTER_IN_PREFIX(&route->prefix));
                        return 0;
                }
 
@@ -458,7 +440,7 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                                summary->path.origin.type,
                                summary->path.origin.adv_router, area->lsdb);
                }
-               summary = ospf6_route_add(summary, summary_table);
+               summary = ospf6_route_add(summary, summary_table, area->ospf6);
        } else {
                summary->type = route->type;
                monotime(&summary->changed);
@@ -597,7 +579,8 @@ ospf6_abr_range_summary_needs_update(struct ospf6_route *range, uint32_t cost)
        return (redo_summary);
 }
 
-static void ospf6_abr_range_update(struct ospf6_route *range)
+static void ospf6_abr_range_update(struct ospf6_route *range,
+                                  struct ospf6 *ospf6)
 {
        uint32_t cost = 0;
        struct listnode *node, *nnode;
@@ -636,7 +619,7 @@ static void ospf6_abr_range_update(struct ospf6_route *range)
                                if (IS_OSPF6_DEBUG_ABR)
                                        zlog_debug("Add discard route");
 
-                               ospf6_zebra_add_discard(range);
+                               ospf6_zebra_add_discard(range, ospf6);
                        }
                } else {
                        /* Summary removed or no summary generated as no
@@ -646,18 +629,19 @@ static void ospf6_abr_range_update(struct ospf6_route *range)
                                if (IS_OSPF6_DEBUG_ABR)
                                        zlog_debug("Delete discard route");
 
-                               ospf6_zebra_delete_discard(range);
+                               ospf6_zebra_delete_discard(range, ospf6);
                        }
                }
        }
 }
 
-void ospf6_abr_originate_summary(struct ospf6_route *route)
+void ospf6_abr_originate_summary(struct ospf6_route *route, struct ospf6 *ospf6)
 {
        struct listnode *node, *nnode;
        struct ospf6_area *oa;
        struct ospf6_route *range = NULL;
 
+
        if (route->type == OSPF6_DEST_TYPE_NETWORK) {
                oa = ospf6_area_lookup(route->path.area_id, ospf6);
                if (!oa) {
@@ -668,7 +652,7 @@ void ospf6_abr_originate_summary(struct ospf6_route *route)
                range = ospf6_route_lookup_bestmatch(&route->prefix,
                                                     oa->range_table);
                if (range) {
-                       ospf6_abr_range_update(range);
+                       ospf6_abr_range_update(range, ospf6);
                }
        }
 
@@ -695,7 +679,7 @@ void ospf6_abr_defaults_to_stub(struct ospf6 *o)
        def->path.subtype = OSPF6_PATH_SUBTYPE_DEFAULT_RT;
        def->path.area_id = o->backbone->area_id;
 
-       for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa)) {
+       for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa)) {
                if (!IS_AREA_STUB(oa)) {
                        /* withdraw defaults when an area switches from stub to
                         * non-stub */
@@ -725,7 +709,8 @@ void ospf6_abr_defaults_to_stub(struct ospf6 *o)
 
 void ospf6_abr_old_path_update(struct ospf6_route *old_route,
                               struct ospf6_route *route,
-                              struct ospf6_route_table *table)
+                              struct ospf6_route_table *table,
+                              struct ospf6 *ospf6)
 {
        struct ospf6_path *o_path = NULL;
        struct listnode *anode, *anext;
@@ -772,7 +757,7 @@ void ospf6_abr_old_path_update(struct ospf6_route *old_route,
                                           : 0);
 
                if (table->hook_add)
-                       (*table->hook_add)(old_route);
+                       (*table->hook_add)(old_route, ospf6);
 
                if (old_route->path.origin.id == route->path.origin.id &&
                    old_route->path.origin.adv_router ==
@@ -789,16 +774,15 @@ void ospf6_abr_old_path_update(struct ospf6_route *old_route,
        }
 }
 
-void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa,
-                               struct ospf6_route *old,
-                               struct ospf6_route_table *table)
+void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old,
+                               struct ospf6_route_table *table,
+                               struct ospf6 *ospf6)
 {
        if (listcount(old->paths) > 1) {
                struct listnode *anode, *anext, *nnode, *rnode, *rnext;
                struct ospf6_path *o_path;
                struct ospf6_nexthop *nh, *rnh;
                bool nh_updated = false;
-               char buf[PREFIX2STR_BUFFER];
 
                for (ALL_LIST_ELEMENTS(old->paths, anode, anext, o_path)) {
                        if (o_path->origin.adv_router != lsa->header->adv_router
@@ -820,19 +804,16 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa,
 
                if (nh_updated) {
                        if (listcount(old->paths)) {
-                               if (IS_OSPF6_DEBUG_ABR ||
-                                   IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX)) {
-                                       prefix2str(&old->prefix, buf,
-                                                  sizeof(buf));
-                                       zlog_debug("%s: old %s updated nh %u",
-                                                  __func__, buf,
+                               if (IS_OSPF6_DEBUG_ABR
+                                   || IS_OSPF6_DEBUG_EXAMIN(INTER_PREFIX))
+                                       zlog_debug("%s: old %pFX updated nh %u",
+                                                  __func__, &old->prefix,
                                                   old->nh_list ? listcount(
                                                           old->nh_list)
                                                                : 0);
-                               }
 
                                if (table->hook_add)
-                                       (*table->hook_add)(old);
+                                       (*table->hook_add)(old, ospf6);
 
                                if ((old->path.origin.id == lsa->header->id) &&
                                    (old->path.origin.adv_router
@@ -849,11 +830,10 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa,
                                                h_path->origin.adv_router;
                                }
                        } else
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, ospf6);
                }
        } else
-               ospf6_route_remove(old, table);
-
+               ospf6_route_remove(old, table, ospf6);
 }
 
 /* RFC 2328 16.2. Calculating the inter-area routes */
@@ -968,7 +948,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                if (is_debug)
                        zlog_debug("cost is LS_INFINITY, ignore");
                if (old)
-                       ospf6_abr_old_route_remove(lsa, old, table);
+                       ospf6_abr_old_route_remove(lsa, old, table, oa->ospf6);
                return;
        }
        if (OSPF6_LSA_IS_MAXAGE(lsa)) {
@@ -976,7 +956,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        zlog_debug("%s: LSA %s is MaxAge, ignore", __func__,
                                   lsa->name);
                if (old)
-                       ospf6_abr_old_route_remove(lsa, old, table);
+                       ospf6_abr_old_route_remove(lsa, old, table, oa->ospf6);
                return;
        }
 
@@ -986,7 +966,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        zlog_debug("LSA %s is self-originated, ignore",
                                   lsa->name);
                if (old)
-                       ospf6_route_remove(old, table);
+                       ospf6_route_remove(old, table, oa->ospf6);
                return;
        }
 
@@ -1002,7 +982,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                                zlog_debug(
                                        "Prefix is equal to address range, ignore");
                        if (old)
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, oa->ospf6);
                        return;
                }
 
@@ -1013,7 +993,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        if (is_debug)
                                zlog_debug("Prefix has NU/LA bit set, ignore");
                        if (old)
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, oa->ospf6);
                        return;
                }
        }
@@ -1026,7 +1006,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        if (is_debug)
                                zlog_debug("Prefix has NU/LA bit set, ignore");
                        if (old)
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, oa->ospf6);
 
                        return;
                }
@@ -1040,7 +1020,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                                        "Ignorning Inter-Router LSA for an ABR (%s)",
                                        buf);
                        if (old)
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, oa->ospf6);
 
                        return;
                }
@@ -1068,7 +1048,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                                        zlog_debug(
                                                "%s: remove old entry: %s %p ",
                                                __func__, buf, (void *)old);
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, oa->ospf6);
                        }
                }
                return;
@@ -1087,7 +1067,8 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                                        zlog_debug(
                                                "Prefix was denied by import-list");
                                if (old)
-                                       ospf6_route_remove(old, table);
+                                       ospf6_route_remove(old, table,
+                                                          oa->ospf6);
                                return;
                        }
        }
@@ -1099,7 +1080,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        if (is_debug)
                                zlog_debug("Prefix was denied by prefix-list");
                        if (old)
-                               ospf6_route_remove(old, table);
+                               ospf6_route_remove(old, table, oa->ospf6);
                        return;
                }
        }
@@ -1140,13 +1121,11 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                        continue;
 
                if ((ospf6_route_cmp(route, old_route) != 0)) {
-                       if (is_debug) {
-                               prefix2str(&prefix, buf, sizeof(buf));
+                       if (is_debug)
                                zlog_debug(
-                                       "%s: old %p %s cost %u new route cost %u are not same",
-                                       __func__, (void *)old_route, buf,
+                                       "%s: old %p %pFX cost %u new route cost %u are not same",
+                                       __func__, (void *)old_route, &prefix,
                                        old_route->path.cost, route->path.cost);
-                       }
 
                        /* Check new route's adv. router is same in one of
                         * the paths with differed cost, if so remove the
@@ -1154,7 +1133,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                         */
                        if (listcount(old_route->paths) > 1)
                                ospf6_abr_old_path_update(old_route, route,
-                                                         table);
+                                                         table, oa->ospf6);
                        continue;
                }
 
@@ -1222,7 +1201,7 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                 * For Inter-Router trigger summary update
                 */
                if (table->hook_add)
-                       (*table->hook_add)(old_route);
+                       (*table->hook_add)(old_route, oa->ospf6);
 
                /* Delete new route */
                ospf6_route_delete(route);
@@ -1241,23 +1220,19 @@ void ospf6_abr_examin_summary(struct ospf6_lsa *lsa, struct ospf6_area *oa)
                path = ospf6_path_dup(&route->path);
                ospf6_copy_nexthops(path->nh_list, abr_entry->nh_list);
                listnode_add_sort(route->paths, path);
-
                /* ospf6_ia_add_nw_route (table, &prefix, route); */
-               ospf6_route_add(route, table);
+               ospf6_route_add(route, table, oa->ospf6);
        }
 }
 
-void ospf6_abr_examin_brouter(uint32_t router_id)
+void ospf6_abr_examin_brouter(uint32_t router_id, struct ospf6_route *route,
+                             struct ospf6 *ospf6)
 {
        struct ospf6_lsa *lsa;
        struct ospf6_area *oa;
        uint16_t type;
 
-       if (ospf6_is_router_abr(ospf6))
-               oa = ospf6->backbone;
-       else
-               oa = listgetdata(listhead(ospf6->area_list));
-
+       oa = ospf6_area_lookup(route->path.area_id, ospf6);
        /*
         * It is possible to designate a non backbone
         * area first.  If that is the case safely
@@ -1298,7 +1273,7 @@ void ospf6_abr_prefix_resummarize(struct ospf6 *o)
 
        for (route = ospf6_route_head(o->route_table); route;
             route = ospf6_route_next(route))
-               ospf6_abr_originate_summary(route);
+               ospf6_abr_originate_summary(route, o);
 
        if (IS_OSPF6_DEBUG_ABR)
                zlog_debug("Finished re-examining Inter-Prefix Summaries");
index e40d155037f3ac2cac37a26fde505d134f8ad374..8ad51a4f8202b33943c608a400d3c415c2ac8d0e 100644 (file)
@@ -64,11 +64,14 @@ extern void ospf6_abr_disable_area(struct ospf6_area *oa);
 
 extern int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
                                               struct ospf6_area *area);
-extern void ospf6_abr_originate_summary(struct ospf6_route *route);
+extern void ospf6_abr_originate_summary(struct ospf6_route *route,
+                                       struct ospf6 *ospf6);
 extern void ospf6_abr_examin_summary(struct ospf6_lsa *lsa,
                                     struct ospf6_area *oa);
 extern void ospf6_abr_defaults_to_stub(struct ospf6 *);
-extern void ospf6_abr_examin_brouter(uint32_t router_id);
+extern void ospf6_abr_examin_brouter(uint32_t router_id,
+                                    struct ospf6_route *route,
+                                    struct ospf6 *ospf6);
 extern void ospf6_abr_reimport(struct ospf6_area *oa);
 extern void ospf6_abr_range_reset_cost(struct ospf6 *ospf6);
 extern void ospf6_abr_prefix_resummarize(struct ospf6 *ospf6);
@@ -78,10 +81,12 @@ extern void install_element_ospf6_debug_abr(void);
 extern int ospf6_abr_config_write(struct vty *vty);
 extern void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa,
                                       struct ospf6_route *old,
-                                      struct ospf6_route_table *table);
+                                      struct ospf6_route_table *table,
+                                      struct ospf6 *ospf6);
 extern void ospf6_abr_old_path_update(struct ospf6_route *old_route,
                                      struct ospf6_route *route,
-                                     struct ospf6_route_table *table);
+                                     struct ospf6_route_table *table,
+                                     struct ospf6 *ospf6);
 extern void ospf6_abr_init(void);
 
 #endif /*OSPF6_ABR_H*/
index 713ce26ecb6184c3ea78e29de67271c7e1dc4c4b..e98764cd26d61130663e099d8d14ebb3b967a5d9 100644 (file)
@@ -115,21 +115,23 @@ static void ospf6_area_lsdb_hook_remove(struct ospf6_lsa *lsa)
        }
 }
 
-static void ospf6_area_route_hook_add(struct ospf6_route *route)
+static void ospf6_area_route_hook_add(struct ospf6_route *route,
+                                     struct ospf6 *ospf6)
 {
        struct ospf6_route *copy;
 
        copy = ospf6_route_copy(route);
-       ospf6_route_add(copy, ospf6->route_table);
+       ospf6_route_add(copy, ospf6->route_table, ospf6);
 }
 
-static void ospf6_area_route_hook_remove(struct ospf6_route *route)
+static void ospf6_area_route_hook_remove(struct ospf6_route *route,
+                                        struct ospf6 *ospf6)
 {
        struct ospf6_route *copy;
 
        copy = ospf6_route_lookup_identical(route, ospf6->route_table);
        if (copy)
-               ospf6_route_remove(copy, ospf6->route_table);
+               ospf6_route_remove(copy, ospf6->route_table, ospf6);
 }
 
 static void ospf6_area_stub_update(struct ospf6_area *area)
@@ -282,13 +284,13 @@ void ospf6_area_delete(struct ospf6_area *oa)
        ospf6_lsdb_delete(oa->lsdb_self);
        ospf6_lsdb_delete(oa->temp_router_lsa_lsdb);
 
-       ospf6_spf_table_finish(oa->spf_table);
-       ospf6_route_table_delete(oa->spf_table);
-       ospf6_route_table_delete(oa->route_table);
+       ospf6_spf_table_finish(oa->spf_table, oa->ospf6);
+       ospf6_route_table_delete(oa->spf_table, oa->ospf6);
+       ospf6_route_table_delete(oa->route_table, oa->ospf6);
 
-       ospf6_route_table_delete(oa->range_table);
-       ospf6_route_table_delete(oa->summary_prefix);
-       ospf6_route_table_delete(oa->summary_router);
+       ospf6_route_table_delete(oa->range_table, oa->ospf6);
+       ospf6_route_table_delete(oa->summary_prefix, oa->ospf6);
+       ospf6_route_table_delete(oa->summary_router, oa->ospf6);
 
        listnode_delete(oa->ospf6->area_list, oa);
        oa->ospf6 = NULL;
@@ -297,6 +299,20 @@ void ospf6_area_delete(struct ospf6_area *oa)
        XFREE(MTYPE_OSPF6_AREA, oa);
 }
 
+struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id)
+{
+       struct ospf6_area *oa;
+       struct listnode *n, *node, *nnode;
+       struct ospf6 *ospf6;
+
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa))
+                       if (oa->area_id == area_id)
+                               return oa;
+       }
+       return (struct ospf6_area *)NULL;
+}
+
 struct ospf6_area *ospf6_area_lookup(uint32_t area_id, struct ospf6 *ospf6)
 {
        struct ospf6_area *oa;
@@ -335,8 +351,8 @@ void ospf6_area_disable(struct ospf6_area *oa)
        ospf6_lsdb_remove_all(oa->lsdb);
        ospf6_lsdb_remove_all(oa->lsdb_self);
 
-       ospf6_spf_table_finish(oa->spf_table);
-       ospf6_route_remove_all(oa->route_table);
+       ospf6_spf_table_finish(oa->spf_table, oa->ospf6);
+       ospf6_route_remove_all(oa->route_table, oa->ospf6);
 
        THREAD_OFF(oa->thread_router_lsa);
        THREAD_OFF(oa->thread_intra_prefix_lsa);
@@ -401,7 +417,9 @@ DEFUN (area_range,
        struct ospf6_route *range;
        uint32_t cost = OSPF_AREA_RANGE_COST_UNSPEC;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
 
        ret = str2prefix(argv[idx_ipv6_prefixlen]->arg, &prefix);
        if (ret != 1 || prefix.family != AF_INET6) {
@@ -436,7 +454,7 @@ DEFUN (area_range,
        zlog_debug("%s: for prefix %s, flag = %x", __func__,
                   argv[idx_ipv6_prefixlen]->arg, range->flag);
        if (range->rnode == NULL) {
-               ospf6_route_add(range, oa->range_table);
+               ospf6_route_add(range, oa->range_table, oa->ospf6);
        }
 
        if (ospf6_is_router_abr(ospf6)) {
@@ -468,7 +486,9 @@ DEFUN (no_area_range,
        struct prefix prefix;
        struct ospf6_route *range, *route;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
 
        ret = str2prefix(argv[idx_ipv6]->arg, &prefix);
        if (ret != 1 || prefix.family != AF_INET6) {
@@ -488,30 +508,29 @@ DEFUN (no_area_range,
                SET_FLAG(range->flag, OSPF6_ROUTE_REMOVE);
 
                /* Redo summaries if required */
-               for (route = ospf6_route_head(ospf6->route_table); route;
+               for (route = ospf6_route_head(oa->ospf6->route_table); route;
                     route = ospf6_route_next(route))
-                       ospf6_abr_originate_summary(route);
+                       ospf6_abr_originate_summary(route, oa->ospf6);
 
                /* purge the old aggregated summary LSA */
-               ospf6_abr_originate_summary(range);
+               ospf6_abr_originate_summary(range, oa->ospf6);
        }
-       ospf6_route_remove(range, oa->range_table);
+       ospf6_route_remove(range, oa->range_table, oa->ospf6);
 
        return CMD_SUCCESS;
 }
 
-void ospf6_area_config_write(struct vty *vty)
+void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6)
 {
        struct listnode *node;
        struct ospf6_area *oa;
        struct ospf6_route *range;
-       char buf[PREFIX2STR_BUFFER];
 
        for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
                for (range = ospf6_route_head(oa->range_table); range;
                     range = ospf6_route_next(range)) {
-                       prefix2str(&range->prefix, buf, sizeof(buf));
-                       vty_out(vty, " area %s range %s", oa->name, buf);
+                       vty_out(vty, " area %s range %pFX", oa->name,
+                               &range->prefix);
 
                        if (CHECK_FLAG(range->flag,
                                       OSPF6_ROUTE_DO_NOT_ADVERTISE)) {
@@ -567,7 +586,9 @@ DEFUN (area_filter_list,
        struct ospf6_area *area;
        struct prefix_list *plist;
 
-       OSPF6_CMD_AREA_GET(areaid, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(areaid, area, ospf6);
 
        plist = prefix_list_lookup(AFI_IP6, plistname);
        if (strmatch(inout, "in")) {
@@ -606,7 +627,8 @@ DEFUN (no_area_filter_list,
 
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(areaid, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+       OSPF6_CMD_AREA_GET(areaid, area, ospf6);
 
        if (strmatch(inout, "in")) {
                if (PREFIX_NAME_IN(area))
@@ -630,18 +652,25 @@ DEFUN (no_area_filter_list,
 
 void ospf6_area_plist_update(struct prefix_list *plist, int add)
 {
+       struct listnode *node, *nnode;
        struct ospf6_area *oa;
        struct listnode *n;
        const char *name = prefix_list_name(plist);
+       struct ospf6 *ospf6 = NULL;
+
 
-       if (!ospf6)
+       if (!om6->ospf6)
                return;
 
-       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) {
-               if (PREFIX_NAME_IN(oa) && !strcmp(PREFIX_NAME_IN(oa), name))
-                       PREFIX_LIST_IN(oa) = add ? plist : NULL;
-               if (PREFIX_NAME_OUT(oa) && !strcmp(PREFIX_NAME_OUT(oa), name))
-                       PREFIX_LIST_OUT(oa) = add ? plist : NULL;
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, n, oa)) {
+                       if (PREFIX_NAME_IN(oa)
+                           && !strcmp(PREFIX_NAME_IN(oa), name))
+                               PREFIX_LIST_IN(oa) = add ? plist : NULL;
+                       if (PREFIX_NAME_OUT(oa)
+                           && !strcmp(PREFIX_NAME_OUT(oa), name))
+                               PREFIX_LIST_OUT(oa) = add ? plist : NULL;
+               }
        }
 }
 
@@ -659,7 +688,9 @@ DEFUN (area_import_list,
        struct ospf6_area *area;
        struct access_list *list;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6);
 
        list = access_list_lookup(AFI_IP6, argv[idx_name]->arg);
 
@@ -687,7 +718,9 @@ DEFUN (no_area_import_list,
        int idx_ipv4 = 2;
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6);
 
        IMPORT_LIST(area) = 0;
 
@@ -714,7 +747,9 @@ DEFUN (area_export_list,
        struct ospf6_area *area;
        struct access_list *list;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6);
 
        list = access_list_lookup(AFI_IP6, argv[idx_name]->arg);
 
@@ -742,7 +777,9 @@ DEFUN (no_area_export_list,
        int idx_ipv4 = 2;
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, area, ospf6);
 
        EXPORT_LIST(area) = 0;
 
@@ -769,9 +806,10 @@ DEFUN (show_ipv6_ospf6_spf_tree,
        struct ospf6_vertex *root;
        struct ospf6_route *route;
        struct prefix prefix;
+       struct ospf6 *ospf6;
 
-       OSPF6_CMD_CHECK_RUNNING();
-
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix);
 
        for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
@@ -805,8 +843,11 @@ DEFUN (show_ipv6_ospf6_area_spf_tree,
        struct ospf6_vertex *root;
        struct ospf6_route *route;
        struct prefix prefix;
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
 
-       OSPF6_CMD_CHECK_RUNNING();
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        ospf6_linkstate_prefix(ospf6->router_id, htonl(0), &prefix);
 
@@ -854,8 +895,11 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
        uint32_t router_id;
        struct ospf6_route_table *spf_table;
        unsigned char tmp_debug_ospf6_spf = 0;
+       struct ospf6 *ospf6;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id);
        ospf6_linkstate_prefix(router_id, htonl(0), &prefix);
@@ -880,15 +924,15 @@ DEFUN (show_ipv6_ospf6_simulate_spf_tree_root,
 
        route = ospf6_route_lookup(&prefix, spf_table);
        if (route == NULL) {
-               ospf6_spf_table_finish(spf_table);
-               ospf6_route_table_delete(spf_table);
+               ospf6_spf_table_finish(spf_table, ospf6);
+               ospf6_route_table_delete(spf_table, ospf6);
                return CMD_SUCCESS;
        }
        root = (struct ospf6_vertex *)route->route_option;
        ospf6_spf_display_subtree(vty, "", 0, root);
 
-       ospf6_spf_table_finish(spf_table);
-       ospf6_route_table_delete(spf_table);
+       ospf6_spf_table_finish(spf_table, ospf6);
+       ospf6_route_table_delete(spf_table, ospf6);
 
        return CMD_SUCCESS;
 }
@@ -904,7 +948,9 @@ DEFUN (ospf6_area_stub,
        int idx_ipv4_number = 1;
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6);
 
        if (!ospf6_area_stub_set(ospf6, area)) {
                vty_out(vty,
@@ -929,7 +975,9 @@ DEFUN (ospf6_area_stub_no_summary,
        int idx_ipv4_number = 1;
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6);
 
        if (!ospf6_area_stub_set(ospf6, area)) {
                vty_out(vty,
@@ -954,7 +1002,9 @@ DEFUN (no_ospf6_area_stub,
        int idx_ipv4_number = 2;
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6);
 
        ospf6_area_stub_unset(ospf6, area);
        ospf6_area_no_summary_unset(ospf6, area);
@@ -975,7 +1025,9 @@ DEFUN (no_ospf6_area_stub_no_summary,
        int idx_ipv4_number = 2;
        struct ospf6_area *area;
 
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area);
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4_number]->arg, area, ospf6);
 
        ospf6_area_stub_unset(ospf6, area);
        ospf6_area_no_summary_unset(ospf6, area);
@@ -1010,11 +1062,12 @@ void ospf6_area_interface_delete(struct ospf6_interface *oi)
 {
        struct ospf6_area *oa;
        struct listnode *node, *nnode;
+       struct ospf6 *ospf6;
 
-       if (!ospf6)
+       if (!om6->ospf6)
                return;
-       for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
-               if(listnode_lookup(oa->if_list, oi))
-                       listnode_delete(oa->if_list, oi);
-
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6))
+               for (ALL_LIST_ELEMENTS(ospf6->area_list, node, nnode, oa))
+                       if (listnode_lookup(oa->if_list, oi))
+                               listnode_delete(oa->if_list, oi);
 }
index f6287660d6972ddd86fe6c48f2818c4e4b8d91f9..2097ef6e43c61ec4d59da7068457664b01457077 100644 (file)
@@ -117,7 +117,7 @@ struct ospf6_area {
 #define IS_AREA_TRANSIT(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_TRANSIT))
 #define IS_AREA_STUB(oa) (CHECK_FLAG ((oa)->flag, OSPF6_AREA_STUB))
 
-#define OSPF6_CMD_AREA_GET(str, oa)                                            \
+#define OSPF6_CMD_AREA_GET(str, oa, ospf6)                                     \
        {                                                                      \
                char *ep;                                                      \
                uint32_t area_id = htonl(strtoul(str, &ep, 10));               \
@@ -138,6 +138,7 @@ extern int ospf6_area_cmp(void *va, void *vb);
 extern struct ospf6_area *ospf6_area_create(uint32_t, struct ospf6 *, int);
 extern void ospf6_area_delete(struct ospf6_area *);
 extern struct ospf6_area *ospf6_area_lookup(uint32_t, struct ospf6 *);
+extern struct ospf6_area *ospf6_area_lookup_by_area_id(uint32_t area_id);
 
 extern void ospf6_area_enable(struct ospf6_area *);
 extern void ospf6_area_disable(struct ospf6_area *);
@@ -145,7 +146,7 @@ extern void ospf6_area_disable(struct ospf6_area *);
 extern void ospf6_area_show(struct vty *, struct ospf6_area *);
 
 extern void ospf6_area_plist_update(struct prefix_list *plist, int add);
-extern void ospf6_area_config_write(struct vty *vty);
+extern void ospf6_area_config_write(struct vty *vty, struct ospf6 *ospf6);
 extern void ospf6_area_init(void);
 struct ospf6_interface;
 extern void ospf6_area_interface_delete(struct ospf6_interface *oi);
index 71ca5afcd22d06e395611696e296a6cd624f5f37..c053716f26c8e792440db7543e2f1d522ebe41f7 100644 (file)
@@ -43,6 +43,7 @@
 #include "ospf6_interface.h"
 #include "ospf6_neighbor.h"
 #include "ospf6_asbr.h"
+#include "ospf6_abr.h"
 #include "ospf6_intra.h"
 #include "ospf6_flood.h"
 #include "ospf6d.h"
@@ -55,7 +56,8 @@ unsigned char conf_debug_ospf6_asbr = 0;
 #define ZROUTE_NAME(x) zebra_route_string(x)
 
 /* AS External LSA origination */
-static void ospf6_as_external_lsa_originate(struct ospf6_route *route)
+static void ospf6_as_external_lsa_originate(struct ospf6_route *route,
+                                           struct ospf6 *ospf6)
 {
        char buffer[OSPF6_MAX_LSASIZE];
        struct ospf6_lsa_header *lsa_header;
@@ -63,13 +65,11 @@ static void ospf6_as_external_lsa_originate(struct ospf6_route *route)
        struct ospf6_external_info *info = route->route_option;
 
        struct ospf6_as_external_lsa *as_external_lsa;
-       char buf[PREFIX2STR_BUFFER];
        caddr_t p;
 
-       if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE(AS_EXTERNAL)) {
-               prefix2str(&route->prefix, buf, sizeof(buf));
-               zlog_debug("Originate AS-External-LSA for %s", buf);
-       }
+       if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE(AS_EXTERNAL))
+               zlog_debug("Originate AS-External-LSA for %pFX",
+                          &route->prefix);
 
        /* prepare buffer */
        memset(buffer, 0, sizeof(buffer));
@@ -165,7 +165,8 @@ int ospf6_orig_as_external_lsa(struct thread *thread)
 
        type = htons(OSPF6_LSTYPE_AS_EXTERNAL);
        adv_router = oi->area->ospf6->router_id;
-       for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, adv_router, lsa)) {
+       for (ALL_LSDB_TYPED_ADVRTR(oi->area->ospf6->lsdb, type, adv_router,
+                                  lsa)) {
                if (IS_OSPF6_DEBUG_ASBR)
                        zlog_debug(
                                "%s: Send update of AS-External LSA %s seq 0x%x",
@@ -204,14 +205,14 @@ static route_tag_t ospf6_as_external_lsa_get_tag(struct ospf6_lsa *lsa)
 }
 
 void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
-                                      struct ospf6_route *route)
+                                      struct ospf6_route *route,
+                                      struct ospf6 *ospf6)
 {
        struct ospf6_route *old_route;
        struct ospf6_path *ecmp_path, *o_path = NULL;
        struct listnode *anode, *anext;
        struct listnode *nnode, *rnode, *rnext;
        struct ospf6_nexthop *nh, *rnh;
-       char buf[PREFIX2STR_BUFFER];
        bool route_found = false;
 
        /* check for old entry match with new route origin,
@@ -284,8 +285,8 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                 * nh_list
                                 */
                                if (ospf6->route_table->hook_add)
-                                       (*ospf6->route_table->hook_add)
-                                               (old_route);
+                                       (*ospf6->route_table->hook_add)(
+                                               old_route, ospf6);
 
                                if (old_route->path.origin.id
                                            == route->path.origin.id
@@ -313,7 +314,7 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                                route->path.cost);
                                }
                                ospf6_route_remove(old_route,
-                                                  ospf6->route_table);
+                                                  ospf6->route_table, ospf6);
                        }
                }
                if (route_updated)
@@ -371,11 +372,9 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                listnode_add_sort(old_route->paths, ecmp_path);
 
                                if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
-                                       prefix2str(&route->prefix, buf,
-                                                  sizeof(buf));
                                        zlog_debug(
-                                               "%s: route %s another path added with nh %u, effective paths %u nh %u",
-                                               __func__, buf,
+                                               "%s: route %pFX another path added with nh %u, effective paths %u nh %u",
+                                               __func__, &route->prefix,
                                                listcount(ecmp_path->nh_list),
                                                old_route->paths ? listcount(
                                                        old_route->paths)
@@ -401,36 +400,32 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                                        &o_path->ls_prefix,
                                                        ospf6->brouter_table);
                                if (asbr_entry == NULL) {
-                                       if (IS_OSPF6_DEBUG_EXAMIN(
-                                                       AS_EXTERNAL)) {
-                                               prefix2str(&old_route->prefix,
-                                                          buf, sizeof(buf));
+                                       if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL))
                                                zlog_debug(
-                                                       "%s: ls_prfix %s asbr_entry not found.",
-                                                       __func__, buf);
-                                       }
+                                                       "%s: ls_prfix %pFX asbr_entry not found.",
+                                                       __func__,
+                                                       &old_route->prefix);
                                        continue;
                                }
                                ospf6_route_merge_nexthops(old_route,
                                                           asbr_entry);
                        }
 
-                       if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
-                               prefix2str(&route->prefix, buf, sizeof(buf));
+                       if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL))
                                zlog_debug(
-                                       "%s: route %s with effective paths %u nh %u",
-                                       __func__, buf,
+                                       "%s: route %pFX with effective paths %u nh %u",
+                                       __func__, &route->prefix,
                                        old_route->paths
                                                ? listcount(old_route->paths)
                                                : 0,
                                        old_route->nh_list
                                                ? listcount(old_route->nh_list)
                                                : 0);
-                       }
 
                        /* Update RIB/FIB */
                        if (ospf6->route_table->hook_add)
-                               (*ospf6->route_table->hook_add)(old_route);
+                               (*ospf6->route_table->hook_add)(old_route,
+                                                               ospf6);
 
                        /* Delete the new route its info added to existing
                         * route.
@@ -443,17 +438,16 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
 
        if (!route_found) {
                /* Add new route to existing node in ospf6 route table. */
-               ospf6_route_add(route, ospf6->route_table);
+               ospf6_route_add(route, ospf6->route_table, ospf6);
        }
 }
 
-void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa)
+void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6)
 {
        struct ospf6_as_external_lsa *external;
        struct prefix asbr_id;
        struct ospf6_route *asbr_entry, *route, *old;
        struct ospf6_path *path;
-       char buf[PREFIX2STR_BUFFER];
 
        external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END(
                lsa->header);
@@ -484,10 +478,8 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa)
        asbr_entry = ospf6_route_lookup(&asbr_id, ospf6->brouter_table);
        if (asbr_entry == NULL
            || !CHECK_FLAG(asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E)) {
-               if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
-                       prefix2str(&asbr_id, buf, sizeof(buf));
-                       zlog_debug("ASBR entry not found: %s", buf);
-               }
+               if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL))
+                       zlog_debug("ASBR entry not found: %pFX", &asbr_id);
                return;
        }
 
@@ -527,27 +519,25 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa)
        listnode_add_sort(route->paths, path);
 
 
-       if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
-               prefix2str(&route->prefix, buf, sizeof(buf));
-               zlog_debug("%s: AS-External %u route add %s cost %u(%u) nh %u",
-                          __func__,
-                          (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1) ? 1
-                                                                          : 2,
-                          buf, route->path.cost, route->path.u.cost_e2,
-                          listcount(route->nh_list));
-       }
+       if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL))
+               zlog_debug(
+                       "%s: AS-External %u route add %pFX cost %u(%u) nh %u",
+                       __func__,
+                       (route->path.type == OSPF6_PATH_TYPE_EXTERNAL1) ? 1 : 2,
+                       &route->prefix, route->path.cost, route->path.u.cost_e2,
+                       listcount(route->nh_list));
 
        old = ospf6_route_lookup(&route->prefix, ospf6->route_table);
        if (!old) {
                /* Add the new route to ospf6 instance route table. */
-               ospf6_route_add(route, ospf6->route_table);
+               ospf6_route_add(route, ospf6->route_table, ospf6);
        } else {
                /* RFC 2328 16.4 (6)
                 * ECMP: Keep new equal preference path in current
                 * route's path list, update zebra with new effective
                 * list along with addition of ECMP path.
                 */
-               ospf6_asbr_update_route_ecmp_path(old, route);
+               ospf6_asbr_update_route_ecmp_path(old, route, ospf6);
        }
 }
 
@@ -557,6 +547,8 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        struct ospf6_as_external_lsa *external;
        struct prefix prefix;
        struct ospf6_route *route, *nroute, *route_to_del;
+       struct ospf6_area *oa = NULL;
+       struct ospf6 *ospf6;
 
        external = (struct ospf6_as_external_lsa *)OSPF6_LSA_HEADER_END(
                lsa->header);
@@ -564,7 +556,16 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL))
                zlog_debug("Withdraw AS-External route for %s", lsa->name);
 
-       if (lsa->header->adv_router == ospf6->router_id) {
+       ospf6 = ospf6_get_by_lsdb(lsa);
+       if (ospf6_is_router_abr(ospf6))
+               oa = ospf6->backbone;
+       else
+               oa = listgetdata(listhead(ospf6->area_list));
+
+       if (oa == NULL)
+               return;
+
+       if (lsa->header->adv_router == oa->ospf6->router_id) {
                if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL))
                        zlog_debug("Ignore self-originated AS-External-LSA");
                return;
@@ -603,7 +604,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        prefix.prefixlen = external->prefix.prefix_length;
        ospf6_prefix_in6_addr(&prefix.u.prefix6, external, &external->prefix);
 
-       route = ospf6_route_lookup(&prefix, ospf6->route_table);
+       route = ospf6_route_lookup(&prefix, oa->ospf6->route_table);
        if (route == NULL) {
                if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL)) {
                        zlog_debug("AS-External route %pFX not found", &prefix);
@@ -729,9 +730,10 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                                        /* Update RIB/FIB with effective
                                         * nh_list
                                         */
-                                       if (ospf6->route_table->hook_add)
-                                               (*ospf6->route_table->hook_add)
-                                               (route);
+                                       if (oa->ospf6->route_table->hook_add)
+                                               (*oa->ospf6->route_table
+                                                         ->hook_add)(
+                                                       route, oa->ospf6);
 
                                        /* route's primary path is similar
                                         * to LSA, replace route's primary
@@ -754,8 +756,9 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                                                h_path->origin.adv_router;
                                        }
                                } else {
-                                       ospf6_route_remove(route,
-                                                          ospf6->route_table);
+                                       ospf6_route_remove(
+                                               route, oa->ospf6->route_table,
+                                               oa->ospf6);
                                }
                        }
                        continue;
@@ -795,7 +798,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                                &route->prefix, route->path.cost, route->path.u.cost_e2,
                                listcount(route->nh_list));
                }
-               ospf6_route_remove(route, ospf6->route_table);
+               ospf6_route_remove(route, oa->ospf6->route_table, oa->ospf6);
        }
        if (route != NULL)
                ospf6_route_unlock(route);
@@ -803,7 +806,7 @@ void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
        ospf6_route_delete(route_to_del);
 }
 
-void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry)
+void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry, struct ospf6 *ospf6)
 {
        struct ospf6_lsa *lsa;
        uint16_t type;
@@ -821,11 +824,12 @@ void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry)
        router = ospf6_linkstate_prefix_adv_router(&asbr_entry->prefix);
        for (ALL_LSDB_TYPED_ADVRTR(ospf6->lsdb, type, router, lsa)) {
                if (!OSPF6_LSA_IS_MAXAGE(lsa))
-                       ospf6_asbr_lsa_add(lsa);
+                       ospf6_asbr_lsa_add(lsa, ospf6);
        }
 }
 
-void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry)
+void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry,
+                              struct ospf6 *ospf6)
 {
        struct ospf6_lsa *lsa;
        uint16_t type;
@@ -840,8 +844,16 @@ void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry)
 
 /* redistribute function */
 
-static void ospf6_asbr_routemap_set(int type, const char *mapname)
+static void ospf6_asbr_routemap_set(int type, const char *mapname,
+                                   uint32_t vrf_id)
 {
+       struct ospf6 *ospf6 = NULL;
+
+       ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
+
+       if (ospf6 == NULL)
+               return;
+
        if (ospf6->rmap[type].name) {
                route_map_counter_decrement(ospf6->rmap[type].map);
                free(ospf6->rmap[type].name);
@@ -851,7 +863,7 @@ static void ospf6_asbr_routemap_set(int type, const char *mapname)
        route_map_counter_increment(ospf6->rmap[type].map);
 }
 
-static void ospf6_asbr_routemap_unset(int type)
+static void ospf6_asbr_routemap_unset(int type, struct ospf6 *ospf6)
 {
        if (ospf6->rmap[type].name)
                free(ospf6->rmap[type].name);
@@ -866,8 +878,10 @@ static int ospf6_asbr_routemap_update_timer(struct thread *thread)
 {
        void **arg;
        int arg_type;
+       struct ospf6 *ospf6;
 
        arg = THREAD_ARG(thread);
+       ospf6 = (struct ospf6 *)arg[0];
        arg_type = (int)(intptr_t)arg[1];
 
        ospf6->t_distribute_update = NULL;
@@ -889,7 +903,7 @@ static int ospf6_asbr_routemap_update_timer(struct thread *thread)
        return 0;
 }
 
-void ospf6_asbr_distribute_list_update(int type)
+void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6)
 {
        void **args = NULL;
 
@@ -914,62 +928,75 @@ void ospf6_asbr_distribute_list_update(int type)
 static void ospf6_asbr_routemap_update(const char *mapname)
 {
        int type;
+       struct listnode *node, *nnode;
+       struct ospf6 *ospf6 = NULL;
 
-       if (ospf6 == NULL)
+       if (om6 == NULL)
                return;
 
-       for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
-               if (ospf6->rmap[type].name) {
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+               for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+                       if (ospf6->rmap[type].name == NULL)
+                               continue;
                        ospf6->rmap[type].map = route_map_lookup_by_name(
-                               ospf6->rmap[type].name);
+                                       ospf6->rmap[type].name);
 
-                       if (mapname
-                           && (strcmp(ospf6->rmap[type].name, mapname) == 0)) {
-                               if (ospf6->rmap[type].map) {
-                                       if (IS_OSPF6_DEBUG_ASBR)
-                                               zlog_debug(
+                       if (mapname == NULL || strcmp(ospf6->rmap[type].name, mapname))
+                               continue;
+                       if (ospf6->rmap[type].map) {
+                               if (IS_OSPF6_DEBUG_ASBR)
+                                       zlog_debug(
                                                        "%s: route-map %s update, reset redist %s",
-                                                       __func__, mapname,
-                                                       ZROUTE_NAME(type));
+                                                       __func__,
+                                                       mapname,
+                                                       ZROUTE_NAME(
+                                                               type));
 
                                        route_map_counter_increment(
-                                               ospf6->rmap[type].map);
+                                                       ospf6->rmap[type].map);
 
-                                       ospf6_asbr_distribute_list_update(type);
-                               } else {
-                                       /*
-                                        * if the mapname matches a route-map on
-                                        * ospf6 but the map doesn't exist, it
-                                        * is being deleted. flush and then
-                                        * readvertise
-                                        */
-                                       if (IS_OSPF6_DEBUG_ASBR)
-                                               zlog_debug(
+                                       ospf6_asbr_distribute_list_update(
+                                                       type, ospf6);
+                       } else {
+                               /*
+                               * if the mapname matches a
+                               * route-map on ospf6 but the
+                               * map doesn't exist, it is
+                               * being deleted. flush and then
+                               * readvertise
+                               */
+                               if (IS_OSPF6_DEBUG_ASBR)
+                                       zlog_debug(
                                                        "%s: route-map %s deleted, reset redist %s",
-                                                       __func__, mapname,
-                                                       ZROUTE_NAME(type));
-                                       ospf6_asbr_redistribute_unset(
+                                                       __func__,
+                                                       mapname,
+                                                       ZROUTE_NAME(
+                                                               type));
+                               ospf6_asbr_redistribute_unset(
                                                type, ospf6->vrf_id);
-                                       ospf6_asbr_routemap_set(type, mapname);
-                                       ospf6_asbr_redistribute_set(
+                               ospf6_asbr_routemap_set(
+                                               type, mapname,
+                                               ospf6->vrf_id);
+                               ospf6_asbr_redistribute_set(
                                                type, ospf6->vrf_id);
-                               }
                        }
-               } else
-                       ospf6->rmap[type].map = NULL;
+               }
        }
 }
 
 static void ospf6_asbr_routemap_event(const char *name)
 {
        int type;
+       struct listnode *node, *nnode;
+       struct ospf6 *ospf6;
 
-       if (ospf6 == NULL)
+       if (om6 == NULL)
                return;
-       for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
-               if ((ospf6->rmap[type].name)
-                   && (strcmp(ospf6->rmap[type].name, name) == 0)) {
-                       ospf6_asbr_distribute_list_update(type);
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+               for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
+                       if ((ospf6->rmap[type].name)
+                           && (strcmp(ospf6->rmap[type].name, name) == 0))
+                               ospf6_asbr_distribute_list_update(type, ospf6);
                }
        }
 }
@@ -988,6 +1015,12 @@ static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id)
 {
        struct ospf6_route *route;
        struct ospf6_external_info *info;
+       struct ospf6 *ospf6 = NULL;
+
+       ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
+
+       if (ospf6 == NULL)
+               return;
 
        ospf6_zebra_no_redistribute(type, vrf_id);
 
@@ -997,18 +1030,19 @@ static void ospf6_asbr_redistribute_unset(int type, vrf_id_t vrf_id)
                if (info->type != type)
                        continue;
 
-               ospf6_asbr_redistribute_remove(info->type, 0, &route->prefix);
+               ospf6_asbr_redistribute_remove(info->type, 0, &route->prefix,
+                                              ospf6);
        }
 
-       ospf6_asbr_routemap_unset(type);
+       ospf6_asbr_routemap_unset(type, ospf6);
 }
 
 /* When an area is unstubified, flood all the external LSAs in the area */
 void ospf6_asbr_send_externals_to_area(struct ospf6_area *oa)
 {
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
-       for (ALL_LSDB(oa->ospf6->lsdb, lsa)) {
+       for (ALL_LSDB(oa->ospf6->lsdb, lsa, lsanext)) {
                if (ntohs(lsa->header->type) == OSPF6_LSTYPE_AS_EXTERNAL) {
                        zlog_debug("%s: Flooding AS-External LSA %s",
                                   __func__, lsa->name);
@@ -1020,7 +1054,8 @@ void ospf6_asbr_send_externals_to_area(struct ospf6_area *oa)
 void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
                                 struct prefix *prefix,
                                 unsigned int nexthop_num,
-                                struct in6_addr *nexthop, route_tag_t tag)
+                                struct in6_addr *nexthop, route_tag_t tag,
+                                struct ospf6 *ospf6)
 {
        route_map_result_t ret;
        struct ospf6_route troute;
@@ -1029,7 +1064,7 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
        struct ospf6_external_info *info;
        struct prefix prefix_id;
        struct route_node *node;
-       char pbuf[PREFIX2STR_BUFFER], ibuf[16];
+       char ibuf[16];
        struct listnode *lnode, *lnnode;
        struct ospf6_area *oa;
 
@@ -1039,10 +1074,8 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
        memset(&troute, 0, sizeof(troute));
        memset(&tinfo, 0, sizeof(tinfo));
 
-       if (IS_OSPF6_DEBUG_ASBR) {
-               prefix2str(prefix, pbuf, sizeof(pbuf));
-               zlog_debug("Redistribute %s (%s)", pbuf, ZROUTE_NAME(type));
-       }
+       if (IS_OSPF6_DEBUG_ASBR)
+               zlog_debug("Redistribute %pFX (%s)", prefix, ZROUTE_NAME(type));
 
        /* if route-map was specified but not found, do not advertise */
        if (ospf6->rmap[type].name) {
@@ -1068,7 +1101,8 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
                        if (IS_OSPF6_DEBUG_ASBR)
                                zlog_debug("Denied by route-map \"%s\"",
                                           ospf6->rmap[type].name);
-                       ospf6_asbr_redistribute_remove(type, ifindex, prefix);
+                       ospf6_asbr_redistribute_remove(type, ifindex, prefix,
+                                                      ospf6);
                        return;
                }
        }
@@ -1109,14 +1143,13 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
                if (IS_OSPF6_DEBUG_ASBR) {
                        inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf,
                                  sizeof(ibuf));
-                       prefix2str(prefix, pbuf, sizeof(pbuf));
                        zlog_debug(
-                               "Advertise as AS-External Id:%s prefix %s metric %u",
-                               ibuf, pbuf, match->path.metric_type);
+                               "Advertise as AS-External Id:%s prefix %pFX metric %u",
+                               ibuf, prefix, match->path.metric_type);
                }
 
                match->path.origin.id = htonl(info->id);
-               ospf6_as_external_lsa_originate(match);
+               ospf6_as_external_lsa_originate(match, ospf6);
                return;
        }
 
@@ -1158,18 +1191,18 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
        node = route_node_get(ospf6->external_id_table, &prefix_id);
        node->info = route;
 
-       route = ospf6_route_add(route, ospf6->external_table);
+       route = ospf6_route_add(route, ospf6->external_table, ospf6);
        route->route_option = info;
 
        if (IS_OSPF6_DEBUG_ASBR) {
                inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf));
-               prefix2str(prefix, pbuf, sizeof(pbuf));
-               zlog_debug("Advertise as AS-External Id:%s prefix %s metric %u",
-                          ibuf, pbuf, route->path.metric_type);
+               zlog_debug(
+                       "Advertise as AS-External Id:%s prefix %pFX metric %u",
+                       ibuf, prefix, route->path.metric_type);
        }
 
        route->path.origin.id = htonl(info->id);
-       ospf6_as_external_lsa_originate(route);
+       ospf6_as_external_lsa_originate(route, ospf6);
 
        /* Router-Bit (ASBR Flag) may have to be updated */
        for (ALL_LIST_ELEMENTS(ospf6->area_list, lnode, lnnode, oa))
@@ -1177,23 +1210,21 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
 }
 
 void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
-                                   struct prefix *prefix)
+                                   struct prefix *prefix, struct ospf6 *ospf6)
 {
        struct ospf6_route *match;
        struct ospf6_external_info *info = NULL;
        struct route_node *node;
        struct ospf6_lsa *lsa;
        struct prefix prefix_id;
-       char pbuf[PREFIX2STR_BUFFER], ibuf[16];
+       char ibuf[16];
        struct listnode *lnode, *lnnode;
        struct ospf6_area *oa;
 
        match = ospf6_route_lookup(prefix, ospf6->external_table);
        if (match == NULL) {
-               if (IS_OSPF6_DEBUG_ASBR) {
-                       prefix2str(prefix, pbuf, sizeof(pbuf));
-                       zlog_debug("No such route %s to withdraw", pbuf);
-               }
+               if (IS_OSPF6_DEBUG_ASBR)
+                       zlog_debug("No such route %pFX to withdraw", prefix);
                return;
        }
 
@@ -1201,17 +1232,14 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
        assert(info);
 
        if (info->type != type) {
-               if (IS_OSPF6_DEBUG_ASBR) {
-                       prefix2str(prefix, pbuf, sizeof(pbuf));
-                       zlog_debug("Original protocol mismatch: %s", pbuf);
-               }
+               if (IS_OSPF6_DEBUG_ASBR)
+                       zlog_debug("Original protocol mismatch: %pFX", prefix);
                return;
        }
 
        if (IS_OSPF6_DEBUG_ASBR) {
-               prefix2str(prefix, pbuf, sizeof(pbuf));
                inet_ntop(AF_INET, &prefix_id.u.prefix4, ibuf, sizeof(ibuf));
-               zlog_debug("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
+               zlog_debug("Withdraw %pFX (AS-External Id:%s)", prefix, ibuf);
        }
 
        lsa = ospf6_lsdb_lookup(htons(OSPF6_LSTYPE_AS_EXTERNAL),
@@ -1229,7 +1257,7 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
        route_unlock_node(node); /* to free the lookup lock */
        route_unlock_node(node); /* to free the original lock */
 
-       ospf6_route_remove(match, ospf6->external_table);
+       ospf6_route_remove(match, ospf6->external_table, ospf6);
        XFREE(MTYPE_OSPF6_EXTERNAL_INFO, info);
 
        /* Router-Bit (ASBR Flag) may have to be updated */
@@ -1245,8 +1273,8 @@ DEFUN (ospf6_redistribute,
 {
        int type;
 
-       OSPF6_CMD_CHECK_RUNNING();
-
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        char *proto = argv[argc - 1]->text;
        type = proto_redistnum(AFI_IP6, proto);
        if (type < 0)
@@ -1269,7 +1297,8 @@ DEFUN (ospf6_redistribute_routemap,
        int idx_word = 3;
        int type;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        char *proto = argv[idx_protocol]->text;
        type = proto_redistnum(AFI_IP6, proto);
@@ -1277,7 +1306,7 @@ DEFUN (ospf6_redistribute_routemap,
                return CMD_WARNING_CONFIG_FAILED;
 
        ospf6_asbr_redistribute_unset(type, ospf6->vrf_id);
-       ospf6_asbr_routemap_set(type, argv[idx_word]->arg);
+       ospf6_asbr_routemap_set(type, argv[idx_word]->arg, ospf6->vrf_id);
        ospf6_asbr_redistribute_set(type, ospf6->vrf_id);
        return CMD_SUCCESS;
 }
@@ -1294,7 +1323,9 @@ DEFUN (no_ospf6_redistribute,
        int idx_protocol = 2;
        int type;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        char *proto = argv[idx_protocol]->text;
        type = proto_redistnum(AFI_IP6, proto);
@@ -1306,7 +1337,7 @@ DEFUN (no_ospf6_redistribute,
        return CMD_SUCCESS;
 }
 
-int ospf6_redistribute_config_write(struct vty *vty)
+int ospf6_redistribute_config_write(struct vty *vty, struct ospf6 *ospf6)
 {
        int type;
 
@@ -1326,7 +1357,7 @@ int ospf6_redistribute_config_write(struct vty *vty)
        return 0;
 }
 
-static void ospf6_redistribute_show_config(struct vty *vty)
+static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6)
 {
        int type;
        int nroute[ZEBRA_ROUTE_MAX];
@@ -1823,10 +1854,9 @@ static void ospf6_asbr_external_route_show(struct vty *vty,
                                           struct ospf6_route *route)
 {
        struct ospf6_external_info *info = route->route_option;
-       char prefix[PREFIX2STR_BUFFER], id[16], forwarding[64];
+       char id[16], forwarding[64];
        uint32_t tmp_id;
 
-       prefix2str(&route->prefix, prefix, sizeof(prefix));
        tmp_id = ntohl(info->id);
        inet_ntop(AF_INET, &tmp_id, id, sizeof(id));
        if (!IN6_IS_ADDR_UNSPECIFIED(&info->forwarding))
@@ -1836,8 +1866,8 @@ static void ospf6_asbr_external_route_show(struct vty *vty,
                snprintf(forwarding, sizeof(forwarding), ":: (ifindex %d)",
                         ospf6_route_get_first_nh_index(route));
 
-       vty_out(vty, "%c %-32s %-15s type-%d %5lu %s\n",
-               zebra_route_char(info->type), prefix, id,
+       vty_out(vty, "%c %-32pFX %-15s type-%d %5lu %s\n",
+               zebra_route_char(info->type), &route->prefix, id,
                route->path.metric_type,
                (unsigned long)(route->path.metric_type == 2
                                        ? route->path.u.cost_e2
@@ -1855,10 +1885,12 @@ DEFUN (show_ipv6_ospf6_redistribute,
        )
 {
        struct ospf6_route *route;
+       struct ospf6 *ospf6 = NULL;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
-       ospf6_redistribute_show_config(vty);
+       ospf6_redistribute_show_config(vty, ospf6);
 
        for (route = ospf6_route_head(ospf6->external_table); route;
             route = ospf6_route_next(route))
index 41b1ac70e9ff190501b99eb17bbd7fa0909e9be9..46c99706acf0ba5e480abca844f4c21c99245265 100644 (file)
@@ -70,22 +70,26 @@ struct ospf6_as_external_lsa {
                (E)->bits_metric |= htonl(0x00ffffff) & htonl(C);              \
        }
 
-extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa);
+extern void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6);
 extern void ospf6_asbr_lsa_remove(struct ospf6_lsa *lsa,
                                  struct ospf6_route *asbr_entry);
-extern void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry);
-extern void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry);
+extern void ospf6_asbr_lsentry_add(struct ospf6_route *asbr_entry,
+                                  struct ospf6 *ospf6);
+extern void ospf6_asbr_lsentry_remove(struct ospf6_route *asbr_entry,
+                                     struct ospf6 *ospf6);
 
 extern int ospf6_asbr_is_asbr(struct ospf6 *o);
 extern void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
                                        struct prefix *prefix,
                                        unsigned int nexthop_num,
                                        struct in6_addr *nexthop,
-                                       route_tag_t tag);
+                                       route_tag_t tag, struct ospf6 *ospf6);
 extern void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
-                                          struct prefix *prefix);
+                                          struct prefix *prefix,
+                                          struct ospf6 *ospf6);
 
-extern int ospf6_redistribute_config_write(struct vty *vty);
+extern int ospf6_redistribute_config_write(struct vty *vty,
+                                          struct ospf6 *ospf6);
 
 extern void ospf6_asbr_init(void);
 extern void ospf6_asbr_redistribute_reset(vrf_id_t vrf_id);
@@ -95,7 +99,8 @@ extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *);
 extern int config_write_ospf6_debug_asbr(struct vty *vty);
 extern void install_element_ospf6_debug_asbr(void);
 extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
-                                             struct ospf6_route *route);
-extern void ospf6_asbr_distribute_list_update(int type);
+                                             struct ospf6_route *route,
+                                             struct ospf6 *ospf6);
+extern void ospf6_asbr_distribute_list_update(int type, struct ospf6 *ospf6);
 
 #endif /* OSPF6_ASBR_H */
index 1b58cd14f6f71ec246ea38c0d12428516d79a24e..4e50ab5244acd0d459eb9e8cf178ea4e9db27d5c 100644 (file)
@@ -204,12 +204,9 @@ static int ospf6_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
        if ((ifp == NULL) || (dp.family != AF_INET6))
                return 0;
 
-       if (IS_OSPF6_DEBUG_ZEBRA(RECV)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&dp, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s bfd destination %s %s",
-                          ifp->name, buf, bfd_get_status_str(status));
-       }
+       if (IS_OSPF6_DEBUG_ZEBRA(RECV))
+               zlog_debug("Zebra: interface %s bfd destination %pFX %s",
+                          ifp->name, &dp, bfd_get_status_str(status));
 
 
        oi = (struct ospf6_interface *)ifp->info;
index b144c6804e9e41bdffc5c3a9e85ba46af9547bcd..0662cfd683647ae74000c00d1f6049b044ed53d2 100644 (file)
@@ -370,7 +370,7 @@ void ospf6_flood_interface(struct ospf6_neighbor *from, struct ospf6_lsa *lsa,
                        continue;
                }
 
-               if (ospf6->inst_shutdown) {
+               if (oi->area->ospf6->inst_shutdown) {
                        if (is_debug)
                                zlog_debug(
                                        "%s: Send LSA %s (age %d) update now",
@@ -486,6 +486,12 @@ static void ospf6_flood_process(struct ospf6_neighbor *from,
 
 void ospf6_flood(struct ospf6_neighbor *from, struct ospf6_lsa *lsa)
 {
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_get_by_lsdb(lsa);
+       if (ospf6 == NULL)
+               return;
+
        ospf6_flood_process(from, lsa, ospf6);
 }
 
@@ -555,6 +561,9 @@ static void ospf6_flood_clear_process(struct ospf6_lsa *lsa,
 
 void ospf6_flood_clear(struct ospf6_lsa *lsa)
 {
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_get_by_lsdb(lsa);
        ospf6_flood_clear_process(lsa, ospf6);
 }
 
@@ -1001,18 +1010,22 @@ void ospf6_receive_lsa(struct ospf6_neighbor *from,
                         * MAXAGEd and not removed.*/
                        if (OSPF6_LSA_IS_MAXAGE(old)
                            && !OSPF6_LSA_IS_MAXAGE(new)) {
-
-                               if (is_debug)
-                                       zlog_debug(
-                                               "%s: Current copy of LSA %s is MAXAGE, but new has recent Age.",
-                                               old->name, __func__);
-
-                               ospf6_lsa_purge(old);
                                if (new->header->adv_router
-                                   != from->ospf6_if->area->ospf6->router_id)
+                                   != from->ospf6_if->area->ospf6->router_id) {
+                                       if (is_debug)
+                                               zlog_debug(
+                                                       "%s: Current copy of LSA %s is MAXAGE, but new has recent age, flooding/installing.",
+                                                       old->name, __PRETTY_FUNCTION__);
+                                       ospf6_lsa_purge(old);
                                        ospf6_flood(from, new);
-
-                               ospf6_install_lsa(new);
+                                       ospf6_install_lsa(new);
+                               } else {
+                                       if (is_debug)
+                                               zlog_debug(
+                                                       "%s: Current copy of self-originated LSA %s is MAXAGE, but new has recent age, ignoring new.",
+                                                       old->name, __PRETTY_FUNCTION__);
+                                       ospf6_lsa_delete(new);
+                               }
                                return;
                        }
 
index fabcc426eadedbb6221935fc2fe542a9fbc1f986..75917b9d859e9325e46670a374c9e469083f8784 100644 (file)
 
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
+#include "ospf6_top.h"
 #include "ospf6_network.h"
 #include "ospf6_message.h"
 #include "ospf6_route.h"
-#include "ospf6_top.h"
 #include "ospf6_area.h"
 #include "ospf6_interface.h"
 #include "ospf6_neighbor.h"
@@ -118,7 +118,7 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
        /* If all else fails, use default OSPF cost */
        uint32_t cost;
        uint32_t bw, refbw;
-
+       struct ospf6 *ospf6;
        /* interface speed and bw can be 0 in some platforms,
         * use ospf default bw. If bw is configured then it would
         * be used.
@@ -130,6 +130,7 @@ static uint32_t ospf6_interface_get_cost(struct ospf6_interface *oi)
                                              : OSPF6_INTERFACE_BANDWIDTH;
        }
 
+       ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
        refbw = ospf6 ? ospf6->ref_bandwidth : OSPF6_REFERENCE_BANDWIDTH;
 
        /* A specifed ip ospf cost overrides a calculated one. */
@@ -259,7 +260,7 @@ void ospf6_interface_delete(struct ospf6_interface *oi)
        ospf6_lsdb_delete(oi->lsupdate_list);
        ospf6_lsdb_delete(oi->lsack_list);
 
-       ospf6_route_table_delete(oi->route_connected);
+       ospf6_route_table_delete(oi->route_connected, oi->area->ospf6);
 
        /* cut link */
        oi->interface->info = NULL;
@@ -415,7 +416,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
                return;
 
        /* update "route to advertise" interface route table */
-       ospf6_route_remove_all(oi->route_connected);
+       ospf6_route_remove_all(oi->route_connected, oi->area->ospf6);
 
        for (ALL_LIST_ELEMENTS(oi->interface->connected, node, nnode, c)) {
                if (c->address->family != AF_INET6)
@@ -436,16 +437,14 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
                if (oi->plist_name) {
                        struct prefix_list *plist;
                        enum prefix_list_type ret;
-                       char buf[PREFIX2STR_BUFFER];
 
-                       prefix2str(c->address, buf, sizeof(buf));
                        plist = prefix_list_lookup(AFI_IP6, oi->plist_name);
                        ret = prefix_list_apply(plist, (void *)c->address);
                        if (ret == PREFIX_DENY) {
                                if (IS_OSPF6_DEBUG_INTERFACE)
                                        zlog_debug(
-                                               "%s on %s filtered by prefix-list %s ",
-                                               buf, oi->interface->name,
+                                               "%pFX on %s filtered by prefix-list %s ",
+                                               c->address, oi->interface->name,
                                                oi->plist_name);
                                continue;
                        }
@@ -461,7 +460,7 @@ void ospf6_interface_connected_route_update(struct interface *ifp)
                inet_pton(AF_INET6, "::1", &nh_addr);
                ospf6_route_add_nexthop(route, oi->interface->ifindex,
                                        &nh_addr);
-               ospf6_route_add(route, oi->route_connected);
+               ospf6_route_add(route, oi->route_connected, oi->area->ospf6);
        }
 
        /* create new Link-LSA */
@@ -474,6 +473,7 @@ static void ospf6_interface_state_change(uint8_t next_state,
                                         struct ospf6_interface *oi)
 {
        uint8_t prev_state;
+       struct ospf6 *ospf6;
 
        prev_state = oi->state;
        oi->state = next_state;
@@ -489,20 +489,21 @@ static void ospf6_interface_state_change(uint8_t next_state,
                           ospf6_interface_state_str[next_state]);
        }
        oi->state_change++;
+       ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
 
        if ((prev_state == OSPF6_INTERFACE_DR
             || prev_state == OSPF6_INTERFACE_BDR)
            && (next_state != OSPF6_INTERFACE_DR
                && next_state != OSPF6_INTERFACE_BDR))
                ospf6_sso(oi->interface->ifindex, &alldrouters6,
-                         IPV6_LEAVE_GROUP);
+                         IPV6_LEAVE_GROUP, ospf6->fd);
 
        if ((prev_state != OSPF6_INTERFACE_DR
             && prev_state != OSPF6_INTERFACE_BDR)
            && (next_state == OSPF6_INTERFACE_DR
                || next_state == OSPF6_INTERFACE_BDR))
                ospf6_sso(oi->interface->ifindex, &alldrouters6,
-                         IPV6_JOIN_GROUP);
+                         IPV6_JOIN_GROUP, ospf6->fd);
 
        OSPF6_ROUTER_LSA_SCHEDULE(oi->area);
        if (next_state == OSPF6_INTERFACE_DOWN) {
@@ -679,6 +680,7 @@ static uint8_t dr_election(struct ospf6_interface *oi)
 int interface_up(struct thread *thread)
 {
        struct ospf6_interface *oi;
+       struct ospf6 *ospf6;
 
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
        assert(oi && oi->interface);
@@ -749,9 +751,14 @@ int interface_up(struct thread *thread)
                return 0;
        }
 #endif /* __FreeBSD__ */
+       if (oi->area->ospf6)
+               ospf6 = oi->area->ospf6;
+       else
+               ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
 
        /* Join AllSPFRouters */
-       if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP)
+       if (ospf6_sso(oi->interface->ifindex, &allspfrouters6, IPV6_JOIN_GROUP,
+                     ospf6->fd)
            < 0) {
                if (oi->sso_try_cnt++ < OSPF6_INTERFACE_SSO_RETRY_MAX) {
                        zlog_info(
@@ -848,6 +855,7 @@ int interface_down(struct thread *thread)
        struct ospf6_interface *oi;
        struct listnode *node, *nnode;
        struct ospf6_neighbor *on;
+       struct ospf6 *ospf6;
 
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
        assert(oi && oi->interface);
@@ -861,11 +869,11 @@ int interface_down(struct thread *thread)
 
        /* Stop trying to set socket options. */
        THREAD_OFF(oi->thread_sso);
-
+       ospf6 = ospf6_lookup_by_vrf_id(oi->interface->vrf_id);
        /* Leave AllSPFRouters */
        if (oi->state > OSPF6_INTERFACE_DOWN)
                ospf6_sso(oi->interface->ifindex, &allspfrouters6,
-                         IPV6_LEAVE_GROUP);
+                         IPV6_LEAVE_GROUP, ospf6->fd);
 
        ospf6_interface_state_change(OSPF6_INTERFACE_DOWN, oi);
 
@@ -906,7 +914,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
        uint8_t default_iftype;
        struct timeval res, now;
        char duration[32];
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        default_iftype = ospf6_default_iftype(ifp);
 
@@ -929,16 +937,15 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
 
        for (ALL_LIST_ELEMENTS_RO(ifp->connected, i, c)) {
                p = c->address;
-               prefix2str(p, strbuf, sizeof(strbuf));
                switch (p->family) {
                case AF_INET:
-                       vty_out(vty, "    inet : %s\n", strbuf);
+                       vty_out(vty, "    inet : %pFX\n", p);
                        break;
                case AF_INET6:
-                       vty_out(vty, "    inet6: %s\n", strbuf);
+                       vty_out(vty, "    inet6: %pFX\n", p);
                        break;
                default:
-                       vty_out(vty, "    ???  : %s\n", strbuf);
+                       vty_out(vty, "    ???  : %pFX\n", p);
                        break;
                }
        }
@@ -977,7 +984,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
                "    %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
                oi->lsupdate_list->count, duration,
                (oi->thread_send_lsupdate ? "on" : "off"));
-       for (ALL_LSDB(oi->lsupdate_list, lsa))
+       for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        timerclear(&res);
@@ -987,7 +994,7 @@ static int ospf6_interface_show(struct vty *vty, struct interface *ifp)
        vty_out(vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]\n",
                oi->lsack_list->count, duration,
                (oi->thread_send_lsack ? "on" : "off"));
-       for (ALL_LSDB(oi->lsack_list, lsa))
+       for (ALL_LSDB(oi->lsack_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
        ospf6_bfd_show_info(vty, oi->bfd_info, 1);
        return 0;
index a34f8d369355da240b72957222e655c0de27708e..f84a7cfe9af1c398400497d9e353018b75a71b53 100644 (file)
@@ -147,7 +147,7 @@ static void ospf6_router_lsa_options_set(struct ospf6_area *oa,
        OSPF6_OPT_CLEAR_ALL(router_lsa->options);
        memcpy(router_lsa->options, oa->options, 3);
 
-       if (ospf6_is_router_abr(ospf6))
+       if (ospf6_is_router_abr(oa->ospf6))
                SET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B);
        else
                UNSET_FLAG(router_lsa->bits, OSPF6_ROUTER_BIT_B);
@@ -907,7 +907,6 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
        struct listnode *i, *j;
        int full_count = 0;
        unsigned short prefix_num = 0;
-       char buf[PREFIX2STR_BUFFER];
        struct ospf6_route_table *route_advertise;
        int ls_id = 0;
 
@@ -985,12 +984,10 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
                /* connected prefix to advertise */
                for (route = ospf6_route_head(oi->route_connected); route;
                     route = ospf6_route_best_next(route)) {
-                       if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) {
-                               prefix2str(&route->prefix, buf, sizeof(buf));
-                               zlog_debug("    include %s", buf);
-                       }
+                       if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
+                               zlog_debug("    include %pFX", &route->prefix);
                        ospf6_route_add(ospf6_route_copy(route),
-                                       route_advertise);
+                                       route_advertise, oa->ospf6);
                }
        }
 
@@ -1011,7 +1008,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
                                        oa->lsdb);
                        }
                }
-               ospf6_route_table_delete(route_advertise);
+               ospf6_route_table_delete(route_advertise, oa->ospf6);
                return 0;
        }
 
@@ -1091,7 +1088,7 @@ int ospf6_intra_prefix_lsa_originate_stub(struct thread *thread)
                op = OSPF6_PREFIX_NEXT(op);
        }
 
-       ospf6_route_table_delete(route_advertise);
+       ospf6_route_table_delete(route_advertise, oa->ospf6);
 
        if (prefix_num == 0) {
                if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
@@ -1144,7 +1141,6 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)
        struct ospf6_link_lsa *link_lsa;
        char *start, *end, *current;
        uint16_t type;
-       char buf[PREFIX2STR_BUFFER];
 
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
        oi->thread_intra_prefix_lsa = NULL;
@@ -1255,12 +1251,11 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)
                        route->path.area_id = oi->area->area_id;
                        route->path.type = OSPF6_PATH_TYPE_INTRA;
 
-                       if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX)) {
-                               prefix2str(&route->prefix, buf, sizeof(buf));
-                               zlog_debug("    include %s", buf);
-                       }
+                       if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
+                               zlog_debug("    include %pFX", &route->prefix);
 
-                       ospf6_route_add(route, route_advertise);
+                       ospf6_route_add(route, route_advertise,
+                                       oi->area->ospf6);
                        prefix_num--;
                }
                if (current != end && IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
@@ -1282,7 +1277,7 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)
                prefix_num++;
        }
 
-       ospf6_route_table_delete(route_advertise);
+       ospf6_route_table_delete(route_advertise, oi->area->ospf6);
 
        if (prefix_num == 0) {
                if (IS_OSPF6_DEBUG_ORIGINATE(INTRA_PREFIX))
@@ -1315,14 +1310,14 @@ int ospf6_intra_prefix_lsa_originate_transit(struct thread *thread)
        return 0;
 }
 
-static void ospf6_intra_prefix_update_route_origin(struct ospf6_route *oa_route)
+static void ospf6_intra_prefix_update_route_origin(struct ospf6_route *oa_route,
+                                                  struct ospf6 *ospf6)
 {
        struct ospf6_path *h_path;
        struct ospf6_route *g_route, *nroute;
 
        /* Update Global ospf6 route path */
-       g_route = ospf6_route_lookup(&oa_route->prefix,
-                                    ospf6->route_table);
+       g_route = ospf6_route_lookup(&oa_route->prefix, ospf6->route_table);
 
        assert(g_route);
 
@@ -1442,15 +1437,15 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
                                         * nh_list
                                         */
                                        if (oa->route_table->hook_add)
-                                               (*oa->route_table->hook_add)
-                                                       (old_route);
+                                               (*oa->route_table->hook_add)(
+                                                       old_route, oa->ospf6);
 
                                        if (old_route->path.origin.id ==
                                        route->path.origin.id &&
                                        old_route->path.origin.adv_router ==
                                                route->path.origin.adv_router) {
                                                ospf6_intra_prefix_update_route_origin(
-                                                               old_route);
+                                                       old_route, oa->ospf6);
                                        }
                                        break;
                                }
@@ -1464,7 +1459,8 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
                                }
                                if (oa->route_table->hook_remove)
                                        ospf6_route_remove(old_route,
-                                                  oa->route_table);
+                                                          oa->route_table,
+                                                          oa->ospf6);
                                else
                                        SET_FLAG(old_route->flag,
                                                 OSPF6_ROUTE_REMOVE);
@@ -1554,11 +1550,9 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
                                                ospf6_linkstate_prefix(
                                                o_path->origin.adv_router,
                                                o_path->origin.id, &adv_prefix);
-                                               prefix2str(&adv_prefix, buf,
-                                                          sizeof(buf));
                                                zlog_debug(
-                                                       "%s: adv_router %s lsa not found",
-                                                       __func__, buf);
+                                                       "%s: adv_router %pFX lsa not found",
+                                                       __func__, &adv_prefix);
                                        }
                                        continue;
                                }
@@ -1590,16 +1584,15 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
                                }
                        }
 
-                       if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX)) {
-                               prefix2str(&route->prefix, buf, sizeof(buf));
+                       if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
                                zlog_debug(
-                                       "%s: route %s %p with final effective paths %u nh%u",
-                                       __func__, buf, (void *)old_route,
+                                       "%s: route %pFX %p with final effective paths %u nh%u",
+                                       __func__, &route->prefix,
+                                       (void *)old_route,
                                        old_route->paths
                                                ? listcount(old_route->paths)
                                                : 0,
                                        listcount(old_route->nh_list));
-                       }
 
                        /* used in intra_route_calculation() to add to
                         * global ospf6 route table.
@@ -1608,7 +1601,8 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
                        SET_FLAG(old_route->flag, OSPF6_ROUTE_ADD);
                        /* Update ospf6 route table and RIB/FIB */
                        if (oa->route_table->hook_add)
-                               (*oa->route_table->hook_add)(old_route);
+                               (*oa->route_table->hook_add)(old_route,
+                                                            oa->ospf6);
                        /* Delete the new route its info added to existing
                         * route.
                         */
@@ -1620,7 +1614,7 @@ void ospf6_intra_prefix_route_ecmp_path(struct ospf6_area *oa,
 
        if (!route_found) {
                /* Add new route to existing node in ospf6 route table. */
-               ospf6_route_add(route, oa->route_table);
+               ospf6_route_add(route, oa->route_table, oa->ospf6);
        }
 }
 
@@ -1763,7 +1757,7 @@ void ospf6_intra_prefix_lsa_add(struct ospf6_lsa *lsa)
                                        listcount(route->paths),
                                        listcount(route->nh_list));
                        }
-                       ospf6_route_add(route, oa->route_table);
+                       ospf6_route_add(route, oa->route_table, oa->ospf6);
                }
                prefix_num--;
        }
@@ -1845,7 +1839,7 @@ static void ospf6_intra_prefix_lsa_remove_update_route(struct ospf6_lsa *lsa,
                 * nh_list
                 */
                if (oa->route_table->hook_add)
-                       (*oa->route_table->hook_add)(route);
+                       (*oa->route_table->hook_add)(route, oa->ospf6);
 
                /* route's primary path is similar
                 * to LSA, replace route's primary
@@ -1855,7 +1849,8 @@ static void ospf6_intra_prefix_lsa_remove_update_route(struct ospf6_lsa *lsa,
                if ((route->path.origin.id == lsa->header->id) &&
                    (route->path.origin.adv_router ==
                                lsa->header->adv_router)) {
-                       ospf6_intra_prefix_update_route_origin(route);
+                       ospf6_intra_prefix_update_route_origin(route,
+                                                              oa->ospf6);
                }
        }
 
@@ -1937,7 +1932,8 @@ void ospf6_intra_prefix_lsa_remove(struct ospf6_lsa *lsa)
                                                listcount(route->paths),
                                                listcount(route->nh_list));
                                }
-                               ospf6_route_remove(route, oa->route_table);
+                               ospf6_route_remove(route, oa->route_table,
+                                                  oa->ospf6);
                        }
                }
                if (route)
@@ -1953,8 +1949,8 @@ void ospf6_intra_route_calculation(struct ospf6_area *oa)
        struct ospf6_route *route, *nroute;
        uint16_t type;
        struct ospf6_lsa *lsa;
-       void (*hook_add)(struct ospf6_route *) = NULL;
-       void (*hook_remove)(struct ospf6_route *) = NULL;
+       void (*hook_add)(struct ospf6_route *, struct ospf6 *) = NULL;
+       void (*hook_remove)(struct ospf6_route *, struct ospf6 *) = NULL;
 
        if (IS_OSPF6_DEBUG_EXAMIN(INTRA_PREFIX))
                zlog_debug("Re-examin intra-routes for area %s", oa->name);
@@ -1984,15 +1980,15 @@ void ospf6_intra_route_calculation(struct ospf6_area *oa)
                }
 
                if (CHECK_FLAG(route->flag, OSPF6_ROUTE_REMOVE))
-                       ospf6_route_remove(route, oa->route_table);
+                       ospf6_route_remove(route, oa->route_table, oa->ospf6);
                else if (CHECK_FLAG(route->flag, OSPF6_ROUTE_ADD)
                         || CHECK_FLAG(route->flag, OSPF6_ROUTE_CHANGE)) {
                        if (hook_add)
-                               (*hook_add)(route);
+                               (*hook_add)(route, oa->ospf6);
                        route->flag = 0;
                } else {
                        /* Redo the summaries as things might have changed */
-                       ospf6_abr_originate_summary(route);
+                       ospf6_abr_originate_summary(route, oa->ospf6);
                        route->flag = 0;
                }
        }
@@ -2060,8 +2056,8 @@ static void ospf6_brouter_debug_print(struct ospf6_route *brouter)
 void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
 {
        struct ospf6_route *brouter, *nbrouter, *copy;
-       void (*hook_add)(struct ospf6_route *) = NULL;
-       void (*hook_remove)(struct ospf6_route *) = NULL;
+       void (*hook_add)(struct ospf6_route *, struct ospf6 *) = NULL;
+       void (*hook_remove)(struct ospf6_route *, struct ospf6 *) = NULL;
        uint32_t brouter_id;
        char brouter_name[16];
 
@@ -2119,7 +2115,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
                copy = ospf6_route_copy(brouter);
                copy->type = OSPF6_DEST_TYPE_ROUTER;
                copy->path.area_id = oa->area_id;
-               ospf6_route_add(copy, oa->ospf6->brouter_table);
+               ospf6_route_add(copy, oa->ospf6->brouter_table, oa->ospf6);
 
                if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(brouter_id)
                    || IS_OSPF6_DEBUG_ROUTE(MEMORY)) {
@@ -2205,7 +2201,8 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
                         * removes brouters which are marked for remove.
                         */
                        oa->intra_brouter_calc = 1;
-                       ospf6_route_remove(brouter, oa->ospf6->brouter_table);
+                       ospf6_route_remove(brouter, oa->ospf6->brouter_table,
+                                          oa->ospf6);
                        brouter = NULL;
                } else if (CHECK_FLAG(brouter->flag, OSPF6_ROUTE_ADD)
                           || CHECK_FLAG(brouter->flag, OSPF6_ROUTE_CHANGE)) {
@@ -2219,7 +2216,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
 
                        /* newly added */
                        if (hook_add)
-                               (*hook_add)(brouter);
+                               (*hook_add)(brouter, oa->ospf6);
                } else {
                        if (IS_OSPF6_DEBUG_BROUTER_SPECIFIC_ROUTER_ID(
                                    brouter_id)
@@ -2228,7 +2225,7 @@ void ospf6_intra_brouter_calculation(struct ospf6_area *oa)
                                zlog_info("brouter %s still exists via area %s",
                                          brouter_name, oa->name);
                        /* But re-originate summaries */
-                       ospf6_abr_originate_summary(brouter);
+                       ospf6_abr_originate_summary(brouter, oa->ospf6);
                }
 
                if (brouter) {
index 9e7479c797a6aca75e825cb415f1d5f423489abd..29141ee7f86d21237288af5423101edc8132a4a0 100644 (file)
 
 vector ospf6_lsa_handler_vector;
 
+struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa)
+{
+       struct ospf6 *ospf6 = NULL;
+
+       switch (OSPF6_LSA_SCOPE(lsa->header->type)) {
+       case OSPF6_SCOPE_LINKLOCAL:
+               ospf6 = OSPF6_INTERFACE(lsa->lsdb->data)->area->ospf6;
+               break;
+       case OSPF6_SCOPE_AREA:
+               ospf6 = OSPF6_AREA(lsa->lsdb->data)->ospf6;
+               break;
+       case OSPF6_SCOPE_AS:
+               ospf6 = OSPF6_PROCESS(lsa->lsdb->data);
+               break;
+       default:
+               assert(0);
+               break;
+       }
+       return ospf6;
+}
+
 static int ospf6_unknown_lsa_show(struct vty *vty, struct ospf6_lsa *lsa)
 {
        uint8_t *start, *end, *current;
@@ -601,10 +622,10 @@ struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *lsa)
 }
 
 /* increment reference counter of struct ospf6_lsa */
-void ospf6_lsa_lock(struct ospf6_lsa *lsa)
+struct ospf6_lsa *ospf6_lsa_lock(struct ospf6_lsa *lsa)
 {
        lsa->lock++;
-       return;
+       return lsa;
 }
 
 /* decrement reference counter of struct ospf6_lsa */
@@ -626,6 +647,7 @@ struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *lsa)
 int ospf6_lsa_expire(struct thread *thread)
 {
        struct ospf6_lsa *lsa;
+       struct ospf6 *ospf6;
 
        lsa = (struct ospf6_lsa *)THREAD_ARG(thread);
 
@@ -642,7 +664,7 @@ int ospf6_lsa_expire(struct thread *thread)
 
        if (CHECK_FLAG(lsa->flag, OSPF6_LSA_HEADERONLY))
                return 0; /* dbexchange will do something ... */
-
+       ospf6 = ospf6_get_by_lsdb(lsa);
        /* reinstall lsa */
        ospf6_install_lsa(lsa);
 
@@ -703,7 +725,7 @@ int ospf6_lsa_refresh(struct thread *thread)
        return 0;
 }
 
-void ospf6_flush_self_originated_lsas_now(void)
+void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6)
 {
        struct listnode *node;
        struct ospf6_area *oa;
index a85d7b06035f587ef79816e6415b06ad366268c4..814e2767967e0ebd27123566c2bb0d65144fb65f 100644 (file)
@@ -20,6 +20,7 @@
 
 #ifndef OSPF6_LSA_H
 #define OSPF6_LSA_H
+#include "ospf6_top.h"
 
 /* Debug option */
 #define OSPF6_LSA_DEBUG           0x01
@@ -156,46 +157,36 @@ extern vector ospf6_lsa_handler_vector;
 /* addr is (struct prefix *) */
 #define CONTINUE_IF_ADDRESS_LINKLOCAL(debug, addr)                             \
        if (IN6_IS_ADDR_LINKLOCAL(&(addr)->u.prefix6)) {                       \
-               char buf[PREFIX2STR_BUFFER];                                   \
-               prefix2str(addr, buf, sizeof(buf));                            \
                if (debug)                                                     \
-                       zlog_debug("Filter out Linklocal: %s", buf);           \
+                       zlog_debug("Filter out Linklocal: %pFX", addr);        \
                continue;                                                      \
        }
 
 #define CONTINUE_IF_ADDRESS_UNSPECIFIED(debug, addr)                           \
        if (IN6_IS_ADDR_UNSPECIFIED(&(addr)->u.prefix6)) {                     \
-               char buf[PREFIX2STR_BUFFER];                                   \
-               prefix2str(addr, buf, sizeof(buf));                            \
                if (debug)                                                     \
-                       zlog_debug("Filter out Unspecified: %s", buf);         \
+                       zlog_debug("Filter out Unspecified: %pFX", addr);      \
                continue;                                                      \
        }
 
 #define CONTINUE_IF_ADDRESS_LOOPBACK(debug, addr)                              \
        if (IN6_IS_ADDR_LOOPBACK(&(addr)->u.prefix6)) {                        \
-               char buf[PREFIX2STR_BUFFER];                                   \
-               prefix2str(addr, buf, sizeof(buf));                            \
                if (debug)                                                     \
-                       zlog_debug("Filter out Loopback: %s", buf);            \
+                       zlog_debug("Filter out Loopback: %pFX", addr);         \
                continue;                                                      \
        }
 
 #define CONTINUE_IF_ADDRESS_V4COMPAT(debug, addr)                              \
        if (IN6_IS_ADDR_V4COMPAT(&(addr)->u.prefix6)) {                        \
-               char buf[PREFIX2STR_BUFFER];                                   \
-               prefix2str(addr, buf, sizeof(buf));                            \
                if (debug)                                                     \
-                       zlog_debug("Filter out V4Compat: %s", buf);            \
+                       zlog_debug("Filter out V4Compat: %pFX", addr);         \
                continue;                                                      \
        }
 
 #define CONTINUE_IF_ADDRESS_V4MAPPED(debug, addr)                              \
        if (IN6_IS_ADDR_V4MAPPED(&(addr)->u.prefix6)) {                        \
-               char buf[PREFIX2STR_BUFFER];                                   \
-               prefix2str(addr, buf, sizeof(buf));                            \
                if (debug)                                                     \
-                       zlog_debug("Filter out V4Mapped: %s", buf);            \
+                       zlog_debug("Filter out V4Mapped: %pFX", addr);         \
                continue;                                                      \
        }
 
@@ -226,8 +217,8 @@ ospf6_lsa_create_headeronly(struct ospf6_lsa_header *header);
 extern void ospf6_lsa_delete(struct ospf6_lsa *lsa);
 extern struct ospf6_lsa *ospf6_lsa_copy(struct ospf6_lsa *);
 
-extern void ospf6_lsa_lock(struct ospf6_lsa *);
-extern struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *);
+extern struct ospf6_lsa *ospf6_lsa_lock(struct ospf6_lsa *lsa);
+extern struct ospf6_lsa *ospf6_lsa_unlock(struct ospf6_lsa *lsa);
 
 extern int ospf6_lsa_expire(struct thread *);
 extern int ospf6_lsa_refresh(struct thread *);
@@ -246,6 +237,6 @@ extern void ospf6_lsa_terminate(void);
 extern int config_write_ospf6_debug_lsa(struct vty *vty);
 extern void install_element_ospf6_debug_lsa(void);
 extern void ospf6_lsa_age_set(struct ospf6_lsa *lsa);
-extern void ospf6_flush_self_originated_lsas_now(void);
-
+extern void ospf6_flush_self_originated_lsas_now(struct ospf6 *ospf6);
+extern struct ospf6 *ospf6_get_by_lsdb(struct ospf6_lsa *lsa);
 #endif /* OSPF6_LSA_H */
index b551dbdfa6e2bededa49e0265567e3b2364d08d3..0892863cf10cae0499b4c5b5966985a60d14781b 100644 (file)
@@ -207,11 +207,7 @@ struct ospf6_lsa *ospf6_lsdb_lookup_next(uint16_t type, uint32_t id,
        ospf6_lsdb_set_key(&key, &adv_router, sizeof(adv_router));
        ospf6_lsdb_set_key(&key, &id, sizeof(id));
 
-       {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&key, buf, sizeof(buf));
-               zlog_debug("lsdb_lookup_next: key: %s", buf);
-       }
+       zlog_debug("lsdb_lookup_next: key: %pFX", &key);
 
        node = route_table_get_next(lsdb->table, &key);
 
@@ -298,12 +294,12 @@ struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend,
 
 void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb)
 {
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        if (lsdb == NULL)
                return;
 
-       for (ALL_LSDB(lsdb, lsa))
+       for (ALL_LSDB(lsdb, lsa, lsanext))
                ospf6_lsdb_remove(lsa, lsdb);
 }
 
@@ -319,9 +315,9 @@ void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa)
 int ospf6_lsdb_maxage_remover(struct ospf6_lsdb *lsdb)
 {
        int reschedule = 0;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
-       for (ALL_LSDB(lsdb, lsa)) {
+       for (ALL_LSDB(lsdb, lsa, lsanext)) {
                if (!OSPF6_LSA_IS_MAXAGE(lsa))
                        continue;
                if (lsa->retrans_count != 0) {
index 3b32e3ecf6d7138300ab8dc31d681e50cf2286a2..457e3dc4e4afeed0ddd8a5d892973553dcf0905a 100644 (file)
@@ -66,11 +66,19 @@ extern struct ospf6_lsa *ospf6_lsdb_next(const struct route_node *iterend,
        lsa;                                                                   \
        lsa = ospf6_lsdb_next(iterend, lsa)
 
-#define ALL_LSDB(lsdb, lsa)                                                    \
+/*
+ * Since we are locking the lsa in ospf6_lsdb_head
+ * and then unlocking it in lspf6_lsa_lock, when
+ * we cache the next pointer we need to increment
+ * the lock for the lsa so we don't accidently free
+ * it really early.
+ */
+#define ALL_LSDB(lsdb, lsa, lsanext)                                           \
        const struct route_node *iterend =                                     \
                ospf6_lsdb_head(lsdb, 0, 0, 0, &lsa);                          \
-       lsa;                                                                   \
-       lsa = ospf6_lsdb_next(iterend, lsa)
+       (lsa) != NULL &&ospf6_lsa_lock(lsa)                                    \
+               && ((lsanext) = ospf6_lsdb_next(iterend, (lsa)), 1);           \
+       ospf6_lsa_unlock(lsa), (lsa) = (lsanext)
 
 extern void ospf6_lsdb_remove_all(struct ospf6_lsdb *lsdb);
 extern void ospf6_lsdb_lsa_unlock(struct ospf6_lsa *lsa);
index 182faf0038f4eb28af67a94861bba901060861e4..4ed6e2a6040dbb85d932e8d43743aa7d91255870 100644 (file)
@@ -55,7 +55,7 @@
 #define OSPF6_VTY_PORT             2606
 
 /* ospf6d privileges */
-zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND};
+zebra_capabilities_t _caps_p[] = {ZCAP_NET_RAW, ZCAP_BIND, ZCAP_SYS_ADMIN};
 
 struct zebra_privs_t ospf6d_privs = {
 #if defined(FRR_USER)
@@ -68,7 +68,7 @@ struct zebra_privs_t ospf6d_privs = {
        .vty_group = VTY_GROUP,
 #endif
        .caps_p = _caps_p,
-       .cap_num_p = 2,
+       .cap_num_p = array_size(_caps_p),
        .cap_num_i = 0};
 
 /* ospf6d options, we use GNU getopt library. */
@@ -81,27 +81,28 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
 {
        struct vrf *vrf;
        struct interface *ifp;
+       struct ospf6 *ospf6;
+       struct listnode *node, *nnode;
 
        frr_early_fini();
 
-       if (ospf6) {
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
                vrf = vrf_lookup_by_id(ospf6->vrf_id);
+               ospf6_serv_close(&ospf6->fd);
+               FOR_ALL_INTERFACES (vrf, ifp)
+                       if (ifp->info != NULL)
+                               ospf6_interface_delete(ifp->info);
                ospf6_delete(ospf6);
                ospf6 = NULL;
-       } else
-               vrf = vrf_lookup_by_id(VRF_DEFAULT);
+       }
 
        bfd_gbl_exit();
 
-       FOR_ALL_INTERFACES (vrf, ifp)
-               if (ifp->info != NULL)
-                       ospf6_interface_delete(ifp->info);
 
        ospf6_message_terminate();
        ospf6_asbr_terminate();
        ospf6_lsa_terminate();
 
-       ospf6_serv_close();
        /* reverse access_list_init */
        access_list_reset();
 
@@ -216,17 +217,17 @@ int main(int argc, char *argv[], char *envp[])
        }
 
        /* OSPF6 master init. */
-       ospf6_master_init();
+       ospf6_master_init(frr_init());
 
        /* thread master */
-       master = frr_init();
+       master = om6->master;
 
        vrf_init(NULL, NULL, NULL, NULL, NULL);
        access_list_init();
        prefix_list_init();
 
        /* initialize ospf6 */
-       ospf6_init();
+       ospf6_init(master);
 
        frr_config_fork();
        frr_run(master);
index 4830b38a66614496dcafcda2d238cc6f2dd47cab..5f9953782c896201622104c686da177d8f4e213b 100644 (file)
 #include "ospf6_proto.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
+#include "ospf6_top.h"
 #include "ospf6_network.h"
 #include "ospf6_message.h"
 
-#include "ospf6_top.h"
 #include "ospf6_area.h"
 #include "ospf6_neighbor.h"
 #include "ospf6_interface.h"
@@ -781,9 +781,9 @@ static void ospf6_dbdesc_recv(struct in6_addr *src, struct in6_addr *dst,
 
        oi->db_desc_in++;
 
-       if (ntohl(oh->router_id) < ntohl(ospf6->router_id))
+       if (ntohl(oh->router_id) < ntohl(oi->area->ospf6->router_id))
                ospf6_dbdesc_recv_master(oh, on);
-       else if (ntohl(ospf6->router_id) < ntohl(oh->router_id))
+       else if (ntohl(oi->area->ospf6->router_id) < ntohl(oh->router_id))
                ospf6_dbdesc_recv_slave(oh, on);
        else {
                if (IS_OSPF6_DEBUG_MESSAGE(oh->type, RECV))
@@ -1532,10 +1532,14 @@ int ospf6_receive(struct thread *thread)
        struct iovec iovector[2];
        struct ospf6_interface *oi;
        struct ospf6_header *oh;
+       struct ospf6 *ospf6;
 
        /* add next read thread */
+       ospf6 = THREAD_ARG(thread);
        sockfd = THREAD_FD(thread);
-       thread_add_read(master, ospf6_receive, NULL, sockfd, NULL);
+
+       thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
+                       &ospf6->t_ospf6_receive);
 
        /* initialize */
        memset(&src, 0, sizeof(src));
@@ -1548,7 +1552,7 @@ int ospf6_receive(struct thread *thread)
        iovector[1].iov_len = 0;
 
        /* receive message */
-       len = ospf6_recvmsg(&src, &dst, &ifindex, iovector);
+       len = ospf6_recvmsg(&src, &dst, &ifindex, iovector, sockfd);
        if (len > iobuflen) {
                flog_err(EC_LIB_DEVELOPMENT, "Excess message read");
                return 0;
@@ -1696,9 +1700,13 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst,
        }
 
        /* send message */
-       len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector);
-       if (len != ntohs(oh->length))
-               flog_err(EC_LIB_DEVELOPMENT, "Could not send entire message");
+       if (oi->area->ospf6->fd != -1) {
+               len = ospf6_sendmsg(src, dst, oi->interface->ifindex, iovector,
+                                   oi->area->ospf6->fd);
+               if (len != ntohs(oh->length))
+                       flog_err(EC_LIB_DEVELOPMENT,
+                                "Could not send entire message");
+       }
 }
 
 static uint32_t ospf6_packet_max(struct ospf6_interface *oi)
@@ -1784,7 +1792,7 @@ int ospf6_dbdesc_send(struct thread *thread)
        struct ospf6_header *oh;
        struct ospf6_dbdesc *dbdesc;
        uint8_t *p;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
        struct in6_addr *dst;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
@@ -1825,7 +1833,7 @@ int ospf6_dbdesc_send(struct thread *thread)
        /* if this is not initial one, set LSA headers in dbdesc */
        p = (uint8_t *)((caddr_t)dbdesc + sizeof(struct ospf6_dbdesc));
        if (!CHECK_FLAG(on->dbdesc_bits, OSPF6_DBDESC_IBIT)) {
-               for (ALL_LSDB(on->dbdesc_list, lsa)) {
+               for (ALL_LSDB(on->dbdesc_list, lsa, lsanext)) {
                        ospf6_lsa_age_update_to_send(lsa,
                                                     on->ospf6_if->transdelay);
 
@@ -1859,7 +1867,7 @@ int ospf6_dbdesc_send(struct thread *thread)
 int ospf6_dbdesc_send_newone(struct thread *thread)
 {
        struct ospf6_neighbor *on;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
        unsigned int size = 0;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
@@ -1869,7 +1877,7 @@ int ospf6_dbdesc_send_newone(struct thread *thread)
           structure)
           so that ospf6_send_dbdesc () can send those LSAs */
        size = sizeof(struct ospf6_lsa_header) + sizeof(struct ospf6_dbdesc);
-       for (ALL_LSDB(on->summary_list, lsa)) {
+       for (ALL_LSDB(on->summary_list, lsa, lsanext)) {
                if (size + sizeof(struct ospf6_lsa_header)
                    > ospf6_packet_max(on->ospf6_if)) {
                        ospf6_lsdb_lsa_unlock(lsa);
@@ -1900,7 +1908,7 @@ int ospf6_lsreq_send(struct thread *thread)
        struct ospf6_header *oh;
        struct ospf6_lsreq_entry *e;
        uint8_t *p;
-       struct ospf6_lsa *lsa, *last_req;
+       struct ospf6_lsa *lsa, *lsanext, *last_req;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        on->thread_send_lsreq = (struct thread *)NULL;
@@ -1927,7 +1935,7 @@ int ospf6_lsreq_send(struct thread *thread)
 
        /* set Request entries in lsreq */
        p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header));
-       for (ALL_LSDB(on->request_list, lsa)) {
+       for (ALL_LSDB(on->request_list, lsa, lsanext)) {
                /* MTU check */
                if (p - sendbuf + sizeof(struct ospf6_lsreq_entry)
                    > ospf6_packet_max(on->ospf6_if)) {
@@ -2012,7 +2020,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread)
        struct ospf6_lsupdate *lsupdate;
        uint8_t *p;
        int lsa_cnt;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        on->thread_send_lsupdate = (struct thread *)NULL;
@@ -2037,7 +2045,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread)
 
        /* lsupdate_list lists those LSA which doesn't need to be
           retransmitted. remove those from the list */
-       for (ALL_LSDB(on->lsupdate_list, lsa)) {
+       for (ALL_LSDB(on->lsupdate_list, lsa, lsanext)) {
                /* MTU check */
                if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header))
                    > ospf6_packet_max(on->ospf6_if)) {
@@ -2089,7 +2097,7 @@ int ospf6_lsupdate_send_neighbor(struct thread *thread)
        p = (uint8_t *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate));
        lsa_cnt = 0;
 
-       for (ALL_LSDB(on->retrans_list, lsa)) {
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                /* MTU check */
                if ((p - sendbuf + (unsigned int)OSPF6_LSA_SIZE(lsa->header))
                    > ospf6_packet_max(on->ospf6_if)) {
@@ -2194,7 +2202,7 @@ int ospf6_lsupdate_send_interface(struct thread *thread)
        struct ospf6_lsupdate *lsupdate;
        uint8_t *p;
        int lsa_cnt;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
        oi->thread_send_lsupdate = (struct thread *)NULL;
@@ -2220,7 +2228,7 @@ int ospf6_lsupdate_send_interface(struct thread *thread)
        p = (uint8_t *)((caddr_t)lsupdate + sizeof(struct ospf6_lsupdate));
        lsa_cnt = 0;
 
-       for (ALL_LSDB(oi->lsupdate_list, lsa)) {
+       for (ALL_LSDB(oi->lsupdate_list, lsa, lsanext)) {
                /* MTU check */
                if ((p - sendbuf + ((unsigned int)OSPF6_LSA_SIZE(lsa->header)))
                    > ospf6_packet_max(oi)) {
@@ -2280,7 +2288,7 @@ int ospf6_lsack_send_neighbor(struct thread *thread)
        struct ospf6_neighbor *on;
        struct ospf6_header *oh;
        uint8_t *p;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
        int lsa_cnt = 0;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
@@ -2303,7 +2311,7 @@ int ospf6_lsack_send_neighbor(struct thread *thread)
 
        p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header));
 
-       for (ALL_LSDB(on->lsack_list, lsa)) {
+       for (ALL_LSDB(on->lsack_list, lsa, lsanext)) {
                /* MTU check */
                if (p - sendbuf + sizeof(struct ospf6_lsa_header)
                    > ospf6_packet_max(on->ospf6_if)) {
@@ -2358,7 +2366,7 @@ int ospf6_lsack_send_interface(struct thread *thread)
        struct ospf6_interface *oi;
        struct ospf6_header *oh;
        uint8_t *p;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
        int lsa_cnt = 0;
 
        oi = (struct ospf6_interface *)THREAD_ARG(thread);
@@ -2382,7 +2390,7 @@ int ospf6_lsack_send_interface(struct thread *thread)
 
        p = (uint8_t *)((caddr_t)oh + sizeof(struct ospf6_header));
 
-       for (ALL_LSDB(oi->lsack_list, lsa)) {
+       for (ALL_LSDB(oi->lsack_list, lsa, lsanext)) {
                /* MTU check */
                if (p - sendbuf + sizeof(struct ospf6_lsa_header)
                    > ospf6_packet_max(oi)) {
index 92a3c9e1adc5122f78be50e440879acdbe5de73e..9f13ecffa1d18b4e4e6f4da25cdf90489f78a538 100644 (file)
@@ -118,11 +118,11 @@ struct ospf6_neighbor *ospf6_neighbor_create(uint32_t router_id,
 
 void ospf6_neighbor_delete(struct ospf6_neighbor *on)
 {
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        ospf6_lsdb_remove_all(on->summary_list);
        ospf6_lsdb_remove_all(on->request_list);
-       for (ALL_LSDB(on->retrans_list, lsa)) {
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                ospf6_decrement_retrans_count(lsa);
                ospf6_lsdb_remove(lsa, on->retrans_list);
        }
@@ -293,7 +293,7 @@ int twoway_received(struct thread *thread)
 int negotiation_done(struct thread *thread)
 {
        struct ospf6_neighbor *on;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        assert(on);
@@ -307,13 +307,13 @@ int negotiation_done(struct thread *thread)
        /* clear ls-list */
        ospf6_lsdb_remove_all(on->summary_list);
        ospf6_lsdb_remove_all(on->request_list);
-       for (ALL_LSDB(on->retrans_list, lsa)) {
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                ospf6_decrement_retrans_count(lsa);
                ospf6_lsdb_remove(lsa, on->retrans_list);
        }
 
        /* Interface scoped LSAs */
-       for (ALL_LSDB(on->ospf6_if->lsdb, lsa)) {
+       for (ALL_LSDB(on->ospf6_if->lsdb, lsa, lsanext)) {
                if (OSPF6_LSA_IS_MAXAGE(lsa)) {
                        ospf6_increment_retrans_count(lsa);
                        ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
@@ -322,7 +322,7 @@ int negotiation_done(struct thread *thread)
        }
 
        /* Area scoped LSAs */
-       for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa)) {
+       for (ALL_LSDB(on->ospf6_if->area->lsdb, lsa, lsanext)) {
                if (OSPF6_LSA_IS_MAXAGE(lsa)) {
                        ospf6_increment_retrans_count(lsa);
                        ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
@@ -331,7 +331,7 @@ int negotiation_done(struct thread *thread)
        }
 
        /* AS scoped LSAs */
-       for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa)) {
+       for (ALL_LSDB(on->ospf6_if->area->ospf6->lsdb, lsa, lsanext)) {
                if (OSPF6_LSA_IS_MAXAGE(lsa)) {
                        ospf6_increment_retrans_count(lsa);
                        ospf6_lsdb_add(ospf6_lsa_copy(lsa), on->retrans_list);
@@ -427,7 +427,7 @@ int loading_done(struct thread *thread)
 int adj_ok(struct thread *thread)
 {
        struct ospf6_neighbor *on;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        assert(on);
@@ -452,7 +452,7 @@ int adj_ok(struct thread *thread)
                                            OSPF6_NEIGHBOR_EVENT_ADJ_OK);
                ospf6_lsdb_remove_all(on->summary_list);
                ospf6_lsdb_remove_all(on->request_list);
-               for (ALL_LSDB(on->retrans_list, lsa)) {
+               for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                        ospf6_decrement_retrans_count(lsa);
                        ospf6_lsdb_remove(lsa, on->retrans_list);
                }
@@ -464,7 +464,7 @@ int adj_ok(struct thread *thread)
 int seqnumber_mismatch(struct thread *thread)
 {
        struct ospf6_neighbor *on;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        assert(on);
@@ -483,7 +483,7 @@ int seqnumber_mismatch(struct thread *thread)
 
        ospf6_lsdb_remove_all(on->summary_list);
        ospf6_lsdb_remove_all(on->request_list);
-       for (ALL_LSDB(on->retrans_list, lsa)) {
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                ospf6_decrement_retrans_count(lsa);
                ospf6_lsdb_remove(lsa, on->retrans_list);
        }
@@ -501,7 +501,7 @@ int seqnumber_mismatch(struct thread *thread)
 int bad_lsreq(struct thread *thread)
 {
        struct ospf6_neighbor *on;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        assert(on);
@@ -520,7 +520,7 @@ int bad_lsreq(struct thread *thread)
 
        ospf6_lsdb_remove_all(on->summary_list);
        ospf6_lsdb_remove_all(on->request_list);
-       for (ALL_LSDB(on->retrans_list, lsa)) {
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                ospf6_decrement_retrans_count(lsa);
                ospf6_lsdb_remove(lsa, on->retrans_list);
        }
@@ -538,7 +538,7 @@ int bad_lsreq(struct thread *thread)
 int oneway_received(struct thread *thread)
 {
        struct ospf6_neighbor *on;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        on = (struct ospf6_neighbor *)THREAD_ARG(thread);
        assert(on);
@@ -555,7 +555,7 @@ int oneway_received(struct thread *thread)
 
        ospf6_lsdb_remove_all(on->summary_list);
        ospf6_lsdb_remove_all(on->request_list);
-       for (ALL_LSDB(on->retrans_list, lsa)) {
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext)) {
                ospf6_decrement_retrans_count(lsa);
                ospf6_lsdb_remove(lsa, on->retrans_list);
        }
@@ -685,7 +685,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
        char drouter[16], bdrouter[16];
        char linklocal_addr[64], duration[32];
        struct timeval now, res;
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
 
        inet_ntop(AF_INET6, &on->linklocal_addr, linklocal_addr,
                  sizeof(linklocal_addr));
@@ -715,15 +715,15 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
                (unsigned long)ntohl(on->dbdesc_seqnum));
 
        vty_out(vty, "    Summary-List: %d LSAs\n", on->summary_list->count);
-       for (ALL_LSDB(on->summary_list, lsa))
+       for (ALL_LSDB(on->summary_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        vty_out(vty, "    Request-List: %d LSAs\n", on->request_list->count);
-       for (ALL_LSDB(on->request_list, lsa))
+       for (ALL_LSDB(on->request_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        vty_out(vty, "    Retrans-List: %d LSAs\n", on->retrans_list->count);
-       for (ALL_LSDB(on->retrans_list, lsa))
+       for (ALL_LSDB(on->retrans_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        timerclear(&res);
@@ -733,7 +733,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
        vty_out(vty, "    %d Pending LSAs for DbDesc in Time %s [thread %s]\n",
                on->dbdesc_list->count, duration,
                (on->thread_send_dbdesc ? "on" : "off"));
-       for (ALL_LSDB(on->dbdesc_list, lsa))
+       for (ALL_LSDB(on->dbdesc_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        timerclear(&res);
@@ -743,7 +743,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
        vty_out(vty, "    %d Pending LSAs for LSReq in Time %s [thread %s]\n",
                on->request_list->count, duration,
                (on->thread_send_lsreq ? "on" : "off"));
-       for (ALL_LSDB(on->request_list, lsa))
+       for (ALL_LSDB(on->request_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        timerclear(&res);
@@ -754,7 +754,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
                "    %d Pending LSAs for LSUpdate in Time %s [thread %s]\n",
                on->lsupdate_list->count, duration,
                (on->thread_send_lsupdate ? "on" : "off"));
-       for (ALL_LSDB(on->lsupdate_list, lsa))
+       for (ALL_LSDB(on->lsupdate_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        timerclear(&res);
@@ -764,7 +764,7 @@ static void ospf6_neighbor_show_detail(struct vty *vty,
        vty_out(vty, "    %d Pending LSAs for LSAck in Time %s [thread %s]\n",
                on->lsack_list->count, duration,
                (on->thread_send_lsack ? "on" : "off"));
-       for (ALL_LSDB(on->lsack_list, lsa))
+       for (ALL_LSDB(on->lsack_list, lsa, lsanext))
                vty_out(vty, "      %s\n", lsa->name);
 
        ospf6_bfd_show_info(vty, on->bfd_info, 0);
@@ -786,8 +786,11 @@ DEFUN (show_ipv6_ospf6_neighbor,
        struct ospf6_area *oa;
        struct listnode *i, *j, *k;
        void (*showfunc)(struct vty *, struct ospf6_neighbor *);
+       struct ospf6 *ospf6;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        showfunc = ospf6_neighbor_show;
 
        if (argc == 5) {
@@ -831,8 +834,10 @@ DEFUN (show_ipv6_ospf6_neighbor_one,
        struct listnode *i, *j, *k;
        void (*showfunc)(struct vty *, struct ospf6_neighbor *);
        uint32_t router_id;
+       struct ospf6 *ospf6;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        showfunc = ospf6_neighbor_show_detail;
 
        if ((inet_pton(AF_INET, argv[idx_ipv4]->arg, &router_id)) != 1) {
index 9a18680b8b532c1a2fa16b430c58ab2d9fafeaae..76f98fecdd8e2deb4d520edd3ca6135cf4bbce10 100644 (file)
 #include "sockopt.h"
 #include "privs.h"
 #include "lib_errors.h"
+#include "vrf.h"
 
 #include "libospf.h"
 #include "ospf6_proto.h"
+#include "ospf6_top.h"
 #include "ospf6_network.h"
 #include "ospf6d.h"
 
-int ospf6_sock;
 struct in6_addr allspfrouters6;
 struct in6_addr alldrouters6;
 
 /* setsockopt MulticastLoop to off */
-static void ospf6_reset_mcastloop(void)
+static void ospf6_reset_mcastloop(int ospf6_sock)
 {
        unsigned int off = 0;
        if (setsockopt(ospf6_sock, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, &off,
@@ -47,19 +48,19 @@ static void ospf6_reset_mcastloop(void)
                          safe_strerror(errno));
 }
 
-static void ospf6_set_pktinfo(void)
+static void ospf6_set_pktinfo(int ospf6_sock)
 {
        setsockopt_ipv6_pktinfo(ospf6_sock, 1);
 }
 
-static void ospf6_set_transport_class(void)
+static void ospf6_set_transport_class(int ospf6_sock)
 {
 #ifdef IPTOS_PREC_INTERNETCONTROL
        setsockopt_ipv6_tclass(ospf6_sock, IPTOS_PREC_INTERNETCONTROL);
 #endif
 }
 
-static void ospf6_set_checksum(void)
+static void ospf6_set_checksum(int ospf6_sock)
 {
        int offset = 12;
 #ifndef DISABLE_IPV6_CHECKSUM
@@ -73,21 +74,30 @@ static void ospf6_set_checksum(void)
 #endif /* DISABLE_IPV6_CHECKSUM */
 }
 
-void ospf6_serv_close(void)
+void ospf6_serv_close(int *ospf6_sock)
 {
-       if (ospf6_sock > 0) {
-               close(ospf6_sock);
-               ospf6_sock = -1;
+       if (*ospf6_sock != -1) {
+               close(*ospf6_sock);
+               *ospf6_sock = -1;
                return;
        }
 }
 
 /* Make ospf6d's server socket. */
-int ospf6_serv_sock(void)
+int ospf6_serv_sock(struct ospf6 *ospf6)
 {
+       int ospf6_sock;
+
+       if (ospf6->fd != -1)
+               return -1;
+
+       if (ospf6->vrf_id == VRF_UNKNOWN)
+               return -1;
+
        frr_with_privs(&ospf6d_privs) {
 
-               ospf6_sock = socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP);
+               ospf6_sock = vrf_socket(AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP,
+                                       ospf6->vrf_id, ospf6->name);
                if (ospf6_sock < 0) {
                        zlog_warn("Network: can't create OSPF6 socket.");
                        return -1;
@@ -100,11 +110,12 @@ int ospf6_serv_sock(void)
 #else
        ospf6_set_reuseaddr();
 #endif /*1*/
-       ospf6_reset_mcastloop();
-       ospf6_set_pktinfo();
-       ospf6_set_transport_class();
-       ospf6_set_checksum();
+       ospf6_reset_mcastloop(ospf6_sock);
+       ospf6_set_pktinfo(ospf6_sock);
+       ospf6_set_transport_class(ospf6_sock);
+       ospf6_set_checksum(ospf6_sock);
 
+       ospf6->fd = ospf6_sock;
        /* setup global in6_addr, allspf6 and alldr6 for later use */
        inet_pton(AF_INET6, ALLSPFROUTERS6, &allspfrouters6);
        inet_pton(AF_INET6, ALLDROUTERS6, &alldrouters6);
@@ -113,18 +124,20 @@ int ospf6_serv_sock(void)
 }
 
 /* ospf6 set socket option */
-int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option)
+int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option, int sockfd)
 {
        struct ipv6_mreq mreq6;
        int ret;
        int bufsize = (8 * 1024 * 1024);
 
+       if (sockfd == -1)
+               return -1;
+
        assert(ifindex);
        mreq6.ipv6mr_interface = ifindex;
        memcpy(&mreq6.ipv6mr_multiaddr, group, sizeof(struct in6_addr));
 
-       ret = setsockopt(ospf6_sock, IPPROTO_IPV6, option, &mreq6,
-                        sizeof(mreq6));
+       ret = setsockopt(sockfd, IPPROTO_IPV6, option, &mreq6, sizeof(mreq6));
        if (ret < 0) {
                flog_err_sys(
                        EC_LIB_SOCKET,
@@ -133,8 +146,8 @@ int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option)
                return ret;
        }
 
-       setsockopt_so_sendbuf(ospf6_sock, bufsize);
-       setsockopt_so_recvbuf(ospf6_sock, bufsize);
+       setsockopt_so_sendbuf(sockfd, bufsize);
+       setsockopt_so_recvbuf(sockfd, bufsize);
 
        return 0;
 }
@@ -157,7 +170,7 @@ static int iov_totallen(struct iovec *iov)
 }
 
 int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
-                 ifindex_t *ifindex, struct iovec *message)
+                 ifindex_t ifindex, struct iovec *message, int ospf6_sock)
 {
        int retval;
        struct msghdr smsghdr;
@@ -170,7 +183,6 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
        struct sockaddr_in6 dst_sin6;
 
        assert(dst);
-       assert(*ifindex);
 
        memset(&cmsgbuf, 0, sizeof(cmsgbuf));
        scmsgp = (struct cmsghdr *)&cmsgbuf;
@@ -178,7 +190,7 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
        memset(&dst_sin6, 0, sizeof(struct sockaddr_in6));
 
        /* source address */
-       pktinfo->ipi6_ifindex = *ifindex;
+       pktinfo->ipi6_ifindex = ifindex;
        if (src)
                memcpy(&pktinfo->ipi6_addr, src, sizeof(struct in6_addr));
        else
@@ -190,7 +202,7 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
        dst_sin6.sin6_len = sizeof(struct sockaddr_in6);
 #endif /*SIN6_LEN*/
        memcpy(&dst_sin6.sin6_addr, dst, sizeof(struct in6_addr));
-       dst_sin6.sin6_scope_id = *ifindex;
+       dst_sin6.sin6_scope_id = ifindex;
 
        /* send control msg */
        scmsgp->cmsg_level = IPPROTO_IPV6;
@@ -209,14 +221,15 @@ int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
 
        retval = sendmsg(ospf6_sock, &smsghdr, 0);
        if (retval != iov_totallen(message))
-               zlog_warn("sendmsg failed: ifindex: %d: %s (%d)", *ifindex,
+               zlog_warn("sendmsg failed: source: %pI6 Dest: %pI6 ifindex: %d: %s (%d)",
+                         src, dst, ifindex,
                          safe_strerror(errno), errno);
 
        return retval;
 }
 
 int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst,
-                 ifindex_t *ifindex, struct iovec *message)
+                 ifindex_t *ifindex, struct iovec *message, int ospf6_sock)
 {
        int retval;
        struct msghdr rmsghdr;
index 7fe6e33ff2b724f50976861d824f325368b785d5..08d8be4445d5bf73805cfdb5b1ae522b2f023e23 100644 (file)
 #ifndef OSPF6_NETWORK_H
 #define OSPF6_NETWORK_H
 
-extern int ospf6_sock;
 extern struct in6_addr allspfrouters6;
 extern struct in6_addr alldrouters6;
 
-extern int ospf6_serv_sock(void);
-extern void ospf6_serv_close(void);
-extern int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option);
+extern int ospf6_serv_sock(struct ospf6 *ospf6);
+extern void ospf6_serv_close(int *ospf6_sock);
+extern int ospf6_sso(ifindex_t ifindex, struct in6_addr *group, int option,
+                    int sockfd);
 
-extern int ospf6_sendmsg(struct in6_addr *, struct in6_addr *, ifindex_t *,
-                        struct iovec *);
-extern int ospf6_recvmsg(struct in6_addr *, struct in6_addr *, ifindex_t *,
-                        struct iovec *);
+extern int ospf6_sendmsg(struct in6_addr *src, struct in6_addr *dst,
+                        ifindex_t ifindex, struct iovec *message,
+                        int ospf6_sock);
+extern int ospf6_recvmsg(struct in6_addr *src, struct in6_addr *dst,
+                        ifindex_t *ifindex, struct iovec *message,
+                        int ospf6_sock);
 
 #endif /* OSPF6_NETWORK_H */
index a443e4c3ba06808b024b942d0e654be0758150a9..2602854f33d8524f56525068b40373c1096c5be6 100644 (file)
@@ -296,25 +296,24 @@ void ospf6_route_zebra_copy_nexthops(struct ospf6_route *route,
 {
        struct ospf6_nexthop *nh;
        struct listnode *node;
+       struct interface *ifp;
        char buf[64];
        int i;
 
        if (route) {
                i = 0;
                for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {
+                       ifp = if_lookup_by_index_all_vrf(nh->ifindex);
                        if (IS_OSPF6_DEBUG_ZEBRA(SEND)) {
-                               const char *ifname;
                                inet_ntop(AF_INET6, &nh->address, buf,
                                          sizeof(buf));
-                               ifname = ifindex2ifname(nh->ifindex,
-                                                       ospf6->vrf_id);
                                zlog_debug("  nexthop: %s%%%.*s(%d)", buf,
-                                          IFNAMSIZ, ifname, nh->ifindex);
+                                          IFNAMSIZ, ifp->name, nh->ifindex);
                        }
                        if (i >= entries)
                                return;
 
-                       nexthops[i].vrf_id = ospf6->vrf_id;
+                       nexthops[i].vrf_id = ifp->vrf_id;
                        nexthops[i].ifindex = nh->ifindex;
                        if (!IN6_IS_ADDR_UNSPECIFIED(&nh->address)) {
                                nexthops[i].gate.ipv6 = nh->address;
@@ -550,7 +549,6 @@ ospf6_route_lookup_bestmatch(struct prefix *prefix,
 static void route_table_assert(struct ospf6_route_table *table)
 {
        struct ospf6_route *prev, *r, *next;
-       char buf[PREFIX2STR_BUFFER];
        unsigned int link_error = 0, num = 0;
 
        r = ospf6_route_head(table);
@@ -579,10 +577,9 @@ static void route_table_assert(struct ospf6_route_table *table)
                 "Something has gone wrong with ospf6_route_table[%p]", table);
        zlog_debug("table count = %d, real number = %d", table->count, num);
        zlog_debug("DUMP START");
-       for (r = ospf6_route_head(table); r; r = ospf6_route_next(r)) {
-               prefix2str(&r->prefix, buf, sizeof(buf));
-               zlog_info("%p<-[%p]->%p : %s", r->prev, r, r->next, buf);
-       }
+       for (r = ospf6_route_head(table); r; r = ospf6_route_next(r))
+               zlog_info("%p<-[%p]->%p : %pFX", r->prev, r, r->next,
+                         &r->prefix);
        zlog_debug("DUMP END");
 
        assert(link_error == 0 && num == table->count);
@@ -593,7 +590,8 @@ static void route_table_assert(struct ospf6_route_table *table)
 #endif /*DEBUG*/
 
 struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
-                                   struct ospf6_route_table *table)
+                                   struct ospf6_route_table *table,
+                                   struct ospf6 *ospf6)
 {
        struct route_node *node, *nextnode, *prevnode;
        struct ospf6_route *current = NULL;
@@ -702,7 +700,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
                ospf6_route_table_assert(table);
 
                if (table->hook_add)
-                       (*table->hook_add)(route);
+                       (*table->hook_add)(route, ospf6);
 
                return route;
        }
@@ -714,7 +712,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
                                "%s %p: route add %p cost %u: another path: prev %p, next %p node ref %u",
                                ospf6_route_table_name(table), (void *)table,
                                (void *)route, route->path.cost, (void *)prev,
-                               (void *)next, node->lock);
+                               (void *)next, route_node_get_lock_count(node));
                else if (IS_OSPF6_DEBUG_ROUTE(TABLE))
                        zlog_debug("%s: route add cost %u: another path found",
                                   ospf6_route_table_name(table),
@@ -757,7 +755,7 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
 
                SET_FLAG(route->flag, OSPF6_ROUTE_ADD);
                if (table->hook_add)
-                       (*table->hook_add)(route);
+                       (*table->hook_add)(route, ospf6);
 
                return route;
        }
@@ -823,13 +821,13 @@ struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
 
        SET_FLAG(route->flag, OSPF6_ROUTE_ADD);
        if (table->hook_add)
-               (*table->hook_add)(route);
+               (*table->hook_add)(route, ospf6);
 
        return route;
 }
 
 void ospf6_route_remove(struct ospf6_route *route,
-                       struct ospf6_route_table *table)
+                       struct ospf6_route_table *table, struct ospf6 *ospf6)
 {
        struct route_node *node;
        struct ospf6_route *current;
@@ -884,7 +882,7 @@ void ospf6_route_remove(struct ospf6_route *route,
 
        /* Note hook_remove may call ospf6_route_remove */
        if (table->hook_remove)
-               (*table->hook_remove)(route);
+               (*table->hook_remove)(route, ospf6);
 
        ospf6_route_unlock(route);
 }
@@ -1004,12 +1002,13 @@ struct ospf6_route *ospf6_route_match_next(struct prefix *prefix,
        return next;
 }
 
-void ospf6_route_remove_all(struct ospf6_route_table *table)
+void ospf6_route_remove_all(struct ospf6_route_table *table,
+                           struct ospf6 *ospf6)
 {
        struct ospf6_route *route;
        for (route = ospf6_route_head(table); route;
             route = ospf6_route_next(route))
-               ospf6_route_remove(route, table);
+               ospf6_route_remove(route, table, ospf6);
 }
 
 struct ospf6_route_table *ospf6_route_table_create(int s, int t)
@@ -1022,9 +1021,10 @@ struct ospf6_route_table *ospf6_route_table_create(int s, int t)
        return new;
 }
 
-void ospf6_route_table_delete(struct ospf6_route_table *table)
+void ospf6_route_table_delete(struct ospf6_route_table *table,
+                             struct ospf6 *ospf6)
 {
-       ospf6_route_remove_all(table);
+       ospf6_route_remove_all(table, ospf6);
        bf_free(table->idspace);
        route_table_finish(table->table);
        XFREE(MTYPE_OSPF6_ROUTE, table);
@@ -1037,12 +1037,11 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
        int i;
        char destination[PREFIX2STR_BUFFER], nexthop[64];
        char duration[64];
-       const char *ifname;
        struct timeval now, res;
        struct listnode *node;
        struct ospf6_nexthop *nh;
 
-       if (ospf6 == NULL) {
+       if (om6->ospf6 == NULL) {
                vty_out(vty, "OSPFv3 is not running\n");
                return;
        }
@@ -1063,35 +1062,34 @@ void ospf6_route_show(struct vty *vty, struct ospf6_route *route)
 
        i = 0;
        for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {
+               struct interface *ifp;
                /* nexthop */
                inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop));
-               ifname = ifindex2ifname(nh->ifindex, ospf6->vrf_id);
-
+               ifp = if_lookup_by_index_all_vrf(nh->ifindex);
                if (!i) {
                        vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n",
                                (ospf6_route_is_best(route) ? '*' : ' '),
                                OSPF6_DEST_TYPE_SUBSTR(route->type),
                                OSPF6_PATH_TYPE_SUBSTR(route->path.type),
-                               destination, nexthop, IFNAMSIZ, ifname,
+                               destination, nexthop, IFNAMSIZ, ifp->name,
                                duration);
                        i++;
                } else
                        vty_out(vty, "%c%1s %2s %-30s %-25s %6.*s %s\n", ' ',
-                               "", "", "", nexthop, IFNAMSIZ, ifname, "");
+                               "", "", "", nexthop, IFNAMSIZ, ifp->name, "");
        }
 }
 
 void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route)
 {
-       const char *ifname;
-       char destination[PREFIX2STR_BUFFER], nexthop[64];
+       char destination[PREFIX2STR_BUFFER];
        char area_id[16], id[16], adv_router[16], capa[16], options[16];
        struct timeval now, res;
        char duration[64];
        struct listnode *node;
        struct ospf6_nexthop *nh;
 
-       if (ospf6 == NULL) {
+       if (om6->ospf6 == NULL) {
                vty_out(vty, "OSPFv3 is not running\n");
                return;
        }
@@ -1168,10 +1166,11 @@ void ospf6_route_show_detail(struct vty *vty, struct ospf6_route *route)
        /* Nexthops */
        vty_out(vty, "Nexthop:\n");
        for (ALL_LIST_ELEMENTS_RO(route->nh_list, node, nh)) {
+               struct interface *ifp;
                /* nexthop */
-               inet_ntop(AF_INET6, &nh->address, nexthop, sizeof(nexthop));
-               ifname = ifindex2ifname(nh->ifindex, ospf6->vrf_id);
-               vty_out(vty, "  %s %.*s\n", nexthop, IFNAMSIZ, ifname);
+
+               ifp = if_lookup_by_index_all_vrf(nh->ifindex);
+               vty_out(vty, "  %pI6 %.*s\n", &nh->address, IFNAMSIZ, ifp->name);
        }
        vty_out(vty, "\n");
 }
index 95ba983e6bdabcc67e8c7604d747beec5f9d95a7..0b984400b56af36aab63c13f847d82e70b0a7b4a 100644 (file)
@@ -178,6 +178,7 @@ struct ospf6_route {
 #define OSPF6_ROUTE_DO_NOT_ADVERTISE 0x20
 #define OSPF6_ROUTE_WAS_REMOVED      0x40
 #define OSPF6_ROUTE_BLACKHOLE_ADDED  0x80
+struct ospf6;
 
 struct ospf6_route_table {
        int scope_type;
@@ -192,9 +193,9 @@ struct ospf6_route_table {
        bitfield_t idspace;
 
        /* hooks */
-       void (*hook_add)(struct ospf6_route *);
+       void (*hook_add)(struct ospf6_route *, struct ospf6 *);
        void (*hook_change)(struct ospf6_route *);
-       void (*hook_remove)(struct ospf6_route *);
+       void (*hook_remove)(struct ospf6_route *, struct ospf6 *);
 };
 
 #define OSPF6_SCOPE_TYPE_NONE      0
@@ -296,7 +297,6 @@ extern int ospf6_route_cmp(struct ospf6_route *ra, struct ospf6_route *rb);
 
 extern void ospf6_route_lock(struct ospf6_route *route);
 extern void ospf6_route_unlock(struct ospf6_route *route);
-
 extern struct ospf6_route *ospf6_route_lookup(struct prefix *prefix,
                                              struct ospf6_route_table *table);
 extern struct ospf6_route *
@@ -307,9 +307,11 @@ ospf6_route_lookup_bestmatch(struct prefix *prefix,
                             struct ospf6_route_table *table);
 
 extern struct ospf6_route *ospf6_route_add(struct ospf6_route *route,
-                                          struct ospf6_route_table *table);
+                                          struct ospf6_route_table *table,
+                                          struct ospf6 *ospf6);
 extern void ospf6_route_remove(struct ospf6_route *route,
-                              struct ospf6_route_table *table);
+                              struct ospf6_route_table *table,
+                              struct ospf6 *ospf6);
 
 extern struct ospf6_route *ospf6_route_head(struct ospf6_route_table *table);
 extern struct ospf6_route *ospf6_route_next(struct ospf6_route *route);
@@ -320,9 +322,10 @@ ospf6_route_match_head(struct prefix *prefix, struct ospf6_route_table *table);
 extern struct ospf6_route *ospf6_route_match_next(struct prefix *prefix,
                                                  struct ospf6_route *route);
 
-extern void ospf6_route_remove_all(struct ospf6_route_table *);
+extern void ospf6_route_remove_all(struct ospf6_route_table *, struct ospf6 *);
 extern struct ospf6_route_table *ospf6_route_table_create(int s, int t);
-extern void ospf6_route_table_delete(struct ospf6_route_table *);
+extern void ospf6_route_table_delete(struct ospf6_route_table *,
+                                    struct ospf6 *);
 extern void ospf6_route_dump(struct ospf6_route_table *table);
 
 
@@ -341,7 +344,6 @@ extern void ospf6_brouter_show(struct vty *vty, struct ospf6_route *route);
 extern int config_write_ospf6_debug_route(struct vty *vty);
 extern void install_element_ospf6_debug_route(void);
 extern void ospf6_route_init(void);
-extern void ospf6_clean(void);
 extern void ospf6_path_free(struct ospf6_path *op);
 extern struct ospf6_path *ospf6_path_dup(struct ospf6_path *path);
 extern void ospf6_copy_paths(struct list *dst, struct list *src);
index 57cc05529685a53e60d2273c5de61d29dd4287ff..3aeba3b6096b36628e356312a0554b9792f8a78a 100644 (file)
@@ -637,8 +637,10 @@ static uint8_t *ospfv3GeneralGroup(struct variable *v, oid *name,
 {
        uint16_t sum;
        uint32_t count;
-       struct ospf6_lsa *lsa = NULL;
+       struct ospf6_lsa *lsa = NULL, *lsanext;
+       struct ospf6 *ospf6;
 
+       ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
        /* Check whether the instance identifier is valid */
        if (smux_header_generic(v, name, length, exact, var_len, write_method)
            == MATCH_FAILED)
@@ -679,7 +681,7 @@ static uint8_t *ospfv3GeneralGroup(struct variable *v, oid *name,
        case OSPFv3ASSCOPELSACHECKSUMSUM:
                if (ospf6) {
                        sum = 0;
-                       for (ALL_LSDB(ospf6->lsdb, lsa))
+                       for (ALL_LSDB(ospf6->lsdb, lsa, lsanext))
                                sum += ntohs(lsa->header->checksum);
                        return SNMP_INTEGER(sum);
                }
@@ -733,7 +735,7 @@ static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length,
                                WriteMethod **write_method)
 {
        struct ospf6_area *oa, *area = NULL;
-       struct ospf6_lsa *lsa = NULL;
+       struct ospf6_lsa *lsa = NULL, *lsanext;
        uint32_t area_id = 0;
        uint32_t count;
        uint16_t sum;
@@ -741,6 +743,9 @@ static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length,
        unsigned int len;
        char a[16];
        struct ospf6_route *ro;
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
 
        if (ospf6 == NULL)
                return NULL;
@@ -808,7 +813,7 @@ static uint8_t *ospfv3AreaEntry(struct variable *v, oid *name, size_t *length,
                return SNMP_INTEGER(area->lsdb->count);
        case OSPFv3AREASCOPELSACKSUMSUM:
                sum = 0;
-               for (ALL_LSDB(area->lsdb, lsa))
+               for (ALL_LSDB(area->lsdb, lsa, lsanext))
                        sum += ntohs(lsa->header->checksum);
                return SNMP_INTEGER(sum);
        case OSPFv3AREASUMMARY:
@@ -850,6 +855,9 @@ static uint8_t *ospfv3WwLsdbEntry(struct variable *v, oid *name, size_t *length,
        struct interface *iif;
        struct ospf6_interface *oi = NULL;
        struct list *ifslist;
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
 
        if (smux_header_table(v, name, length, exact, var_len, write_method)
            == MATCH_FAILED)
@@ -1044,13 +1052,16 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length,
        ifindex_t ifindex = 0;
        unsigned int instid = 0;
        struct ospf6_interface *oi = NULL;
-       struct ospf6_lsa *lsa = NULL;
+       struct ospf6_lsa *lsa = NULL, *lsanext;
        struct interface *iif;
        struct listnode *i;
        struct list *ifslist;
        oid *offset;
        int offsetlen, len;
        uint32_t sum;
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
 
        if (smux_header_table(v, name, length, exact, var_len, write_method)
            == MATCH_FAILED)
@@ -1171,7 +1182,7 @@ static uint8_t *ospfv3IfEntry(struct variable *v, oid *name, size_t *length,
                return SNMP_INTEGER(oi->lsdb->count);
        case OSPFv3IFLINKLSACKSUMSUM:
                sum = 0;
-               for (ALL_LSDB(oi->lsdb, lsa))
+               for (ALL_LSDB(oi->lsdb, lsa, lsanext))
                        sum += ntohs(lsa->header->checksum);
                return SNMP_INTEGER(sum);
        case OSPFv3IFDEMANDNBRPROBE:
@@ -1205,6 +1216,9 @@ static uint8_t *ospfv3NbrEntry(struct variable *v, oid *name, size_t *length,
        struct list *ifslist;
        oid *offset;
        int offsetlen, len;
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_id(VRF_DEFAULT);
 
        if (smux_header_table(v, name, length, exact, var_len, write_method)
            == MATCH_FAILED)
index e5eb8d74eb7877a9aed18bbca4c5d0294729795b..4dd1d5a462e4ad88101491779ccec018a2db49a5 100644 (file)
@@ -258,7 +258,7 @@ static char *ospf6_lsdesc_backlink(struct ospf6_lsa *lsa, caddr_t lsdesc,
 }
 
 static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v,
-                              caddr_t lsdesc)
+                              caddr_t lsdesc, struct ospf6 *ospf6)
 {
        int i;
        ifindex_t ifindex;
@@ -316,11 +316,11 @@ static void ospf6_nexthop_calc(struct ospf6_vertex *w, struct ospf6_vertex *v,
 }
 
 static int ospf6_spf_install(struct ospf6_vertex *v,
-                            struct ospf6_route_table *result_table)
+                            struct ospf6_route_table *result_table,
+                            struct ospf6 *ospf6)
 {
        struct ospf6_route *route, *parent_route;
        struct ospf6_vertex *prev;
-       char pbuf[PREFIX2STR_BUFFER];
 
        if (IS_OSPF6_DEBUG_SPF(PROCESS))
                zlog_debug("SPF install %s (lsa %s) hops %d cost %d", v->name,
@@ -335,12 +335,10 @@ static int ospf6_spf_install(struct ospf6_vertex *v,
                ospf6_vertex_delete(v);
                return -1;
        } else if (route && route->path.cost == v->cost) {
-               if (IS_OSPF6_DEBUG_SPF(PROCESS)) {
-                       prefix2str(&route->prefix, pbuf, sizeof(pbuf));
+               if (IS_OSPF6_DEBUG_SPF(PROCESS))
                        zlog_debug(
-                               "  another path found to route %s lsa %s, merge",
-                               pbuf, v->lsa->name);
-               }
+                               "  another path found to route %pFX lsa %s, merge",
+                               &route->prefix, v->lsa->name);
                ospf6_spf_merge_nexthops_to_route(route, v);
 
                prev = (struct ospf6_vertex *)route->route_option;
@@ -419,11 +417,12 @@ static int ospf6_spf_install(struct ospf6_vertex *v,
                listnode_add_sort(v->parent->child_list, v);
        route->route_option = v;
 
-       ospf6_route_add(route, result_table);
+       ospf6_route_add(route, result_table, ospf6);
        return 0;
 }
 
-void ospf6_spf_table_finish(struct ospf6_route_table *result_table)
+void ospf6_spf_table_finish(struct ospf6_route_table *result_table,
+                           struct ospf6 *ospf6)
 {
        struct ospf6_route *route, *nroute;
        struct ospf6_vertex *v;
@@ -431,7 +430,7 @@ void ospf6_spf_table_finish(struct ospf6_route_table *result_table)
                nroute = ospf6_route_next(route);
                v = (struct ospf6_vertex *)route->route_option;
                ospf6_vertex_delete(v);
-               ospf6_route_remove(route, result_table);
+               ospf6_route_remove(route, result_table, ospf6);
        }
 }
 
@@ -469,7 +468,7 @@ void ospf6_spf_calculation(uint32_t router_id,
        struct ospf6_lsa *lsa;
        struct in6_addr address;
 
-       ospf6_spf_table_finish(result_table);
+       ospf6_spf_table_finish(result_table, oa->ospf6);
 
        /* Install the calculating router itself as the root of the SPF tree */
        /* construct root vertex */
@@ -498,7 +497,7 @@ void ospf6_spf_calculation(uint32_t router_id,
        while ((v = vertex_pqueue_pop(&candidate_list))) {
                /* installing may result in merging or rejecting of the vertex
                 */
-               if (ospf6_spf_install(v, result_table) < 0)
+               if (ospf6_spf_install(v, result_table, oa->ospf6) < 0)
                        continue;
 
                /* Skip overloaded routers */
@@ -544,7 +543,7 @@ void ospf6_spf_calculation(uint32_t router_id,
                                        w->nh_list,
                                        ROUTER_LSDESC_GET_IFID(lsdesc), NULL);
                        else if (w->hops == 1 && v->hops == 0)
-                               ospf6_nexthop_calc(w, v, lsdesc);
+                               ospf6_nexthop_calc(w, v, lsdesc, oa->ospf6);
                        else
                                ospf6_copy_nexthops(w->nh_list, v->nh_list);
 
@@ -915,7 +914,7 @@ int config_write_ospf6_debug_spf(struct vty *vty)
        return 0;
 }
 
-void ospf6_spf_config_write(struct vty *vty)
+void ospf6_spf_config_write(struct vty *vty, struct ospf6 *ospf6)
 {
 
        if (ospf6->spf_delay != OSPF_SPF_DELAY_DEFAULT
@@ -1082,9 +1081,9 @@ struct ospf6_lsa *ospf6_create_single_router_lsa(struct ospf6_area *area,
 
 void ospf6_remove_temp_router_lsa(struct ospf6_area *area)
 {
-       struct ospf6_lsa *lsa = NULL;
+       struct ospf6_lsa *lsa = NULL, *lsanext;
 
-       for (ALL_LSDB(area->temp_router_lsa_lsdb, lsa)) {
+       for (ALL_LSDB(area->temp_router_lsa_lsdb, lsa, lsanext)) {
                if (IS_OSPF6_DEBUG_SPF(PROCESS))
                        zlog_debug(
                                "%s Remove LSA %s lsa->lock %u lsdb count %u",
index a387d40a577e1fbda46ede28370b8028658ea68c..f288f91f57c812fe6d507dc046ffe93be478b20d 100644 (file)
@@ -139,7 +139,8 @@ static inline unsigned int ospf6_lsremove_to_spf_reason(struct ospf6_lsa *lsa)
        return (reason);
 }
 
-extern void ospf6_spf_table_finish(struct ospf6_route_table *result_table);
+extern void ospf6_spf_table_finish(struct ospf6_route_table *result_table,
+                                  struct ospf6 *ospf6);
 extern void ospf6_spf_calculation(uint32_t router_id,
                                  struct ospf6_route_table *result_table,
                                  struct ospf6_area *oa);
@@ -148,7 +149,7 @@ extern void ospf6_spf_schedule(struct ospf6 *ospf, unsigned int reason);
 extern void ospf6_spf_display_subtree(struct vty *vty, const char *prefix,
                                      int rest, struct ospf6_vertex *v);
 
-extern void ospf6_spf_config_write(struct vty *vty);
+extern void ospf6_spf_config_write(struct vty *vty, struct ospf6 *ospf6);
 extern int config_write_ospf6_debug_spf(struct vty *vty);
 extern void install_element_ospf6_debug_spf(void);
 extern void ospf6_spf_init(void);
index 6f23051dc3e32f85dedc22419d2c3ea27a4f424d..95c72290d0ce24a3f89bb03ff69002c0eec55603 100644 (file)
@@ -29,6 +29,7 @@
 #include "thread.h"
 #include "command.h"
 #include "defaults.h"
+#include "lib_errors.h"
 
 #include "ospf6_proto.h"
 #include "ospf6_message.h"
@@ -41,6 +42,7 @@
 #include "ospf6_area.h"
 #include "ospf6_interface.h"
 #include "ospf6_neighbor.h"
+#include "ospf6_network.h"
 
 #include "ospf6_flood.h"
 #include "ospf6_asbr.h"
@@ -57,17 +59,76 @@ FRR_CFG_DEFAULT_BOOL(OSPF6_LOG_ADJACENCY_CHANGES,
 )
 
 /* global ospf6d variable */
-struct ospf6 *ospf6;
 static struct ospf6_master ospf6_master;
 struct ospf6_master *om6;
 
 static void ospf6_disable(struct ospf6 *o);
 
+static void ospf6_add(struct ospf6 *ospf6)
+{
+       listnode_add(om6->ospf6, ospf6);
+}
+
+static void ospf6_del(struct ospf6 *ospf6)
+{
+       listnode_delete(om6->ospf6, ospf6);
+}
+
+const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id)
+{
+       struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+       return vrf ? vrf->name : "NIL";
+}
+
+/* Link OSPF instance to VRF. */
+void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf)
+{
+       ospf6->vrf_id = vrf->vrf_id;
+       if (vrf->info != (void *)ospf6)
+               vrf->info = (void *)ospf6;
+}
+
+/* Unlink OSPF instance from VRF. */
+void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf)
+{
+       if (vrf->info == (void *)ospf6)
+               vrf->info = NULL;
+       ospf6->vrf_id = VRF_UNKNOWN;
+}
+
+struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id)
+{
+       struct vrf *vrf = NULL;
+
+       vrf = vrf_lookup_by_id(vrf_id);
+       if (!vrf)
+               return NULL;
+       return (vrf->info) ? (struct ospf6 *)vrf->info : NULL;
+}
+
+struct ospf6 *ospf6_lookup_by_vrf_name(const char *name)
+{
+       struct ospf6 *o = NULL;
+       struct listnode *node, *nnode;
+
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, o)) {
+               if (((o->name == NULL && name == NULL)
+                    || (o->name && name && strcmp(o->name, name) == 0)))
+                       return o;
+       }
+       return NULL;
+}
+
+
 static void ospf6_top_lsdb_hook_add(struct ospf6_lsa *lsa)
 {
+       struct ospf6 *ospf6 = NULL;
+
        switch (ntohs(lsa->header->type)) {
        case OSPF6_LSTYPE_AS_EXTERNAL:
-               ospf6_asbr_lsa_add(lsa);
+               ospf6 = ospf6_get_by_lsdb(lsa);
+               ospf6_asbr_lsa_add(lsa, ospf6);
                break;
 
        default:
@@ -87,20 +148,23 @@ static void ospf6_top_lsdb_hook_remove(struct ospf6_lsa *lsa)
        }
 }
 
-static void ospf6_top_route_hook_add(struct ospf6_route *route)
+static void ospf6_top_route_hook_add(struct ospf6_route *route,
+                                    struct ospf6 *ospf6)
 {
-       ospf6_abr_originate_summary(route);
-       ospf6_zebra_route_update_add(route);
+       ospf6_abr_originate_summary(route, ospf6);
+       ospf6_zebra_route_update_add(route, ospf6);
 }
 
-static void ospf6_top_route_hook_remove(struct ospf6_route *route)
+static void ospf6_top_route_hook_remove(struct ospf6_route *route,
+                                       struct ospf6 *ospf6)
 {
        route->flag |= OSPF6_ROUTE_REMOVE;
-       ospf6_abr_originate_summary(route);
-       ospf6_zebra_route_update_remove(route);
+       ospf6_abr_originate_summary(route, ospf6);
+       ospf6_zebra_route_update_remove(route, ospf6);
 }
 
-static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
+static void ospf6_top_brouter_hook_add(struct ospf6_route *route,
+                                      struct ospf6 *ospf6)
 {
        if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
            IS_OSPF6_DEBUG_BROUTER) {
@@ -115,12 +179,14 @@ static void ospf6_top_brouter_hook_add(struct ospf6_route *route)
                           route->path.origin.adv_router,
                           listcount(route->nh_list));
        }
-       ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix));
-       ospf6_asbr_lsentry_add(route);
-       ospf6_abr_originate_summary(route);
+       ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
+                                ospf6);
+       ospf6_asbr_lsentry_add(route, ospf6);
+       ospf6_abr_originate_summary(route, ospf6);
 }
 
-static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
+static void ospf6_top_brouter_hook_remove(struct ospf6_route *route,
+                                         struct ospf6 *ospf6)
 {
        if (IS_OSPF6_DEBUG_EXAMIN(AS_EXTERNAL) ||
            IS_OSPF6_DEBUG_BROUTER) {
@@ -136,20 +202,34 @@ static void ospf6_top_brouter_hook_remove(struct ospf6_route *route)
                           listcount(route->nh_list));
        }
        route->flag |= OSPF6_ROUTE_REMOVE;
-       ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix));
-       ospf6_asbr_lsentry_remove(route);
-       ospf6_abr_originate_summary(route);
+       ospf6_abr_examin_brouter(ADV_ROUTER_IN_PREFIX(&route->prefix), route,
+                                ospf6);
+       ospf6_asbr_lsentry_remove(route, ospf6);
+       ospf6_abr_originate_summary(route, ospf6);
 }
 
-static struct ospf6 *ospf6_create(vrf_id_t vrf_id)
+static struct ospf6 *ospf6_create(const char *name)
 {
        struct ospf6 *o;
+       struct vrf *vrf = NULL;
 
        o = XCALLOC(MTYPE_OSPF6_TOP, sizeof(struct ospf6));
 
+       vrf = vrf_lookup_by_name(name);
+       if (vrf) {
+               o->vrf_id = vrf->vrf_id;
+       } else
+               o->vrf_id = VRF_UNKNOWN;
+
+       /* Freed in ospf6_delete */
+       o->name = XSTRDUP(MTYPE_OSPF6_TOP, name);
+       if (vrf)
+               ospf6_vrf_link(o, vrf);
+
+       ospf6_zebra_vrf_register(o);
+
        /* initialize */
        monotime(&o->starttime);
-       o->vrf_id = vrf_id;
        o->area_list = list_new();
        o->area_list->cmp = ospf6_area_cmp;
        o->lsdb = ospf6_lsdb_create(o);
@@ -183,12 +263,32 @@ static struct ospf6 *ospf6_create(vrf_id_t vrf_id)
        o->ref_bandwidth = OSPF6_REFERENCE_BANDWIDTH;
 
        o->distance_table = route_table_init();
+       o->fd = -1;
 
        QOBJ_REG(o, ospf6);
 
+       /* Make ospf protocol socket. */
+       ospf6_serv_sock(o);
+
        return o;
 }
 
+struct ospf6 *ospf6_instance_create(const char *name)
+{
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_create(name);
+       if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
+               SET_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES);
+       if (ospf6->router_id == 0)
+               ospf6_router_id_update(ospf6);
+       ospf6_add(ospf6);
+       thread_add_read(master, ospf6_receive, ospf6, ospf6->fd,
+                       &ospf6->t_ospf6_receive);
+
+       return ospf6;
+}
+
 void ospf6_delete(struct ospf6 *o)
 {
        struct listnode *node, *nnode;
@@ -196,8 +296,9 @@ void ospf6_delete(struct ospf6 *o)
 
        QOBJ_UNREG(o);
 
-       ospf6_flush_self_originated_lsas_now();
-       ospf6_disable(ospf6);
+       ospf6_flush_self_originated_lsas_now(o);
+       ospf6_disable(o);
+       ospf6_del(o);
 
        for (ALL_LIST_ELEMENTS(o->area_list, node, nnode, oa))
                ospf6_area_delete(oa);
@@ -208,15 +309,16 @@ void ospf6_delete(struct ospf6 *o)
        ospf6_lsdb_delete(o->lsdb);
        ospf6_lsdb_delete(o->lsdb_self);
 
-       ospf6_route_table_delete(o->route_table);
-       ospf6_route_table_delete(o->brouter_table);
+       ospf6_route_table_delete(o->route_table, o);
+       ospf6_route_table_delete(o->brouter_table, o);
 
-       ospf6_route_table_delete(o->external_table);
+       ospf6_route_table_delete(o->external_table, o);
        route_table_finish(o->external_id_table);
 
        ospf6_distance_reset(o);
        route_table_finish(o->distance_table);
 
+       XFREE(MTYPE_OSPF6_TOP, o->name);
        XFREE(MTYPE_OSPF6_TOP, o);
 }
 
@@ -235,21 +337,24 @@ static void ospf6_disable(struct ospf6 *o)
                ospf6_asbr_redistribute_reset(o->vrf_id);
 
                ospf6_lsdb_remove_all(o->lsdb);
-               ospf6_route_remove_all(o->route_table);
-               ospf6_route_remove_all(o->brouter_table);
+               ospf6_route_remove_all(o->route_table, o);
+               ospf6_route_remove_all(o->brouter_table, o);
 
                THREAD_OFF(o->maxage_remover);
                THREAD_OFF(o->t_spf_calc);
                THREAD_OFF(o->t_ase_calc);
                THREAD_OFF(o->t_distribute_update);
+               THREAD_OFF(o->t_ospf6_receive);
        }
 }
 
-void ospf6_master_init(void)
+void ospf6_master_init(struct thread_master *master)
 {
        memset(&ospf6_master, 0, sizeof(struct ospf6_master));
 
        om6 = &ospf6_master;
+       om6->ospf6 = list_new();
+       om6->master = master;
 }
 
 static int ospf6_maxage_remover(struct thread *thread)
@@ -307,7 +412,7 @@ void ospf6_maxage_remove(struct ospf6 *o)
                                 &o->maxage_remover);
 }
 
-void ospf6_router_id_update(void)
+void ospf6_router_id_update(struct ospf6 *ospf6)
 {
        if (!ospf6)
                return;
@@ -325,14 +430,12 @@ DEFUN_NOSH (router_ospf6,
        ROUTER_STR
        OSPF6_STR)
 {
-       if (ospf6 == NULL) {
-               ospf6 = ospf6_create(VRF_DEFAULT);
-               if (DFLT_OSPF6_LOG_ADJACENCY_CHANGES)
-                       SET_FLAG(ospf6->config_flags,
-                                OSPF6_LOG_ADJACENCY_CHANGES);
-               if (ospf6->router_id == 0)
-                       ospf6_router_id_update();
-       }
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       if (ospf6 == NULL)
+               ospf6 = ospf6_instance_create(VRF_DEFAULT_NAME);
+
        /* set current ospf point. */
        VTY_PUSH_CONTEXT(OSPF6_NODE, ospf6);
 
@@ -347,9 +450,13 @@ DEFUN (no_router_ospf6,
        ROUTER_STR
        OSPF6_STR)
 {
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
        if (ospf6 == NULL)
                vty_out(vty, "OSPFv3 is not configured\n");
        else {
+               ospf6_serv_close(&ospf6->fd);
                ospf6_delete(ospf6);
                ospf6 = NULL;
        }
@@ -650,13 +757,14 @@ DEFUN (ospf6_interface_area,
        "OSPF6 area ID in decimal notation\n"
       )
 {
-       VTY_DECLVAR_CONTEXT(ospf6, o);
        int idx_ifname = 1;
        int idx_ipv4 = 3;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        struct interface *ifp;
 
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
        /* find/create ospf6 interface */
        ifp = if_get_by_name(argv[idx_ifname]->arg, VRF_DEFAULT);
        oi = (struct ospf6_interface *)ifp->info;
@@ -669,7 +777,7 @@ DEFUN (ospf6_interface_area,
        }
 
        /* parse Area-ID */
-       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa);
+       OSPF6_CMD_AREA_GET(argv[idx_ipv4]->arg, oa, ospf6);
 
        /* attach interface to area */
        listnode_add(oa->if_list, oi); /* sort ?? */
@@ -678,14 +786,14 @@ DEFUN (ospf6_interface_area,
        SET_FLAG(oa->flag, OSPF6_AREA_ENABLE);
 
        /* ospf6 process is currently disabled, not much more to do */
-       if (CHECK_FLAG(o->flag, OSPF6_DISABLED))
+       if (CHECK_FLAG(ospf6->flag, OSPF6_DISABLED))
                return CMD_SUCCESS;
 
        /* start up */
        ospf6_interface_enable(oi);
 
        /* If the router is ABR, originate summary routes */
-       if (ospf6_is_router_abr(o))
+       if (ospf6_is_router_abr(ospf6))
                ospf6_abr_enable_area(oa);
 
        return CMD_SUCCESS;
@@ -761,6 +869,8 @@ DEFUN (ospf6_stub_router_admin,
        struct listnode *node;
        struct ospf6_area *oa;
 
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
        if (!CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
                for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
                        OSPF6_OPT_CLEAR(oa->options, OSPF6_OPT_V6);
@@ -783,6 +893,7 @@ DEFUN (no_ospf6_stub_router_admin,
        struct listnode *node;
        struct ospf6_area *oa;
 
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
        if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
                for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
                        OSPF6_OPT_SET(oa->options, OSPF6_OPT_V6);
@@ -922,8 +1033,10 @@ DEFUN (show_ipv6_ospf6,
        IP6_STR
        OSPF6_STR)
 {
-       OSPF6_CMD_CHECK_RUNNING();
+       struct ospf6 *ospf6;
 
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        ospf6_show(vty, ospf6);
        return CMD_SUCCESS;
 }
@@ -944,7 +1057,10 @@ DEFUN (show_ipv6_ospf6_route,
        "Detailed information\n"
        "Summary of route table\n")
 {
-       OSPF6_CMD_CHECK_RUNNING();
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
        return CMD_SUCCESS;
@@ -961,9 +1077,13 @@ DEFUN (show_ipv6_ospf6_route_match,
        "Display routes which match the specified route\n"
        "Display routes longer than the specified route\n")
 {
-       OSPF6_CMD_CHECK_RUNNING();
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
+
        return CMD_SUCCESS;
 }
 
@@ -979,7 +1099,10 @@ DEFUN (show_ipv6_ospf6_route_match_detail,
        "Detailed information\n"
        )
 {
-       OSPF6_CMD_CHECK_RUNNING();
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
        return CMD_SUCCESS;
@@ -1000,13 +1123,16 @@ DEFUN (show_ipv6_ospf6_route_type_detail,
        "Detailed information\n"
        )
 {
-       OSPF6_CMD_CHECK_RUNNING();
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        ospf6_route_table_show(vty, 4, argc, argv, ospf6->route_table);
        return CMD_SUCCESS;
 }
 
-static void ospf6_stub_router_config_write(struct vty *vty)
+static void ospf6_stub_router_config_write(struct vty *vty, struct ospf6 *ospf6)
 {
        if (CHECK_FLAG(ospf6->flag, OSPF6_STUB_ROUTER)) {
                vty_out(vty, " stub-router administrative\n");
@@ -1014,7 +1140,7 @@ static void ospf6_stub_router_config_write(struct vty *vty)
        return;
 }
 
-static int ospf6_distance_config_write(struct vty *vty)
+static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
 {
        struct route_node *rn;
        struct ospf6_distance *odistance;
@@ -1037,67 +1163,67 @@ static int ospf6_distance_config_write(struct vty *vty)
        }
 
        for (rn = route_top(ospf6->distance_table); rn; rn = route_next(rn))
-               if ((odistance = rn->info) != NULL) {
-                       char buf[PREFIX_STRLEN];
-
-                       vty_out(vty, " distance %u %s %s\n",
-                               odistance->distance,
-                               prefix2str(&rn->p, buf, sizeof(buf)),
+               if ((odistance = rn->info) != NULL)
+                       vty_out(vty, " distance %u %pFX %s\n",
+                               odistance->distance, &rn->p,
                                odistance->access_list ? odistance->access_list
                                                       : "");
-               }
        return 0;
 }
 
 /* OSPF configuration write function. */
 static int config_write_ospf6(struct vty *vty)
 {
-       char router_id[16];
        struct listnode *j, *k;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
+       struct ospf6 *ospf6;
+       struct listnode *node, *nnode;
 
        /* OSPFv3 configuration. */
-       if (ospf6 == NULL)
+       if (om6 == NULL)
                return CMD_SUCCESS;
 
-       inet_ntop(AF_INET, &ospf6->router_id_static, router_id,
-                 sizeof(router_id));
-       vty_out(vty, "router ospf6\n");
-       if (ospf6->router_id_static != 0)
-               vty_out(vty, " ospf6 router-id %s\n", router_id);
-
-       /* log-adjacency-changes flag print. */
-       if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_CHANGES)) {
-               if (CHECK_FLAG(ospf6->config_flags, OSPF6_LOG_ADJACENCY_DETAIL))
-                       vty_out(vty, " log-adjacency-changes detail\n");
-               else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
-                       vty_out(vty, " log-adjacency-changes\n");
-       } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
-               vty_out(vty, " no log-adjacency-changes\n");
-       }
+       for (ALL_LIST_ELEMENTS(om6->ospf6, node, nnode, ospf6)) {
+               vty_out(vty, "router ospf6\n");
+               if (ospf6->router_id_static != 0)
+                       vty_out(vty, " ospf6 router-id %pI4\n",
+                               &ospf6->router_id_static);
+
+               /* log-adjacency-changes flag print. */
+               if (CHECK_FLAG(ospf6->config_flags,
+                              OSPF6_LOG_ADJACENCY_CHANGES)) {
+                       if (CHECK_FLAG(ospf6->config_flags,
+                                      OSPF6_LOG_ADJACENCY_DETAIL))
+                               vty_out(vty, " log-adjacency-changes detail\n");
+                       else if (!SAVE_OSPF6_LOG_ADJACENCY_CHANGES)
+                               vty_out(vty, " log-adjacency-changes\n");
+               } else if (SAVE_OSPF6_LOG_ADJACENCY_CHANGES) {
+                       vty_out(vty, " no log-adjacency-changes\n");
+               }
 
-       if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
-               vty_out(vty, " auto-cost reference-bandwidth %d\n",
-                       ospf6->ref_bandwidth);
-
-       /* LSA timers print. */
-       if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
-               vty_out(vty, " timers lsa min-arrival %d\n",
-                       ospf6->lsa_minarrival);
-
-       ospf6_stub_router_config_write(vty);
-       ospf6_redistribute_config_write(vty);
-       ospf6_area_config_write(vty);
-       ospf6_spf_config_write(vty);
-       ospf6_distance_config_write(vty);
-
-       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
-               for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
-                       vty_out(vty, " interface %s area %s\n",
-                               oi->interface->name, oa->name);
+               if (ospf6->ref_bandwidth != OSPF6_REFERENCE_BANDWIDTH)
+                       vty_out(vty, " auto-cost reference-bandwidth %d\n",
+                               ospf6->ref_bandwidth);
+
+               /* LSA timers print. */
+               if (ospf6->lsa_minarrival != OSPF_MIN_LS_ARRIVAL)
+                       vty_out(vty, " timers lsa min-arrival %d\n",
+                               ospf6->lsa_minarrival);
+
+               ospf6_stub_router_config_write(vty, ospf6);
+               ospf6_redistribute_config_write(vty, ospf6);
+               ospf6_area_config_write(vty, ospf6);
+               ospf6_spf_config_write(vty, ospf6);
+               ospf6_distance_config_write(vty, ospf6);
+
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
+                       for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
+                               vty_out(vty, " interface %s area %s\n",
+                                       oi->interface->name, oa->name);
+               }
+               vty_out(vty, "!\n");
        }
-       vty_out(vty, "!\n");
        return 0;
 }
 
index 806b4da1cfbc80d0a4ca75521ad4c0291777037a..52e1d7ee2b847d8207ad65e2fc5955593456cb72 100644 (file)
 
 #include "qobj.h"
 #include "routemap.h"
-
 struct ospf6_master {
 
+       /* OSPFv3 instance. */
+       struct list *ospf6;
+       /* OSPFv3 thread master. */
+       struct thread_master *master;
        in_addr_t zebra_router_id;
 };
 
@@ -40,6 +43,8 @@ struct ospf6 {
        /* The relevant vrf_id */
        vrf_id_t vrf_id;
 
+       char *name; /* VRF name */
+
        /* my router id */
        in_addr_t router_id;
 
@@ -92,11 +97,13 @@ struct ospf6 {
        struct timeval ts_spf_duration; /* Execution time of last SPF */
        unsigned int last_spf_reason;   /* Last SPF reason */
 
+       int fd;
        /* Threads */
        struct thread *t_spf_calc; /* SPF calculation timer. */
        struct thread *t_ase_calc; /* ASE calculation timer. */
        struct thread *maxage_remover;
        struct thread *t_distribute_update; /* Distirbute update timer. */
+       struct thread *t_ospf6_receive; /* OSPF6 receive timer */
 
        uint32_t ref_bandwidth;
 
@@ -124,11 +131,17 @@ extern struct ospf6 *ospf6;
 extern struct ospf6_master *om6;
 
 /* prototypes */
-extern void ospf6_master_init(void);
+extern void ospf6_master_init(struct thread_master *master);
 extern void ospf6_top_init(void);
 extern void ospf6_delete(struct ospf6 *o);
-extern void ospf6_router_id_update(void);
+extern void ospf6_router_id_update(struct ospf6 *ospf6);
 
 extern void ospf6_maxage_remove(struct ospf6 *o);
+extern struct ospf6 *ospf6_instance_create(const char *name);
+void ospf6_vrf_link(struct ospf6 *ospf6, struct vrf *vrf);
+void ospf6_vrf_unlink(struct ospf6 *ospf6, struct vrf *vrf);
+struct ospf6 *ospf6_lookup_by_vrf_id(vrf_id_t vrf_id);
+struct ospf6 *ospf6_lookup_by_vrf_name(const char *name);
+const char *ospf6_vrf_id_to_name(vrf_id_t vrf_id);
 
 #endif /* OSPF6_TOP_H */
index 62e0e149b86e51c6e21e5c699c88d03379c5ca76..b6c712176a5b4d8eea39d37c718233c56dee2c82 100644 (file)
@@ -39,6 +39,7 @@
 #include "ospf6_asbr.h"
 #include "ospf6_zebra.h"
 #include "ospf6d.h"
+#include "ospf6_area.h"
 
 DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance")
 
@@ -47,16 +48,49 @@ unsigned char conf_debug_ospf6_zebra = 0;
 /* information about zebra. */
 struct zclient *zclient = NULL;
 
+void ospf6_zebra_vrf_register(struct ospf6 *ospf6)
+{
+       if (!zclient || zclient->sock < 0 || !ospf6)
+               return;
+
+       if (ospf6->vrf_id != VRF_UNKNOWN) {
+               if (IS_OSPF6_DEBUG_ZEBRA(RECV)) {
+                       zlog_debug("%s: Register VRF %s id %u", __func__,
+                                  ospf6_vrf_id_to_name(ospf6->vrf_id),
+                                  ospf6->vrf_id);
+               }
+               zclient_send_reg_requests(zclient, ospf6->vrf_id);
+       }
+}
+
+void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6)
+{
+       if (!zclient || zclient->sock < 0 || !ospf6)
+               return;
+
+       if (ospf6->vrf_id != VRF_DEFAULT && ospf6->vrf_id != VRF_UNKNOWN) {
+               if (IS_OSPF6_DEBUG_ZEBRA(RECV)) {
+                       zlog_debug("%s: De-Register VRF %s id %u to Zebra.",
+                                  __func__,
+                                  ospf6_vrf_id_to_name(ospf6->vrf_id),
+                                  ospf6->vrf_id);
+               }
+               /* Deregister for router-id, interfaces,
+                * redistributed routes. */
+               zclient_send_dereg_requests(zclient, ospf6->vrf_id);
+       }
+}
+
 /* Router-id update message from zebra. */
 static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
 {
        struct prefix router_id;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *o;
 
        zebra_router_id_update_read(zclient->ibuf, &router_id);
 
        om6->zebra_router_id = router_id.u.prefix4.s_addr;
-
+       o = ospf6_lookup_by_vrf_id(vrf_id);
        if (o == NULL)
                return 0;
 
@@ -69,7 +103,7 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
                                     INET_ADDRSTRLEN));
        }
 
-       ospf6_router_id_update();
+       ospf6_router_id_update(o);
 
        return 0;
 }
@@ -99,7 +133,6 @@ void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id)
 static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
 {
        struct connected *c;
-       char buf[128];
 
        c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
                                         zclient->ibuf, vrf_id);
@@ -107,11 +140,9 @@ static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
                return 0;
 
        if (IS_OSPF6_DEBUG_ZEBRA(RECV))
-               zlog_debug("Zebra Interface address add: %s %5s %s/%d",
+               zlog_debug("Zebra Interface address add: %s %5s %pFX",
                           c->ifp->name, prefix_family_str(c->address),
-                          inet_ntop(c->address->family, &c->address->u.prefix,
-                                    buf, sizeof(buf)),
-                          c->address->prefixlen);
+                          c->address);
 
        if (c->address->family == AF_INET6) {
                ospf6_interface_state_update(c->ifp);
@@ -123,7 +154,6 @@ static int ospf6_zebra_if_address_update_add(ZAPI_CALLBACK_ARGS)
 static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS)
 {
        struct connected *c;
-       char buf[128];
 
        c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
                                         zclient->ibuf, vrf_id);
@@ -131,11 +161,9 @@ static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS)
                return 0;
 
        if (IS_OSPF6_DEBUG_ZEBRA(RECV))
-               zlog_debug("Zebra Interface address delete: %s %5s %s/%d",
+               zlog_debug("Zebra Interface address delete: %s %5s %pFX",
                           c->ifp->name, prefix_family_str(c->address),
-                          inet_ntop(c->address->family, &c->address->u.prefix,
-                                    buf, sizeof(buf)),
-                          c->address->prefixlen);
+                          c->address);
 
        if (c->address->family == AF_INET6) {
                ospf6_interface_connected_route_update(c->ifp);
@@ -152,6 +180,9 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
        struct zapi_route api;
        unsigned long ifindex;
        struct in6_addr *nexthop;
+       struct ospf6 *ospf6;
+
+       ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
 
        if (ospf6 == NULL)
                return 0;
@@ -169,25 +200,21 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
        ifindex = api.nexthops[0].ifindex;
        nexthop = &api.nexthops[0].gate.ipv6;
 
-       if (IS_OSPF6_DEBUG_ZEBRA(RECV)) {
-               char prefixstr[PREFIX2STR_BUFFER], nexthopstr[128];
-
-               prefix2str(&api.prefix, prefixstr, sizeof(prefixstr));
-               inet_ntop(AF_INET6, nexthop, nexthopstr, sizeof(nexthopstr));
-
+       if (IS_OSPF6_DEBUG_ZEBRA(RECV))
                zlog_debug(
-                       "Zebra Receive route %s: %s %s nexthop %s ifindex %ld tag %" ROUTE_TAG_PRI,
+                       "Zebra Receive route %s: %s %pFX nexthop %pI6 ifindex %ld tag %" ROUTE_TAG_PRI,
                        (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD ? "add"
                                                             : "delete"),
-                       zebra_route_string(api.type), prefixstr, nexthopstr,
+                       zebra_route_string(api.type), &api.prefix, nexthop,
                        ifindex, api.tag);
-       }
 
        if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
                ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix,
-                                           api.nexthop_num, nexthop, api.tag);
+                                           api.nexthop_num, nexthop, api.tag,
+                                           ospf6);
        else
-               ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix);
+               ospf6_asbr_redistribute_remove(api.type, ifindex, &api.prefix,
+                                              ospf6);
 
        return 0;
 }
@@ -222,19 +249,17 @@ DEFUN (show_zebra,
 
 #define ADD    0
 #define REM    1
-static void ospf6_zebra_route_update(int type, struct ospf6_route *request)
+static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
+                                    struct ospf6 *ospf6)
 {
        struct zapi_route api;
-       char buf[PREFIX2STR_BUFFER];
        int nhcount;
        int ret = 0;
        struct prefix *dest;
 
-       if (IS_OSPF6_DEBUG_ZEBRA(SEND)) {
-               prefix2str(&request->prefix, buf, sizeof(buf));
-               zlog_debug("Send %s route: %s",
-                          (type == REM ? "remove" : "add"), buf);
-       }
+       if (IS_OSPF6_DEBUG_ZEBRA(SEND))
+               zlog_debug("Send %s route: %pFX",
+                          (type == REM ? "remove" : "add"), &request->prefix);
 
        if (zclient->sock < 0) {
                if (IS_OSPF6_DEBUG_ZEBRA(SEND))
@@ -295,8 +320,8 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request)
        }
 
        SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
-       api.distance =
-               ospf6_distance_apply((struct prefix_ipv6 *)dest, request);
+       api.distance = ospf6_distance_apply((struct prefix_ipv6 *)dest, request,
+                                           ospf6);
 
        if (type == REM)
                ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
@@ -312,20 +337,21 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request)
        return;
 }
 
-void ospf6_zebra_route_update_add(struct ospf6_route *request)
+void ospf6_zebra_route_update_add(struct ospf6_route *request,
+                                 struct ospf6 *ospf6)
 {
-       ospf6_zebra_route_update(ADD, request);
+       ospf6_zebra_route_update(ADD, request, ospf6);
 }
 
-void ospf6_zebra_route_update_remove(struct ospf6_route *request)
+void ospf6_zebra_route_update_remove(struct ospf6_route *request,
+                                    struct ospf6 *ospf6)
 {
-       ospf6_zebra_route_update(REM, request);
+       ospf6_zebra_route_update(REM, request, ospf6);
 }
 
-void ospf6_zebra_add_discard(struct ospf6_route *request)
+void ospf6_zebra_add_discard(struct ospf6_route *request, struct ospf6 *ospf6)
 {
        struct zapi_route api;
-       char buf[INET6_ADDRSTRLEN];
        struct prefix *dest = &request->prefix;
 
        if (!CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
@@ -339,26 +365,21 @@ void ospf6_zebra_add_discard(struct ospf6_route *request)
                zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
 
                if (IS_OSPF6_DEBUG_ZEBRA(SEND))
-                       zlog_debug("Zebra: Route add discard %s/%d",
-                                  inet_ntop(AF_INET6, &dest->u.prefix6, buf,
-                                            INET6_ADDRSTRLEN),
-                                  dest->prefixlen);
+                       zlog_debug("Zebra: Route add discard %pFX", dest);
 
                SET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
        } else {
                if (IS_OSPF6_DEBUG_ZEBRA(SEND))
                        zlog_debug(
-                               "Zebra: Blackhole route present already %s/%d",
-                               inet_ntop(AF_INET6, &dest->u.prefix6, buf,
-                                         INET6_ADDRSTRLEN),
-                               dest->prefixlen);
+                               "Zebra: Blackhole route present already %pFX",
+                               dest);
        }
 }
 
-void ospf6_zebra_delete_discard(struct ospf6_route *request)
+void ospf6_zebra_delete_discard(struct ospf6_route *request,
+                               struct ospf6 *ospf6)
 {
        struct zapi_route api;
-       char buf[INET6_ADDRSTRLEN];
        struct prefix *dest = &request->prefix;
 
        if (CHECK_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED)) {
@@ -372,19 +393,14 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request)
                zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 
                if (IS_OSPF6_DEBUG_ZEBRA(SEND))
-                       zlog_debug("Zebra: Route delete discard %s/%d",
-                                  inet_ntop(AF_INET6, &dest->u.prefix6, buf,
-                                            INET6_ADDRSTRLEN),
-                                  dest->prefixlen);
+                       zlog_debug("Zebra: Route delete discard %pFX", dest);
 
                UNSET_FLAG(request->flag, OSPF6_ROUTE_BLACKHOLE_ADDED);
        } else {
                if (IS_OSPF6_DEBUG_ZEBRA(SEND))
                        zlog_debug(
-                               "Zebra: Blackhole route already deleted %s/%d",
-                               inet_ntop(AF_INET6, &dest->u.prefix6, buf,
-                                         INET6_ADDRSTRLEN),
-                               dest->prefixlen);
+                               "Zebra: Blackhole route already deleted %pFX",
+                               dest);
        }
 }
 
@@ -489,7 +505,8 @@ void ospf6_distance_reset(struct ospf6 *o)
                }
 }
 
-uint8_t ospf6_distance_apply(struct prefix_ipv6 *p, struct ospf6_route * or)
+uint8_t ospf6_distance_apply(struct prefix_ipv6 *p, struct ospf6_route * or,
+                            struct ospf6 *ospf6)
 {
        struct ospf6 *o;
 
index d23268303aba319c51c8e244f9d2d8196299aeff..5f340924b9c522b791529bdede268fd62d8b38ca 100644 (file)
@@ -41,21 +41,26 @@ struct ospf6_distance {
 };
 
 extern struct zclient *zclient;
+struct ospf6;
 
-extern void ospf6_zebra_route_update_add(struct ospf6_route *request);
-extern void ospf6_zebra_route_update_remove(struct ospf6_route *request);
+extern void ospf6_zebra_route_update_add(struct ospf6_route *request,
+                                        struct ospf6 *ospf6);
+extern void ospf6_zebra_route_update_remove(struct ospf6_route *request,
+                                           struct ospf6 *ospf6);
 
 extern void ospf6_zebra_redistribute(int, vrf_id_t vrf_id);
 extern void ospf6_zebra_no_redistribute(int, vrf_id_t vrf_id);
 #define ospf6_zebra_is_redistribute(type, vrf_id)                              \
        vrf_bitmap_check(zclient->redist[AFI_IP6][type], vrf_id)
 extern void ospf6_zebra_init(struct thread_master *);
-extern void ospf6_zebra_add_discard(struct ospf6_route *request);
-extern void ospf6_zebra_delete_discard(struct ospf6_route *request);
+extern void ospf6_zebra_add_discard(struct ospf6_route *request,
+                                   struct ospf6 *ospf6);
+extern void ospf6_zebra_delete_discard(struct ospf6_route *request,
+                                      struct ospf6 *ospf6);
 
-struct ospf6;
 extern void ospf6_distance_reset(struct ospf6 *);
-extern uint8_t ospf6_distance_apply(struct prefix_ipv6 *, struct ospf6_route *);
+extern uint8_t ospf6_distance_apply(struct prefix_ipv6 *, struct ospf6_route *,
+                                   struct ospf6 *);
 
 extern int ospf6_distance_set(struct vty *, struct ospf6 *, const char *,
                              const char *, const char *);
@@ -64,5 +69,6 @@ extern int ospf6_distance_unset(struct vty *, struct ospf6 *, const char *,
 
 extern int config_write_ospf6_debug_zebra(struct vty *vty);
 extern void install_element_ospf6_debug_zebra(void);
-
+extern void ospf6_zebra_vrf_register(struct ospf6 *ospf6);
+extern void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6);
 #endif /*OSPF6_ZEBRA_H*/
index 17e33902d9a18d9f06dbfc73a899e54b99756f67..fe519d0a26caffc97e881fa53ba51996251d9011 100644 (file)
@@ -27,6 +27,7 @@
 #include "plist.h"
 
 #include "ospf6_proto.h"
+#include "ospf6_top.h"
 #include "ospf6_network.h"
 #include "ospf6_lsa.h"
 #include "ospf6_lsdb.h"
@@ -34,7 +35,6 @@
 #include "ospf6_route.h"
 #include "ospf6_zebra.h"
 #include "ospf6_spf.h"
-#include "ospf6_top.h"
 #include "ospf6_area.h"
 #include "ospf6_interface.h"
 #include "ospf6_neighbor.h"
@@ -168,20 +168,22 @@ DEFUN (show_ipv6_ospf6_database,
        int idx_level = 4;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        level = parse_show_level(idx_level, argc, argv);
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                ospf6_lsdb_show(vty, level, NULL, NULL, NULL, oa->lsdb);
        }
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                        vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
                                oa->name);
@@ -190,7 +192,7 @@ DEFUN (show_ipv6_ospf6_database,
        }
 
        vty_out(vty, AS_LSDB_TITLE_FORMAT);
-       ospf6_lsdb_show(vty, level, NULL, NULL, NULL, o->lsdb);
+       ospf6_lsdb_show(vty, level, NULL, NULL, NULL, ospf6->lsdb);
 
        vty_out(vty, "\n");
        return CMD_SUCCESS;
@@ -221,19 +223,21 @@ DEFUN (show_ipv6_ospf6_database_type,
        int idx_level = 5;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        type = parse_type_spec(idx_lsa, argc, argv);
        level = parse_show_level(idx_level, argc, argv);
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, NULL, NULL,
                                        oa->lsdb);
@@ -241,7 +245,7 @@ DEFUN (show_ipv6_ospf6_database_type,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -253,7 +257,7 @@ DEFUN (show_ipv6_ospf6_database_type,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, NULL, NULL, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, NULL, NULL, ospf6->lsdb);
                break;
 
        default:
@@ -283,24 +287,26 @@ DEFUN (show_ipv6_ospf6_database_id,
        int idx_level = 6;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint32_t id = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        if (argv[idx_ipv4]->type == IPV4_TKN)
                inet_pton(AF_INET, argv[idx_ipv4]->arg, &id);
 
        level = parse_show_level(idx_level, argc, argv);
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                ospf6_lsdb_show(vty, level, NULL, &id, NULL, oa->lsdb);
        }
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                        vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
                                oa->name);
@@ -309,7 +315,7 @@ DEFUN (show_ipv6_ospf6_database_id,
        }
 
        vty_out(vty, AS_LSDB_TITLE_FORMAT);
-       ospf6_lsdb_show(vty, level, NULL, &id, NULL, o->lsdb);
+       ospf6_lsdb_show(vty, level, NULL, &id, NULL, ospf6->lsdb);
 
        vty_out(vty, "\n");
        return CMD_SUCCESS;
@@ -334,21 +340,23 @@ DEFUN (show_ipv6_ospf6_database_router,
        int idx_level = 7;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router);
        level = parse_show_level(idx_level, argc, argv);
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb);
        }
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                        vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
                                oa->name);
@@ -358,7 +366,7 @@ DEFUN (show_ipv6_ospf6_database_router,
        }
 
        vty_out(vty, AS_LSDB_TITLE_FORMAT);
-       ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, o->lsdb);
+       ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, ospf6->lsdb);
 
        vty_out(vty, "\n");
        return CMD_SUCCESS;
@@ -379,15 +387,18 @@ DEFUN_HIDDEN (show_ipv6_ospf6_database_aggr_router,
        uint16_t type = htons(OSPF6_LSTYPE_ROUTER);
        int idx_ipv4 = 6;
        struct listnode *i;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_lsdb *lsdb;
        uint32_t adv_router = 0;
 
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
+
        inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router);
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
-               if (adv_router == o->router_id)
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
+               if (adv_router == ospf6->router_id)
                        lsdb = oa->lsdb_self;
                else
                        lsdb = oa->lsdb;
@@ -435,13 +446,15 @@ DEFUN (show_ipv6_ospf6_database_type_id,
        int idx_level = 7;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t id = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        type = parse_type_spec(idx_lsa, argc, argv);
        inet_pton(AF_INET, argv[idx_ipv4]->arg, &id);
@@ -449,14 +462,14 @@ DEFUN (show_ipv6_ospf6_database_type_id,
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, &id, NULL, oa->lsdb);
                }
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -468,7 +481,7 @@ DEFUN (show_ipv6_ospf6_database_type_id,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, &id, NULL, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, &id, NULL, ospf6->lsdb);
                break;
 
        default:
@@ -509,21 +522,22 @@ DEFUN (show_ipv6_ospf6_database_type_router,
        int idx_level = 7;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
 
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        type = parse_type_spec(idx_lsa, argc, argv);
        inet_pton(AF_INET, argv[idx_ipv4]->arg, &adv_router);
        level = parse_show_level(idx_level, argc, argv);
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
                                        oa->lsdb);
@@ -531,7 +545,7 @@ DEFUN (show_ipv6_ospf6_database_type_router,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -543,7 +557,8 @@ DEFUN (show_ipv6_ospf6_database_type_router,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
+                               ospf6->lsdb);
                break;
 
        default:
@@ -576,23 +591,24 @@ DEFUN (show_ipv6_ospf6_database_id_router,
        int idx_level = 7;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint32_t id = 0;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
        inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
        level = parse_show_level(idx_level, argc, argv);
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb);
        }
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                        vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
                                oa->name);
@@ -602,7 +618,7 @@ DEFUN (show_ipv6_ospf6_database_id_router,
        }
 
        vty_out(vty, AS_LSDB_TITLE_FORMAT);
-       ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, o->lsdb);
+       ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, ospf6->lsdb);
 
        vty_out(vty, "\n");
        return CMD_SUCCESS;
@@ -629,23 +645,25 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
        int idx_level = 8;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint32_t id = 0;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
        inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
        level = parse_show_level(idx_level, argc, argv);
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, oa->lsdb);
        }
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                        vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
                                oa->name);
@@ -655,7 +673,7 @@ DEFUN (show_ipv6_ospf6_database_adv_router_linkstate_id,
        }
 
        vty_out(vty, AS_LSDB_TITLE_FORMAT);
-       ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, o->lsdb);
+       ospf6_lsdb_show(vty, level, NULL, &id, &adv_router, ospf6->lsdb);
 
        vty_out(vty, "\n");
        return CMD_SUCCESS;
@@ -688,14 +706,16 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
        int idx_level = 7;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t id = 0;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        type = parse_type_spec(idx_lsa, argc, argv);
        inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
@@ -704,7 +724,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
                                        oa->lsdb);
@@ -712,7 +732,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -724,7 +744,8 @@ DEFUN (show_ipv6_ospf6_database_type_id_router,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
+                               ospf6->lsdb);
                break;
 
        default:
@@ -766,14 +787,16 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
        int idx_level = 9;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t id = 0;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        type = parse_type_spec(idx_lsa, argc, argv);
        inet_pton(AF_INET, argv[idx_adv_rtr]->arg, &adv_router);
@@ -782,7 +805,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
                                        oa->lsdb);
@@ -790,7 +813,7 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -802,7 +825,8 @@ DEFUN (show_ipv6_ospf6_database_type_adv_router_linkstate_id,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
+                               ospf6->lsdb);
                break;
 
        default:
@@ -829,21 +853,22 @@ DEFUN (show_ipv6_ospf6_database_self_originated,
        int idx_level = 5;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        level = parse_show_level(idx_level, argc, argv);
-       adv_router = o->router_id;
+       adv_router = ospf6->router_id;
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, oa->lsdb);
        }
 
-       for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+       for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                        vty_out(vty, IF_LSDB_TITLE_FORMAT, oi->interface->name,
                                oa->name);
@@ -853,7 +878,7 @@ DEFUN (show_ipv6_ospf6_database_self_originated,
        }
 
        vty_out(vty, AS_LSDB_TITLE_FORMAT);
-       ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, o->lsdb);
+       ospf6_lsdb_show(vty, level, NULL, NULL, &adv_router, ospf6->lsdb);
 
        vty_out(vty, "\n");
        return CMD_SUCCESS;
@@ -885,22 +910,22 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
        int idx_level = 6;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t adv_router = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
-
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        type = parse_type_spec(idx_lsa, argc, argv);
        level = parse_show_level(idx_level, argc, argv);
 
-       adv_router = o->router_id;
+       adv_router = ospf6->router_id;
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
                                        oa->lsdb);
@@ -908,7 +933,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -920,7 +945,8 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, NULL, &adv_router, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, NULL, &adv_router,
+                               ospf6->lsdb);
                break;
 
        default:
@@ -960,23 +986,23 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
        int idx_level = 8;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t adv_router = 0;
        uint32_t id = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
-
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        type = parse_type_spec(idx_lsa, argc, argv);
        inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
        level = parse_show_level(idx_level, argc, argv);
-       adv_router = o->router_id;
+       adv_router = ospf6->router_id;
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
                                        oa->lsdb);
@@ -984,7 +1010,7 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -996,7 +1022,8 @@ DEFUN (show_ipv6_ospf6_database_type_self_originated_linkstate_id,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
+                               ospf6->lsdb);
                break;
 
        default:
@@ -1035,23 +1062,23 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
        int idx_level = 7;
        int level;
        struct listnode *i, *j;
-       struct ospf6 *o = ospf6;
+       struct ospf6 *ospf6;
        struct ospf6_area *oa;
        struct ospf6_interface *oi;
        uint16_t type = 0;
        uint32_t adv_router = 0;
        uint32_t id = 0;
 
-       OSPF6_CMD_CHECK_RUNNING();
-
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        type = parse_type_spec(idx_lsa, argc, argv);
        inet_pton(AF_INET, argv[idx_ls_id]->arg, &id);
        level = parse_show_level(idx_level, argc, argv);
-       adv_router = o->router_id;
+       adv_router = ospf6->router_id;
 
        switch (OSPF6_LSA_SCOPE(type)) {
        case OSPF6_SCOPE_AREA:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        vty_out(vty, AREA_LSDB_TITLE_FORMAT, oa->name);
                        ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
                                        oa->lsdb);
@@ -1059,7 +1086,7 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
                break;
 
        case OSPF6_SCOPE_LINKLOCAL:
-               for (ALL_LIST_ELEMENTS_RO(o->area_list, i, oa)) {
+               for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, i, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, j, oi)) {
                                vty_out(vty, IF_LSDB_TITLE_FORMAT,
                                        oi->interface->name, oa->name);
@@ -1071,7 +1098,8 @@ DEFUN (show_ipv6_ospf6_database_type_id_self_originated,
 
        case OSPF6_SCOPE_AS:
                vty_out(vty, AS_LSDB_TITLE_FORMAT);
-               ospf6_lsdb_show(vty, level, &type, &id, &adv_router, o->lsdb);
+               ospf6_lsdb_show(vty, level, &type, &id, &adv_router,
+                               ospf6->lsdb);
                break;
 
        default:
@@ -1097,9 +1125,11 @@ DEFUN (show_ipv6_ospf6_border_routers,
        uint32_t adv_router;
        struct ospf6_route *ro;
        struct prefix prefix;
+       struct ospf6 *ospf6 = NULL;
 
-       OSPF6_CMD_CHECK_RUNNING();
 
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        if (argc == 5) {
                if (strmatch(argv[idx_ipv4]->text, "detail")) {
                        for (ro = ospf6_route_head(ospf6->brouter_table); ro;
@@ -1148,9 +1178,10 @@ DEFUN (show_ipv6_ospf6_linkstate,
        int idx_ipv4 = 5;
        struct listnode *node;
        struct ospf6_area *oa;
+       struct ospf6 *ospf6 = NULL;
 
-       OSPF6_CMD_CHECK_RUNNING();
-
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
        for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
                vty_out(vty, "\n        SPF Result in Area %s\n\n", oa->name);
                ospf6_linkstate_table_show(vty, idx_ipv4, argc, argv,
@@ -1174,8 +1205,10 @@ DEFUN (show_ipv6_ospf6_linkstate_detail,
        int idx_detail = 4;
        struct listnode *node;
        struct ospf6_area *oa;
+       struct ospf6 *ospf6 = NULL;
 
-       OSPF6_CMD_CHECK_RUNNING();
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
 
        for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, node, oa)) {
                vty_out(vty, "\n        SPF Result in Area %s\n\n", oa->name);
@@ -1202,8 +1235,10 @@ static void ospf6_plist_del(struct prefix_list *plist)
 }
 
 /* Install ospf related commands. */
-void ospf6_init(void)
+void ospf6_init(struct thread_master *master)
 {
+       struct ospf6 *ospf6;
+
        ospf6_top_init();
        ospf6_area_init();
        ospf6_interface_init();
@@ -1236,7 +1271,7 @@ void ospf6_init(void)
 
        install_element_ospf6_clear_interface();
 
-       install_element(VIEW_NODE, &show_debugging_ospf6_cmd);
+       install_element(ENABLE_NODE, &show_debugging_ospf6_cmd);
 
        install_element(VIEW_NODE, &show_ipv6_ospf6_border_routers_cmd);
 
@@ -1268,17 +1303,7 @@ void ospf6_init(void)
                &show_ipv6_ospf6_database_type_self_originated_linkstate_id_cmd);
        install_element(VIEW_NODE, &show_ipv6_ospf6_database_aggr_router_cmd);
 
-       /* Make ospf protocol socket. */
-       ospf6_serv_sock();
-       thread_add_read(master, ospf6_receive, NULL, ospf6_sock, NULL);
-}
-
-void ospf6_clean(void)
-{
-       if (!ospf6)
-               return;
-       if (ospf6->route_table)
-               ospf6_route_remove_all(ospf6->route_table);
-       if (ospf6->brouter_table)
-               ospf6_route_remove_all(ospf6->brouter_table);
+       ospf6 = ospf6_lookup_by_vrf_name(VRF_DEFAULT_NAME);
+       if (ospf6 == NULL)
+               ospf6_instance_create(VRF_DEFAULT_NAME);
 }
index 36f3c2233f77a8dced09fd94d240da8a1c55c622..d85ff40f3254bd2d00c4acfa5cd99b5240e3f761 100644 (file)
@@ -88,7 +88,7 @@ extern struct thread_master *master;
 #define OSPF6_ROUTER_ID_STR "Specify Router-ID\n"
 #define OSPF6_LS_ID_STR     "Specify Link State ID\n"
 
-#define OSPF6_CMD_CHECK_RUNNING()                                              \
+#define OSPF6_CMD_CHECK_RUNNING(ospf6)                                         \
        if (ospf6 == NULL) {                                                   \
                vty_out(vty, "OSPFv3 is not running\n");                       \
                return CMD_SUCCESS;                                            \
@@ -100,6 +100,6 @@ extern struct zebra_privs_t ospf6d_privs;
 extern struct route_node *route_prev(struct route_node *node);
 
 extern void ospf6_debug(void);
-extern void ospf6_init(void);
+extern void ospf6_init(struct thread_master *master);
 
 #endif /* OSPF6D_H */
index da390e3c704ed806da56afaf989297530e5ade12..d4f0dc953c1c39220b161ba5c214d13d13f2ab5d 100644 (file)
@@ -49,6 +49,7 @@
 #include "ospfd/ospf_route.h"
 #include "ospfd/ospf_zebra.h"
 #include "ospfd/ospf_api.h"
+#include "ospfd/ospf_errors.h"
 
 #include "ospf_apiclient.h"
 
@@ -564,15 +565,25 @@ static void ospf_apiclient_handle_lsa_update(struct ospf_apiclient *oclient,
 {
        struct msg_lsa_change_notify *cn;
        struct lsa_header *lsa;
-       int lsalen;
+       void *p;
+       uint16_t lsalen;
 
        cn = (struct msg_lsa_change_notify *)STREAM_DATA(msg->s);
 
        /* Extract LSA from message */
        lsalen = ntohs(cn->data.length);
-       lsa = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen);
+       if (lsalen > OSPF_MAX_LSA_SIZE) {
+               flog_warn(
+                       EC_OSPF_LARGE_LSA,
+                       "%s: message received size: %d is greater than a LSA size: %d",
+                       __func__, lsalen, OSPF_MAX_LSA_SIZE);
+               return;
+       }
+
+       p = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen);
 
-       memcpy(lsa, &(cn->data), lsalen);
+       memcpy(p, &(cn->data), lsalen);
+       lsa = p;
 
        /* Invoke registered update callback function */
        if (oclient->update_notify) {
@@ -581,7 +592,7 @@ static void ospf_apiclient_handle_lsa_update(struct ospf_apiclient *oclient,
        }
 
        /* free memory allocated by ospf apiclient library */
-       XFREE(MTYPE_OSPF_APICLIENT, lsa);
+       XFREE(MTYPE_OSPF_APICLIENT, p);
 }
 
 static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient,
@@ -589,15 +600,25 @@ static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient,
 {
        struct msg_lsa_change_notify *cn;
        struct lsa_header *lsa;
-       int lsalen;
+       void *p;
+       uint16_t lsalen;
 
        cn = (struct msg_lsa_change_notify *)STREAM_DATA(msg->s);
 
        /* Extract LSA from message */
        lsalen = ntohs(cn->data.length);
-       lsa = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen);
+       if (lsalen > OSPF_MAX_LSA_SIZE) {
+               flog_warn(
+                       EC_OSPF_LARGE_LSA,
+                       "%s: message received size: %d is greater than a LSA size: %d",
+                       __func__, lsalen, OSPF_MAX_LSA_SIZE);
+               return;
+       }
+
+       p = XMALLOC(MTYPE_OSPF_APICLIENT, lsalen);
 
-       memcpy(lsa, &(cn->data), lsalen);
+       memcpy(p, &(cn->data), lsalen);
+       lsa = p;
 
        /* Invoke registered update callback function */
        if (oclient->delete_notify) {
@@ -606,7 +627,7 @@ static void ospf_apiclient_handle_lsa_delete(struct ospf_apiclient *oclient,
        }
 
        /* free memory allocated by ospf apiclient library */
-       XFREE(MTYPE_OSPF_APICLIENT, lsa);
+       XFREE(MTYPE_OSPF_APICLIENT, p);
 }
 
 static void ospf_apiclient_msghandle(struct ospf_apiclient *oclient,
index f5f994517ee33dddb9f078dc1b3091b0b6571c2c..3ca1e132bdbc129d042c4605d30364aad3c2014b 100644 (file)
@@ -30,6 +30,7 @@
 #include "prefix.h" /* needed by ospf_asbr.h */
 #include "privs.h"
 #include "log.h"
+#include "lib/printfrr.h"
 
 /* work around gcc bug 69981, disable MTYPEs in libospf */
 #define _QUAGGA_OSPF_MEMORY_H
@@ -186,8 +187,8 @@ static void lsa_update_callback(struct in_addr ifaddr, struct in_addr area_id,
                                struct lsa_header *lsa)
 {
        printf("lsa_update_callback: ");
-       printf("ifaddr: %s ", inet_ntoa(ifaddr));
-       printf("area: %s\n", inet_ntoa(area_id));
+       printfrr("ifaddr: %pI4 ", &ifaddr);
+       printfrr("area: %pI4\n", &area_id);
        printf("is_self_origin: %u\n", is_self_originated);
 
        /* It is important to note that lsa_header does indeed include the
@@ -211,8 +212,8 @@ static void lsa_delete_callback(struct in_addr ifaddr, struct in_addr area_id,
                                struct lsa_header *lsa)
 {
        printf("lsa_delete_callback: ");
-       printf("ifaddr: %s ", inet_ntoa(ifaddr));
-       printf("area: %s\n", inet_ntoa(area_id));
+       printf("ifaddr: %pI4 ", &ifaddr);
+       printf("area: %pI4\n", &area_id);
        printf("is_self_origin: %u\n", is_self_originated);
 
        ospf_lsa_header_dump(lsa);
@@ -221,8 +222,8 @@ static void lsa_delete_callback(struct in_addr ifaddr, struct in_addr area_id,
 static void ready_callback(uint8_t lsa_type, uint8_t opaque_type,
                           struct in_addr addr)
 {
-       printf("ready_callback: lsa_type: %d opaque_type: %d addr=%s\n",
-              lsa_type, opaque_type, inet_ntoa(addr));
+       printfrr("ready_callback: lsa_type: %d opaque_type: %d addr=%pI4\n",
+                lsa_type, opaque_type, &addr);
 
        /* Schedule opaque LSA originate in 5 secs */
        thread_add_timer(master, lsa_inject, oclient, 5, NULL);
@@ -236,20 +237,20 @@ static void ready_callback(uint8_t lsa_type, uint8_t opaque_type,
 
 static void new_if_callback(struct in_addr ifaddr, struct in_addr area_id)
 {
-       printf("new_if_callback: ifaddr: %s ", inet_ntoa(ifaddr));
-       printf("area_id: %s\n", inet_ntoa(area_id));
+       printfrr("new_if_callback: ifaddr: %pI4 ", &ifaddr);
+       printfrr("area_id: %pI4\n", &area_id);
 }
 
 static void del_if_callback(struct in_addr ifaddr)
 {
-       printf("new_if_callback: ifaddr: %s\n ", inet_ntoa(ifaddr));
+       printfrr("new_if_callback: ifaddr: %pI4\n ", &ifaddr);
 }
 
 static void ism_change_callback(struct in_addr ifaddr, struct in_addr area_id,
                                uint8_t state)
 {
-       printf("ism_change: ifaddr: %s ", inet_ntoa(ifaddr));
-       printf("area_id: %s\n", inet_ntoa(area_id));
+       printfrr("ism_change: ifaddr: %pI4 ", &ifaddr);
+       printfrr("area_id: %pI4\n", &area_id);
        printf("state: %d [%s]\n", state,
               lookup_msg(ospf_ism_state_msg, state, NULL));
 }
@@ -257,9 +258,9 @@ static void ism_change_callback(struct in_addr ifaddr, struct in_addr area_id,
 static void nsm_change_callback(struct in_addr ifaddr, struct in_addr nbraddr,
                                struct in_addr router_id, uint8_t state)
 {
-       printf("nsm_change: ifaddr: %s ", inet_ntoa(ifaddr));
-       printf("nbraddr: %s\n", inet_ntoa(nbraddr));
-       printf("router_id: %s\n", inet_ntoa(router_id));
+       printfrr("nsm_change: ifaddr: %pI4 ", &ifaddr);
+       printfrr("nbraddr: %pI4\n", &nbraddr);
+       printfrr("router_id: %pI4\n", &router_id);
        printf("state: %d [%s]\n", state,
               lookup_msg(ospf_nsm_state_msg, state, NULL));
 }
index 2131c8ee9df3f4eee6b270cd73a5ce624eb4fac1..634418ec5ae5b4adca264c5cd7f4177265595227 100644 (file)
@@ -331,6 +331,7 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area)
        struct ospf_lsa *lsa;
        struct router_lsa *rlsa;
        struct in_addr *best = NULL;
+       char buf[PREFIX_STRLEN];
 
        LSDB_LOOP (ROUTER_LSDB(area), rn, lsa) {
                /* sanity checks */
@@ -348,8 +349,8 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area)
                if (IS_ROUTER_LSA_NT(rlsa)) {
                        if (IS_DEBUG_OSPF_NSSA)
                                zlog_debug(
-                                       "ospf_abr_nssa_am_elected: router %s asserts Nt",
-                                       inet_ntoa(lsa->data->id));
+                                       "ospf_abr_nssa_am_elected: router %pI4 asserts Nt",
+                                       &lsa->data->id);
                        return 0;
                }
 
@@ -363,7 +364,8 @@ static int ospf_abr_nssa_am_elected(struct ospf_area *area)
        if (IS_DEBUG_OSPF_NSSA)
                zlog_debug(
                        "ospf_abr_nssa_am_elected: best electable ABR is: %s",
-                       (best) ? inet_ntoa(*best) : "<none>");
+                       (best) ? inet_ntop(AF_INET, best, buf, sizeof(buf)) :
+                       "<none>");
 
        if (best == NULL)
                return 1;
@@ -390,8 +392,8 @@ static void ospf_abr_nssa_check_status(struct ospf *ospf)
 
                if (IS_DEBUG_OSPF(nssa, NSSA))
                        zlog_debug(
-                               "ospf_abr_nssa_check_status: checking area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_nssa_check_status: checking area %pI4",
+                               &area->area_id);
 
                if (!IS_OSPF_ABR(area->ospf)) {
                        if (IS_DEBUG_OSPF(nssa, NSSA))
@@ -615,15 +617,15 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa)
        if (!CHECK_FLAG(lsa->data->options, OSPF_OPTION_NP)) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_abr_translate_nssa(): LSA Id %s, P-bit off, NO Translation",
-                               inet_ntoa(lsa->data->id));
+                               "ospf_abr_translate_nssa(): LSA Id %pI4, P-bit off, NO Translation",
+                               &lsa->data->id);
                return 1;
        }
 
        if (IS_DEBUG_OSPF_NSSA)
                zlog_debug(
-                       "ospf_abr_translate_nssa(): LSA Id %s, TRANSLATING 7 to 5",
-                       inet_ntoa(lsa->data->id));
+                       "ospf_abr_translate_nssa(): LSA Id %pI4, TRANSLATING 7 to 5",
+                       &lsa->data->id);
 
        ext7 = (struct as_external_lsa *)(lsa->data);
        p.prefix = lsa->data->id;
@@ -632,37 +634,41 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa)
        if (ext7->e[0].fwd_addr.s_addr == OSPF_DEFAULT_DESTINATION) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_abr_translate_nssa(): LSA Id %s, Forward address is 0, NO Translation",
-                               inet_ntoa(lsa->data->id));
+                               "ospf_abr_translate_nssa(): LSA Id %pI4, Forward address is 0, NO Translation",
+                               &lsa->data->id);
                return 1;
        }
 
        /* try find existing AS-External LSA for this prefix */
-
        old = ospf_external_info_find_lsa(area->ospf, &p);
 
-       if (old) {
-               /* Do not continue if type 5 LSA not approved */
-               if (!CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) {
+       if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
+               /* if type-7 is removed, remove old translated type-5 lsa */
+               if (old) {
+                       UNSET_FLAG(old->flags, OSPF_LSA_APPROVED);
                        if (IS_DEBUG_OSPF_NSSA)
                                zlog_debug(
-                                       "ospf_abr_translate_nssa(): LSA Id %s type 5 is not approved",
-                                       inet_ntoa(old->data->id));
-                       return 1;
+                                       "ospf_abr_translate_nssa(): remove old translated LSA id %pI4",
+                                       &old->data->id);
                }
+               /* if type-7 is removed and type-5 does not exist, do not
+                * originate */
+               return 1;
+       }
 
+       if (old && CHECK_FLAG(old->flags, OSPF_LSA_APPROVED)) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_abr_translate_nssa(): found old translated LSA Id %s, refreshing",
-                               inet_ntoa(old->data->id));
+                               "ospf_abr_translate_nssa(): found old translated LSA Id %pI4, refreshing",
+                               &old->data->id);
 
                /* refresh */
                new = ospf_translated_nssa_refresh(area->ospf, lsa, old);
                if (!new) {
                        if (IS_DEBUG_OSPF_NSSA)
                                zlog_debug(
-                                       "ospf_abr_translate_nssa(): could not refresh translated LSA Id %s",
-                                       inet_ntoa(old->data->id));
+                                       "ospf_abr_translate_nssa(): could not refresh translated LSA Id %pI4",
+                                       &old->data->id);
                }
        } else {
                /* no existing external route for this LSA Id
@@ -672,8 +678,8 @@ static int ospf_abr_translate_nssa(struct ospf_area *area, struct ospf_lsa *lsa)
                if (ospf_translated_nssa_originate(area->ospf, lsa) == NULL) {
                        if (IS_DEBUG_OSPF_NSSA)
                                zlog_debug(
-                                       "ospf_abr_translate_nssa(): Could not translate Type-7 for %s to Type-5",
-                                       inet_ntoa(lsa->data->id));
+                                       "ospf_abr_translate_nssa(): Could not translate Type-7 for %pI4 to Type-5",
+                                       &lsa->data->id);
                        return 1;
                }
        }
@@ -736,14 +742,10 @@ void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost,
                        lsa = ospf_lsa_refresh(area->ospf, old);
 
                        if (!lsa) {
-                               char buf[PREFIX2STR_BUFFER];
-
-                               prefix2str((struct prefix *)p, buf,
-                                          sizeof(buf));
                                flog_warn(EC_OSPF_LSA_MISSING,
-                                         "%s: Could not refresh %s to %s",
-                                         __func__, buf,
-                                         inet_ntoa(area->area_id));
+                                         "%s: Could not refresh %pFX to %pI4",
+                                         __func__, (struct prefix *)p,
+                                         &area->area_id);
                                return;
                        }
 
@@ -758,12 +760,10 @@ void ospf_abr_announce_network_to_area(struct prefix_ipv4 *p, uint32_t cost,
                /* This will flood through area. */
 
                if (!lsa) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str((struct prefix *)p, buf, sizeof(buf));
                        flog_warn(EC_OSPF_LSA_MISSING,
-                                 "%s: Could not originate %s to %s", __func__,
-                                 buf, inet_ntoa(area->area_id));
+                                 "%s: Could not originate %pFX to %pi4",
+                                 __func__, (struct prefix *)p,
+                                 &area->area_id);
                        return;
                }
 
@@ -856,8 +856,8 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p,
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_announce_network(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_announce_network(): looking at area %pI4",
+                               &area->area_id);
 
                if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
                        continue;
@@ -868,16 +868,16 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p,
                if (!ospf_abr_should_accept(p, area)) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_network(): prefix %s/%d was denied by import-list",
-                                       inet_ntoa(p->prefix), p->prefixlen);
+                                       "ospf_abr_announce_network(): prefix %pFX was denied by import-list",
+                                       p);
                        continue;
                }
 
                if (!ospf_abr_plist_in_check(area, or, p)) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_network(): prefix %s/%d was denied by prefix-list",
-                                       inet_ntoa(p->prefix), p->prefixlen);
+                                       "ospf_abr_announce_network(): prefix %pFX was denied by prefix-list",
+                                       p);
                        continue;
                }
 
@@ -885,16 +885,16 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p,
                    && area->no_summary) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_network(): area %s is stub and no_summary",
-                                       inet_ntoa(area->area_id));
+                                       "ospf_abr_announce_network(): area %pI4 is stub and no_summary",
+                                       &area->area_id);
                        continue;
                }
 
                if (or->path_type == OSPF_PATH_INTER_AREA) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_network(): this is inter-area route to %s/%d",
-                                       inet_ntoa(p->prefix), p->prefixlen);
+                                       "ospf_abr_announce_network(): this is inter-area route to %pFX",
+                                       p);
 
                        if (!OSPF_IS_AREA_BACKBONE(area))
                                ospf_abr_announce_network_to_area(p, or->cost,
@@ -904,8 +904,8 @@ static void ospf_abr_announce_network(struct ospf *ospf, struct prefix_ipv4 *p,
                if (or->path_type == OSPF_PATH_INTRA_AREA) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_network(): this is intra-area route to %s/%d",
-                                       inet_ntoa(p->prefix), p->prefixlen);
+                                       "ospf_abr_announce_network(): this is intra-area route to %pFX",
+                                       p);
                        if ((range = ospf_area_range_match(or_area, p))
                            && !ospf_area_is_transit(area))
                                ospf_abr_update_aggregate(range, or, area);
@@ -964,8 +964,8 @@ static void ospf_abr_process_nssa_translates(struct ospf *ospf)
 
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_abr_process_nssa_translates(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_process_nssa_translates(): looking at area %pI4",
+                               &area->area_id);
 
                LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
                        ospf_abr_translate_nssa(area, lsa);
@@ -993,15 +993,15 @@ static void ospf_abr_process_network_rt(struct ospf *ospf,
                                                         or->u.std.area_id))) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_process_network_rt(): area %s no longer exists",
-                                       inet_ntoa(or->u.std.area_id));
+                                       "ospf_abr_process_network_rt(): area %pI4 no longer exists",
+                                       &or->u.std.area_id);
                        continue;
                }
 
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_process_network_rt(): this is a route to %s/%d",
-                               inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen);
+                               "ospf_abr_process_network_rt(): this is a route to %pFX",
+                               &rn->p);
                if (or->path_type >= OSPF_PATH_TYPE1_EXTERNAL) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
@@ -1114,12 +1114,10 @@ static void ospf_abr_announce_rtr_to_area(struct prefix_ipv4 *p, uint32_t cost,
                } else
                        lsa = ospf_summary_asbr_lsa_originate(p, cost, area);
                if (!lsa) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str((struct prefix *)p, buf, sizeof(buf));
                        flog_warn(EC_OSPF_LSA_MISSING,
-                                 "%s: Could not refresh/originate %s to %s",
-                                 __func__, buf, inet_ntoa(area->area_id));
+                                 "%s: Could not refresh/originate %pFX to %pI4",
+                                 __func__, (struct prefix *)p,
+                                 &area->area_id);
                        return;
                }
 
@@ -1153,8 +1151,8 @@ static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p,
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_announce_rtr(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_announce_rtr(): looking at area %pI4",
+                               &area->area_id);
 
                if (IPV4_ADDR_SAME(& or->u.std.area_id, &area->area_id))
                        continue;
@@ -1166,24 +1164,24 @@ static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p,
                if (or->u.std.external_routing == OSPF_AREA_NSSA) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_rtr(): do not generate LSA Type-4 %s from NSSA",
-                                       inet_ntoa(p->prefix));
+                                       "ospf_abr_announce_rtr(): do not generate LSA Type-4 %pI4 from NSSA",
+                                       &p->prefix);
                        continue;
                }
 
                if (area->external_routing != OSPF_AREA_DEFAULT) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_rtr(): area %s doesn't support external routing",
-                                       inet_ntoa(area->area_id));
+                                       "ospf_abr_announce_rtr(): area %pI4 doesn't support external routing",
+                                       &area->area_id);
                        continue;
                }
 
                if (or->path_type == OSPF_PATH_INTER_AREA) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_rtr(): this is inter-area route to %s",
-                                       inet_ntoa(p->prefix));
+                                       "ospf_abr_announce_rtr(): this is inter-area route to %pI4",
+                                       &p->prefix);
                        if (!OSPF_IS_AREA_BACKBONE(area))
                                ospf_abr_announce_rtr_to_area(p, or->cost,
                                                              area);
@@ -1192,8 +1190,8 @@ static void ospf_abr_announce_rtr(struct ospf *ospf, struct prefix_ipv4 *p,
                if (or->path_type == OSPF_PATH_INTRA_AREA) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "ospf_abr_announce_rtr(): this is intra-area route to %s",
-                                       inet_ntoa(p->prefix));
+                                       "ospf_abr_announce_rtr(): this is intra-area route to %pI4",
+                                       &p->prefix);
                        ospf_abr_announce_rtr_to_area(p, or->cost, area);
                }
        }
@@ -1224,16 +1222,16 @@ static void ospf_abr_process_router_rt(struct ospf *ospf,
 
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_process_router_rt(): this is a route to %s",
-                               inet_ntoa(rn->p.u.prefix4));
+                               "ospf_abr_process_router_rt(): this is a route to %pI4",
+                               &rn->p.u.prefix4);
 
                for (ALL_LIST_ELEMENTS(l, node, nnode, or)) {
                        if (!ospf_area_lookup_by_area_id(ospf,
                                                         or->u.std.area_id)) {
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "ospf_abr_process_router_rt(): area %s no longer exists",
-                                               inet_ntoa(or->u.std.area_id));
+                                               "ospf_abr_process_router_rt(): area %pI4 no longer exists",
+                                               &or->u.std.area_id);
                                continue;
                        }
 
@@ -1314,8 +1312,8 @@ ospf_abr_unapprove_translates(struct ospf *ospf) /* For NSSA Translations */
                        UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
                        if (IS_DEBUG_OSPF_NSSA)
                                zlog_debug(
-                                       "ospf_abr_unapprove_translates(): approved unset on link id %s",
-                                       inet_ntoa(lsa->data->id));
+                                       "ospf_abr_unapprove_translates(): approved unset on link id %pI4",
+                                       &lsa->data->id);
                }
 
        if (IS_DEBUG_OSPF_NSSA)
@@ -1335,14 +1333,14 @@ static void ospf_abr_unapprove_summaries(struct ospf *ospf)
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_unapprove_summaries(): considering area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_unapprove_summaries(): considering area %pI4",
+                               &area->area_id);
                LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
                        if (ospf_lsa_is_self_originated(ospf, lsa)) {
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "ospf_abr_unapprove_summaries(): approved unset on summary link id %s",
-                                               inet_ntoa(lsa->data->id));
+                                               "ospf_abr_unapprove_summaries(): approved unset on summary link id %pI4",
+                                               &lsa->data->id);
                                UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
                        }
 
@@ -1350,8 +1348,8 @@ static void ospf_abr_unapprove_summaries(struct ospf *ospf)
                        if (ospf_lsa_is_self_originated(ospf, lsa)) {
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "ospf_abr_unapprove_summaries(): approved unset on asbr-summary link id %s",
-                                               inet_ntoa(lsa->data->id));
+                                               "ospf_abr_unapprove_summaries(): approved unset on asbr-summary link id %pI4",
+                                               &lsa->data->id);
                                UNSET_FLAG(lsa->flags, OSPF_LSA_APPROVED);
                        }
        }
@@ -1396,8 +1394,8 @@ static void ospf_abr_announce_aggregates(struct ospf *ospf)
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_announce_aggregates(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_announce_aggregates(): looking at area %pI4",
+                               &area->area_id);
 
                for (rn = route_top(area->ranges); rn; rn = route_next(rn))
                        if ((range = rn->info)) {
@@ -1415,9 +1413,8 @@ static void ospf_abr_announce_aggregates(struct ospf *ospf)
 
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "ospf_abr_announce_aggregates(): this is range: %s/%d",
-                                               inet_ntoa(p.u.prefix4),
-                                               p.prefixlen);
+                                               "ospf_abr_announce_aggregates(): this is range: %pFX",
+                                               &p);
 
                                if (CHECK_FLAG(range->flags,
                                               OSPF_AREA_RANGE_SUBSTITUTE)) {
@@ -1486,8 +1483,8 @@ ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */
 
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_abr_send_nssa_aggregates(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_send_nssa_aggregates(): looking at area %pI4",
+                               &area->area_id);
 
                for (rn = route_top(area->ranges); rn; rn = route_next(rn)) {
                        if (rn->info == NULL)
@@ -1509,8 +1506,8 @@ ospf_abr_send_nssa_aggregates(struct ospf *ospf) /* temporarily turned off */
 
                        if (IS_DEBUG_OSPF_NSSA)
                                zlog_debug(
-                                       "ospf_abr_send_nssa_aggregates(): this is range: %s/%d",
-                                       inet_ntoa(p.prefix), p.prefixlen);
+                                       "ospf_abr_send_nssa_aggregates(): this is range: %pFX",
+                                       &p);
 
                        if (CHECK_FLAG(range->flags,
                                       OSPF_AREA_RANGE_SUBSTITUTE)) {
@@ -1557,8 +1554,8 @@ static void ospf_abr_announce_stub_defaults(struct ospf *ospf)
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_announce_stub_defaults(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_announce_stub_defaults(): looking at area %pI4",
+                               &area->area_id);
 
                if ((area->external_routing != OSPF_AREA_STUB)
                    && (area->external_routing != OSPF_AREA_NSSA))
@@ -1569,8 +1566,8 @@ static void ospf_abr_announce_stub_defaults(struct ospf *ospf)
 
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4",
+                               &area->area_id);
                ospf_abr_announce_network_to_area(&p, area->default_cost, area);
        }
 
@@ -1584,8 +1581,8 @@ static int ospf_abr_remove_unapproved_translates_apply(struct ospf *ospf,
        if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT)
            && !CHECK_FLAG(lsa->flags, OSPF_LSA_APPROVED)) {
                zlog_info(
-                       "ospf_abr_remove_unapproved_translates(): removing unapproved translates, ID: %s",
-                       inet_ntoa(lsa->data->id));
+                       "ospf_abr_remove_unapproved_translates(): removing unapproved translates, ID: %pI4",
+                       &lsa->data->id);
 
                /* FLUSH THROUGHOUT AS */
                ospf_lsa_flush_as(ospf, lsa);
@@ -1625,8 +1622,8 @@ static void ospf_abr_remove_unapproved_summaries(struct ospf *ospf)
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_abr_remove_unapproved_summaries(): looking at area %s",
-                               inet_ntoa(area->area_id));
+                               "ospf_abr_remove_unapproved_summaries(): looking at area %pI4",
+                               &area->area_id);
 
                LSDB_LOOP (SUMMARY_LSDB(area), rn, lsa)
                        if (ospf_lsa_is_self_originated(ospf, lsa))
index 73ce60650470e3bc634b0114804a82dadad9ff6c..c01ecdd1d4d7a017448e07e1e4fad57a7b4164b9 100644 (file)
@@ -317,21 +317,12 @@ void ospf_apiserver_free(struct ospf_apiserver *apiserv)
        struct listnode *node;
 
        /* Cancel read and write threads. */
-       if (apiserv->t_sync_read) {
-               thread_cancel(apiserv->t_sync_read);
-       }
+       thread_cancel(&apiserv->t_sync_read);
 #ifdef USE_ASYNC_READ
-       if (apiserv->t_async_read) {
-               thread_cancel(apiserv->t_async_read);
-       }
+       thread_cancel(&apiserv->t_async_read);
 #endif /* USE_ASYNC_READ */
-       if (apiserv->t_sync_write) {
-               thread_cancel(apiserv->t_sync_write);
-       }
-
-       if (apiserv->t_async_write) {
-               thread_cancel(apiserv->t_async_write);
-       }
+       thread_cancel(&apiserv->t_sync_write);
+       thread_cancel(&apiserv->t_async_write);
 
        /* Unregister all opaque types that application registered
           and flush opaque LSAs if still in LSDB. */
@@ -387,8 +378,8 @@ int ospf_apiserver_read(struct thread *thread)
                apiserv->t_sync_read = NULL;
 
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("API: ospf_apiserver_read: Peer: %s/%u",
-                                  inet_ntoa(apiserv->peer_sync.sin_addr),
+                       zlog_debug("API: ospf_apiserver_read: Peer: %pI4/%u",
+                                  &apiserv->peer_sync.sin_addr,
                                   ntohs(apiserv->peer_sync.sin_port));
        }
 #ifdef USE_ASYNC_READ
@@ -397,8 +388,8 @@ int ospf_apiserver_read(struct thread *thread)
                apiserv->t_async_read = NULL;
 
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("API: ospf_apiserver_read: Peer: %s/%u",
-                                  inet_ntoa(apiserv->peer_async.sin_addr),
+                       zlog_debug("API: ospf_apiserver_read: Peer: %pI4/%u",
+                                  &apiserv->peer_async.sin_addr,
                                   ntohs(apiserv->peer_async.sin_port));
        }
 #endif /* USE_ASYNC_READ */
@@ -455,8 +446,8 @@ int ospf_apiserver_sync_write(struct thread *thread)
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("API: ospf_apiserver_sync_write: Peer: %s/%u",
-                          inet_ntoa(apiserv->peer_sync.sin_addr),
+               zlog_debug("API: ospf_apiserver_sync_write: Peer: %pI4/%u",
+                          &apiserv->peer_sync.sin_addr,
                           ntohs(apiserv->peer_sync.sin_port));
 
        /* Check whether there is really a message in the fifo. */
@@ -519,8 +510,8 @@ int ospf_apiserver_async_write(struct thread *thread)
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("API: ospf_apiserver_async_write: Peer: %s/%u",
-                          inet_ntoa(apiserv->peer_async.sin_addr),
+               zlog_debug("API: ospf_apiserver_async_write: Peer: %pI4/%u",
+                          &apiserv->peer_async.sin_addr,
                           ntohs(apiserv->peer_async.sin_port));
 
        /* Check whether there is really a message in the fifo. */
@@ -645,8 +636,8 @@ int ospf_apiserver_accept(struct thread *thread)
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("API: ospf_apiserver_accept: New peer: %s/%u",
-                          inet_ntoa(peer_sync.sin_addr),
+               zlog_debug("API: ospf_apiserver_accept: New peer: %pI4/%u",
+                          &peer_sync.sin_addr,
                           ntohs(peer_sync.sin_port));
 
        /* Create new socket for asynchronous messages. */
@@ -657,8 +648,8 @@ int ospf_apiserver_accept(struct thread *thread)
         */
        if (ntohs(peer_async.sin_port) == ospf_apiserver_getport()) {
                zlog_warn(
-                       "API: ospf_apiserver_accept: Peer(%s/%u): Invalid async port number?",
-                       inet_ntoa(peer_async.sin_addr),
+                       "API: ospf_apiserver_accept: Peer(%pI4/%u): Invalid async port number?",
+                       &peer_async.sin_addr,
                        ntohs(peer_async.sin_port));
                close(new_sync_sock);
                return -1;
@@ -1409,8 +1400,8 @@ struct ospf_lsa *ospf_apiserver_opaque_lsa_new(struct ospf_area *area,
        options |= OSPF_OPTION_O; /* Don't forget to set option bit */
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Creating an Opaque-LSA instance",
-                          protolsa->type, inet_ntoa(protolsa->id));
+               zlog_debug("LSA[Type%d:%pI4]: Creating an Opaque-LSA instance",
+                          protolsa->type, &protolsa->id);
        }
 
        /* Set opaque-LSA header fields. */
@@ -1510,8 +1501,8 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv,
        case OSPF_OPAQUE_LINK_LSA:
                oi = ospf_apiserver_if_lookup_by_addr(omsg->ifaddr);
                if (!oi) {
-                       zlog_warn("apiserver_originate: unknown interface %s",
-                                 inet_ntoa(omsg->ifaddr));
+                       zlog_warn("apiserver_originate: unknown interface %pI4",
+                                 &omsg->ifaddr);
                        rc = OSPF_API_NOSUCHINTERFACE;
                        goto out;
                }
@@ -1521,8 +1512,8 @@ int ospf_apiserver_handle_originate_request(struct ospf_apiserver *apiserv,
        case OSPF_OPAQUE_AREA_LSA:
                area = ospf_area_lookup_by_area_id(ospf, omsg->area_id);
                if (!area) {
-                       zlog_warn("apiserver_originate: unknown area %s",
-                                 inet_ntoa(omsg->area_id));
+                       zlog_warn("apiserver_originate: unknown area %pI4",
+                                 &omsg->area_id);
                        rc = OSPF_API_NOSUCHAREA;
                        goto out;
                }
@@ -1791,8 +1782,8 @@ struct ospf_lsa *ospf_apiserver_lsa_refresher(struct ospf_lsa *lsa)
 
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Refresh Opaque LSA",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: Refresh Opaque LSA",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1829,8 +1820,8 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
        case OSPF_OPAQUE_AREA_LSA:
                area = ospf_area_lookup_by_area_id(ospf, dmsg->area_id);
                if (!area) {
-                       zlog_warn("ospf_apiserver_lsa_delete: unknown area %s",
-                                 inet_ntoa(dmsg->area_id));
+                       zlog_warn("ospf_apiserver_lsa_delete: unknown area %pI4",
+                                 &dmsg->area_id);
                        rc = OSPF_API_NOSUCHAREA;
                        goto out;
                }
@@ -1872,8 +1863,8 @@ int ospf_apiserver_handle_delete_request(struct ospf_apiserver *apiserv,
        old = ospf_lsa_lookup(ospf, area, dmsg->lsa_type, id, ospf->router_id);
        if (!old) {
                zlog_warn(
-                       "ospf_apiserver_lsa_delete: LSA[Type%d:%s] not in LSDB",
-                       dmsg->lsa_type, inet_ntoa(id));
+                       "ospf_apiserver_lsa_delete: LSA[Type%d:%pI4] not in LSDB",
+                       dmsg->lsa_type, &id);
                rc = OSPF_API_NOSUCHLSA;
                goto out;
        }
index 8fb6402c7e9522c449531c4d305b74ae08f20be1..94fa1b5b44f43aec8e9fb017ac71d4b059201459 100644 (file)
@@ -42,7 +42,7 @@
 #include "ospfd/ospf_route.h"
 #include "ospfd/ospf_zebra.h"
 #include "ospfd/ospf_dump.h"
-
+#include "ospfd/ospf_errors.h"
 
 /* Remove external route. */
 void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)
@@ -53,8 +53,7 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)
        rn = route_node_lookup(ospf->old_external_route, (struct prefix *)p);
        if (rn)
                if ((or = rn->info)) {
-                       zlog_info("Route[%s/%d]: external path deleted",
-                                 inet_ntoa(p->prefix), p->prefixlen);
+                       zlog_info("Route[%pFX]: external path deleted", p);
 
                        /* Remove route from zebra. */
                        if (or->type == OSPF_DESTINATION_NETWORK)
@@ -69,8 +68,7 @@ void ospf_external_route_remove(struct ospf *ospf, struct prefix_ipv4 *p)
                        return;
                }
 
-       zlog_info("Route[%s/%d]: no such external path", inet_ntoa(p->prefix),
-                 p->prefixlen);
+       zlog_info("Route[%pFX]: no such external path", p);
 }
 
 /* Add an External info for AS-external-LSA. */
@@ -82,6 +80,7 @@ struct external_info *ospf_external_info_new(uint8_t type,
        new = XCALLOC(MTYPE_OSPF_EXTERNAL_INFO, sizeof(struct external_info));
        new->type = type;
        new->instance = instance;
+       new->to_be_processed = 0;
 
        ospf_reset_route_map_set_values(&new->route_map_set);
        return new;
@@ -133,13 +132,12 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
                        }
 
                        inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
-                                 INET6_BUFSIZ);
+                                 sizeof(inetbuf));
                        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                                zlog_debug(
-                                       "Redistribute[%s][%d][%u]: %s/%d discarding old info with NH %s.",
+                                       "Redistribute[%s][%d][%u]: %pFX discarding old info with NH %s.",
                                        ospf_redist_string(type), instance,
-                                       ospf->vrf_id, inet_ntoa(p.prefix),
-                                       p.prefixlen, inetbuf);
+                                       ospf->vrf_id, &p, inetbuf);
                        XFREE(MTYPE_OSPF_EXTERNAL_INFO, rn->info);
                }
 
@@ -150,6 +148,7 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
        new->nexthop = nexthop;
        new->tag = tag;
        new->orig_tag = tag;
+       new->aggr_route = NULL;
 
        /* we don't unlock rn from the get() because we're attaching the info */
        if (rn)
@@ -157,11 +156,11 @@ ospf_external_info_add(struct ospf *ospf, uint8_t type, unsigned short instance,
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                inet_ntop(AF_INET, (void *)&nexthop.s_addr, inetbuf,
-                         INET6_BUFSIZ);
+                         sizeof(inetbuf));
                zlog_debug(
-                       "Redistribute[%s][%u]: %s/%d external info created, with NH %s",
+                       "Redistribute[%s][%u]: %pFX external info created, with NH %s",
                        ospf_redist_string(type), ospf->vrf_id,
-                       inet_ntoa(p.prefix), p.prefixlen, inetbuf);
+                       &p, inetbuf);
        }
        return new;
 }
@@ -292,8 +291,9 @@ void ospf_asbr_nssa_redist_task(struct ospf *ospf)
                        continue;
 
                for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
-                       ospf_external_lsa_refresh_type(
-                               ospf, type, red->instance, LSA_REFRESH_FORCE);
+                       ospf_external_lsa_refresh_type(ospf, type,
+                                                      red->instance,
+                                                      LSA_REFRESH_IF_CHANGED);
        }
 
        ospf_external_lsa_refresh_default(ospf);
@@ -329,3 +329,890 @@ void ospf_redistribute_withdraw(struct ospf *ospf, uint8_t type,
                                        rn->info = NULL;
                                }
 }
+
+/* External Route Aggregator Handlers */
+bool is_valid_summary_addr(struct prefix_ipv4 *p)
+{
+       /* Default prefix validation*/
+       if (p->prefix.s_addr == INADDR_ANY)
+               return false;
+
+       /*Host route shouldn't be configured as summary addres*/
+       if (p->prefixlen == IPV4_MAX_PREFIXLEN)
+               return false;
+
+       return true;
+}
+void ospf_asbr_external_aggregator_init(struct ospf *instance)
+{
+       instance->rt_aggr_tbl = route_table_init();
+
+       instance->t_external_aggr = NULL;
+
+       instance->aggr_action = 0;
+
+       instance->aggr_delay_interval = OSPF_EXTL_AGGR_DEFAULT_DELAY;
+}
+
+static unsigned int ospf_external_rt_hash_key(const void *data)
+{
+       const struct external_info *ei = data;
+       unsigned int key = 0;
+
+       key = prefix_hash_key(&ei->p);
+       return key;
+}
+
+static bool ospf_external_rt_hash_cmp(const void *d1, const void *d2)
+{
+       const struct external_info *ei1 = d1;
+       const struct external_info *ei2 = d2;
+
+       return prefix_same((struct prefix *)&ei1->p, (struct prefix *)&ei2->p);
+}
+
+static struct ospf_external_aggr_rt *
+ospf_external_aggregator_new(struct prefix_ipv4 *p)
+{
+       struct ospf_external_aggr_rt *aggr;
+
+       aggr = (struct ospf_external_aggr_rt *)XCALLOC(
+               MTYPE_OSPF_EXTERNAL_RT_AGGR,
+               sizeof(struct ospf_external_aggr_rt));
+
+       if (!aggr)
+               return NULL;
+
+       aggr->p.family = p->family;
+       aggr->p.prefix = p->prefix;
+       aggr->p.prefixlen = p->prefixlen;
+       aggr->match_extnl_hash = hash_create(ospf_external_rt_hash_key,
+                                            ospf_external_rt_hash_cmp,
+                                            "Ospf external route hash");
+       return aggr;
+}
+
+static void ospf_aggr_handle_external_info(void *data)
+{
+       struct external_info *ei = (struct external_info *)data;
+       struct ospf_external_aggr_rt *aggr = NULL;
+       struct ospf *ospf = NULL;
+       struct ospf_lsa *lsa = NULL;
+
+       ei->aggr_route = NULL;
+
+       ei->to_be_processed = true;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Handle extrenal route(%pI4/%d)", __func__,
+                          &ei->p.prefix, ei->p.prefixlen);
+
+       ospf = ospf_lookup_instance(ei->instance);
+
+       assert(ospf);
+
+       if (!ospf_redistribute_check(ospf, ei, NULL))
+               return;
+
+       aggr = ospf_external_aggr_match(ospf, &ei->p);
+       if (aggr) {
+               (void)ospf_originate_summary_lsa(ospf, aggr, ei);
+               return;
+       }
+
+       lsa = ospf_external_info_find_lsa(ospf, &ei->p);
+       if (lsa)
+               ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE, 1);
+       else
+               (void)ospf_external_lsa_originate(ospf, ei);
+}
+
+static void ospf_aggr_unlink_external_info(void *data)
+{
+       struct external_info *ei = (struct external_info *)data;
+
+       ei->aggr_route = NULL;
+
+       ei->to_be_processed = true;
+}
+
+void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr)
+{
+       if (OSPF_EXTERNAL_RT_COUNT(aggr))
+               hash_clean(aggr->match_extnl_hash,
+                          (void *)ospf_aggr_unlink_external_info);
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Release the aggregator Address(%pI4/%d)",
+                          __func__, &aggr->p.prefix, aggr->p.prefixlen);
+       hash_free(aggr->match_extnl_hash);
+       aggr->match_extnl_hash = NULL;
+
+       XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr);
+}
+
+static void ospf_external_aggr_add(struct ospf *ospf,
+                                  struct ospf_external_aggr_rt *aggr)
+{
+       struct route_node *rn;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Adding Aggregate route to Aggr table (%pI4/%d)",
+                          __func__, &aggr->p.prefix, aggr->p.prefixlen);
+       rn = route_node_get(ospf->rt_aggr_tbl, (struct prefix *)&aggr->p);
+       if (rn->info)
+               route_unlock_node(rn);
+       else
+               rn->info = aggr;
+}
+
+static void ospf_external_aggr_delete(struct ospf *ospf, struct route_node *rn)
+{
+       struct ospf_external_aggr_rt *aggr = rn->info;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Deleting Aggregate route (%pI4/%d)", __func__,
+                          &aggr->p.prefix, aggr->p.prefixlen);
+
+       /* Sent a Max age LSA if it is already originated. */
+       if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) {
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug("%s: Flushing Aggregate route (%pI4/%d)",
+                                  __func__, &aggr->p.prefix,
+                                  aggr->p.prefixlen);
+               ospf_external_lsa_flush(ospf, 0, &aggr->p, 0);
+       }
+
+       rn->info = NULL;
+       route_unlock_node(rn);
+       route_unlock_node(rn);
+}
+
+struct ospf_external_aggr_rt *
+ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p)
+{
+       struct route_node *rn;
+       struct ospf_external_aggr_rt *summary_rt = NULL;
+
+       rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p);
+       if (rn) {
+               summary_rt = rn->info;
+               route_unlock_node(rn);
+               return summary_rt;
+       }
+       return NULL;
+}
+
+struct ospf_external_aggr_rt *ospf_external_aggr_match(struct ospf *ospf,
+                                                      struct prefix_ipv4 *p)
+{
+       struct route_node *node;
+       struct ospf_external_aggr_rt *summary_rt = NULL;
+
+       node = route_node_match(ospf->rt_aggr_tbl, (struct prefix *)p);
+       if (node) {
+
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       if (node->info) {
+                               struct ospf_external_aggr_rt *ag = node->info;
+
+                               zlog_debug(
+                                       "%s: Matching aggregator found.prefix:%pI4/%d Aggregator %pI4/%d\n",
+                                       __func__, &p->prefix, p->prefixlen,
+                                       &ag->p.prefix, ag->p.prefixlen);
+                       }
+
+               summary_rt = node->info;
+               route_unlock_node(node);
+               return summary_rt;
+       }
+       return NULL;
+}
+
+void ospf_unlink_ei_from_aggr(struct ospf *ospf,
+                             struct ospf_external_aggr_rt *aggr,
+                             struct external_info *ei)
+{
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug(
+                       "%s: Unlinking extrenal route(%pI4/%d) from aggregator(%pI4/%d), external route count:%ld",
+                       __func__, &ei->p.prefix, ei->p.prefixlen,
+                       &aggr->p.prefix, aggr->p.prefixlen,
+                       OSPF_EXTERNAL_RT_COUNT(aggr));
+       hash_release(aggr->match_extnl_hash, ei);
+       ei->aggr_route = NULL;
+
+       /* Flush the aggreagte route if matching
+        * external route count becomes zero.
+        */
+       if (!OSPF_EXTERNAL_RT_COUNT(aggr)
+           && CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) {
+
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug("%s: Flushing the aggreagte route (%pI4/%d)",
+                                  __func__, &aggr->p.prefix,
+                                  aggr->p.prefixlen);
+
+               /* Flush the aggregate LSA */
+               ospf_external_lsa_flush(ospf, 0, &aggr->p, 0);
+
+               /* Unset the Origination flag */
+               UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+       }
+}
+
+static void ospf_link_ei_to_aggr(struct ospf_external_aggr_rt *aggr,
+                                struct external_info *ei)
+{
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug(
+                       "%s: Linking extrenal route(%pI4/%d) to aggregator(%pI4/%d)",
+                       __func__, &ei->p.prefix, ei->p.prefixlen,
+                       &aggr->p.prefix, aggr->p.prefixlen);
+       hash_get(aggr->match_extnl_hash, ei, hash_alloc_intern);
+       ei->aggr_route = aggr;
+}
+
+struct ospf_lsa *ospf_originate_summary_lsa(struct ospf *ospf,
+                                           struct ospf_external_aggr_rt *aggr,
+                                           struct external_info *ei)
+{
+       struct ospf_lsa *lsa;
+       struct external_info ei_aggr;
+       struct as_external_lsa *asel;
+       struct ospf_external_aggr_rt *old_aggr;
+       route_tag_t tag = 0;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Prepare to originate Summary route(%pI4/%d)",
+                          __func__, &aggr->p.prefix, aggr->p.prefixlen);
+
+       /* This case to handle when the overlapping aggregator address
+        * is availbe.Best match will be considered.So need to delink
+        * from old aggregator and link to the new aggr.
+        */
+       if (ei->aggr_route) {
+               if (ei->aggr_route != aggr) {
+                       old_aggr = ei->aggr_route;
+                       ospf_unlink_ei_from_aggr(ospf, old_aggr, ei);
+               }
+       }
+
+       /* Add the external route to hash table */
+       ospf_link_ei_to_aggr(aggr, ei);
+
+       lsa = ospf_external_info_find_lsa(ospf, &aggr->p);
+       /* Dont originate external LSA,
+        * If it is configured not to advertise.
+        */
+       if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) {
+               /* If it is already originated as external LSA,
+                * But, it is configured not to advertise then
+                * flush the originated external lsa.
+                */
+               if (lsa)
+                       ospf_external_lsa_flush(ospf, 0, &aggr->p, 0);
+               UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug(
+                               "%s: Don't originate the summary address,It is configured to not-advertise.",
+                               __func__);
+               return NULL;
+       }
+
+       /* Prepare the extrenal_info for aggregator */
+       memset(&ei_aggr, 0, sizeof(struct external_info));
+       ei_aggr.p = aggr->p;
+       ei_aggr.tag = aggr->tag;
+       ei_aggr.type = 0;
+       ei_aggr.instance = ospf->instance;
+       ei_aggr.route_map_set.metric = -1;
+       ei_aggr.route_map_set.metric_type = -1;
+
+       /* Summary route already originated,
+        * So, Do nothing.
+        */
+       if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) {
+               if (!lsa) {
+                       flog_warn(EC_OSPF_LSA_MISSING,
+                                 "%s: Could not refresh/originate %pI4/%d",
+                                 __func__, &aggr->p.prefix, aggr->p.prefixlen);
+                       return NULL;
+               }
+
+               asel = (struct as_external_lsa *)lsa->data;
+               tag = (unsigned long)ntohl(asel->e[0].route_tag);
+
+               /* If tag modified , then re-originate the route
+                * with modified tag details.
+                */
+               if (tag != ei_aggr.tag) {
+                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                               zlog_debug(
+                                       "%s: Route tag changed(old:%d new:%d,So refresh the summary route.(%pI4/%d)",
+                                       __func__, tag, ei_aggr.tag,
+                                       &aggr->p.prefix, aggr->p.prefixlen);
+
+                       ospf_external_lsa_refresh(ospf, lsa, &ei_aggr,
+                                                 LSA_REFRESH_FORCE, 1);
+               }
+               return lsa;
+       }
+
+       if (lsa && IS_LSA_MAXAGE(lsa)) {
+               /* This is special case.
+                * If a summary route need to be originated but where
+                * summary route already exist in lsdb with maxage, then
+                * it need to be refreshed.
+                */
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug(
+                               "%s: LSA is in MAX-AGE so refreshing LSA(%pI4/%d)",
+                               __PRETTY_FUNCTION__, &aggr->p.prefix,
+                               aggr->p.prefixlen);
+
+               ospf_external_lsa_refresh(ospf, lsa, &ei_aggr,
+                                         LSA_REFRESH_FORCE, 1);
+               SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+               return lsa;
+       }
+
+       /* If the external route prefix same as aggregate route
+        * and if external route is already originated as TYPE-5
+        * then it need to be refreshed and originate bit should
+        * be set.
+        */
+       if (lsa && prefix_same((struct prefix *)&ei_aggr.p,
+                              (struct prefix *)&ei->p)) {
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug(
+                               "%s: External route prefix is same as aggr so refreshing LSA(%pI4/%d)",
+                               __PRETTY_FUNCTION__, &aggr->p.prefix,
+                               aggr->p.prefixlen);
+               ospf_external_lsa_refresh(ospf, lsa, &ei_aggr,
+                                         LSA_REFRESH_FORCE, 1);
+               SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+               return lsa;
+       }
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Originate Summary route(%pI4/%d)", __func__,
+                          &aggr->p.prefix, aggr->p.prefixlen);
+
+       /* Originate summary LSA */
+       lsa = ospf_external_lsa_originate(ospf, &ei_aggr);
+       if (lsa) {
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug("%s: Set the origination bit for aggregator",
+                                  __func__);
+               SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+       }
+
+       return lsa;
+}
+void ospf_unset_all_aggr_flag(struct ospf *ospf)
+{
+       struct route_node *rn = NULL;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("Unset the origination bit for all aggregator");
+
+       for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+
+               struct ospf_external_aggr_rt *aggr = rn->info;
+
+               UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+       }
+}
+
+static void ospf_delete_all_marked_aggregators(struct ospf *ospf)
+{
+       struct route_node *rn = NULL;
+
+       /* Loop through all the aggregators, Delete all aggregators
+        * which are marked as DELETE. Set action to NONE for remaining
+        * aggregators
+        */
+       for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
+               if (!rn->info)
+                       continue;
+
+               struct ospf_external_aggr_rt *aggr = rn->info;
+
+               if (aggr->action != OSPF_ROUTE_AGGR_DEL) {
+                       aggr->action = OSPF_ROUTE_AGGR_NONE;
+                       continue;
+               }
+               ospf_external_aggr_delete(ospf, rn);
+               ospf_external_aggregator_free(aggr);
+       }
+}
+
+static void ospf_handle_aggregated_exnl_rt(struct ospf *ospf,
+                                          struct ospf_external_aggr_rt *aggr,
+                                          struct external_info *ei)
+{
+       struct ospf_lsa *lsa;
+       struct as_external_lsa *al;
+       struct in_addr mask;
+
+       /* Handling the case where the external route prefix
+        * and aggregate prefix is same
+        * If same dont flush the originated external LSA.
+        */
+       if (prefix_same((struct prefix *)&aggr->p, (struct prefix *)&ei->p)) {
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug(
+                               "%s: External Route prefix same as Aggregator(%pI4/%d), so dont flush.",
+                               __func__, &ei->p.prefix, ei->p.prefixlen);
+               return;
+       }
+
+       lsa = ospf_external_info_find_lsa(ospf, &ei->p);
+       if (lsa) {
+               al = (struct as_external_lsa *)lsa->data;
+               masklen2ip(ei->p.prefixlen, &mask);
+
+               if (mask.s_addr != al->mask.s_addr)
+                       return;
+
+               ospf_external_lsa_flush(ospf, ei->type, &ei->p, 0);
+       }
+}
+
+static void ospf_handle_exnl_rt_after_aggr_del(struct ospf *ospf,
+                                              struct external_info *ei)
+{
+       struct ospf_lsa *lsa;
+
+       /* Process only marked external routes.
+        * These routes were part of a deleted
+        * aggregator.So, originate now.
+        */
+       if (!ei->to_be_processed)
+               return;
+
+       ei->to_be_processed = false;
+
+       lsa = ospf_external_info_find_lsa(ospf, &ei->p);
+
+       if (lsa)
+               ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE, 0);
+       else {
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug("%s: Originate external route(%pI4/%d)",
+                                  __func__, &ei->p.prefix, ei->p.prefixlen);
+
+               ospf_external_lsa_originate(ospf, ei);
+       }
+}
+
+static void ospf_handle_external_aggr_add(struct ospf *ospf)
+{
+       struct external_info *ei;
+       struct route_node *rn = NULL;
+       struct route_table *rt = NULL;
+       int type = 0;
+
+       /* Delete all the aggregators which are marked as
+        * OSPF_ROUTE_AGGR_DEL.
+        */
+       ospf_delete_all_marked_aggregators(ospf);
+
+       for (type = 0; type <= ZEBRA_ROUTE_MAX; type++) {
+               struct list *ext_list;
+               struct listnode *node;
+               struct ospf_external *ext;
+               struct ospf_external_aggr_rt *aggr;
+
+               ext_list = ospf->external[type];
+               if (!ext_list)
+                       continue;
+
+               for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
+                       rt = ext->external_info;
+                       if (!rt)
+                               continue;
+
+                       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                               if (!rn->info)
+                                       continue;
+
+                               ei = rn->info;
+                               if (is_prefix_default(&ei->p))
+                                       continue;
+
+                               /* Check the AS-external-LSA
+                                * should be originated.
+                                */
+                               if (!ospf_redistribute_check(ospf, ei, NULL))
+                                       continue;
+
+                               aggr = ospf_external_aggr_match(ospf, &ei->p);
+
+                               /* If matching aggregator found, Add
+                                * the external route reference to the
+                                * aggregator and originate the aggr
+                                * route if it is advertisable.
+                                * flush the external LSA if it is
+                                * already originated for this external
+                                * prefix.
+                                */
+                               if (aggr) {
+                                       ospf_originate_summary_lsa(ospf, aggr,
+                                                                  ei);
+
+                                       /* All aggregated external rts
+                                        * are handled here.
+                                        */
+                                       ospf_handle_aggregated_exnl_rt(
+                                               ospf, aggr, ei);
+                                       continue;
+                               }
+
+                               /* External routes which are only out
+                                * of aggregation will be handled here.
+                                */
+                               ospf_handle_exnl_rt_after_aggr_del(ospf, ei);
+                       }
+               }
+       }
+}
+
+static void
+ospf_aggr_handle_advertise_change(struct ospf *ospf,
+                                 struct ospf_external_aggr_rt *aggr,
+                                 struct external_info *ei_aggr)
+{
+       struct ospf_lsa *lsa;
+
+       /* Check if advertise option modified. */
+       if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE)) {
+
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug(
+                               "%s: Don't originate the summary address,It is configured to not-advertise.",
+                               __func__);
+
+               if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) {
+
+                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                               zlog_debug(
+                                       "%s: No-advertise,So Flush the Aggregate route(%pI4/%d)",
+                                       __func__, &aggr->p.prefix,
+                                       aggr->p.prefixlen);
+
+                       ospf_external_lsa_flush(ospf, 0, &aggr->p, 0);
+
+                       UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+               }
+               return;
+       }
+
+       if (!CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED)) {
+               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                       zlog_debug("%s: Now it is advatisable", __func__);
+
+               lsa = ospf_external_info_find_lsa(ospf, &ei_aggr->p);
+               if (lsa && IS_LSA_MAXAGE(lsa)) {
+                       /* This is special case.
+                        * If a summary route need to be originated but where
+                        * summary route already exist in lsdb with maxage, then
+                        * it need to be refreshed.
+                        */
+                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                               zlog_debug(
+                                       "%s: It is already with Maxage, So refresh it (%pI4/%d)",
+                                       __func__, &aggr->p.prefix,
+                                       aggr->p.prefixlen);
+
+                       ospf_external_lsa_refresh(ospf, lsa, ei_aggr,
+                                                 LSA_REFRESH_FORCE, 1);
+
+                       SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_ORIGINATED);
+
+               } else {
+
+                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                               zlog_debug(
+                                       "%s: Originate Aggregate LSA (%pI4/%d)",
+                                       __func__, &aggr->p.prefix,
+                                       aggr->p.prefixlen);
+
+                       /* Originate summary LSA */
+                       lsa = ospf_external_lsa_originate(ospf, ei_aggr);
+                       if (lsa)
+                               SET_FLAG(aggr->flags,
+                                        OSPF_EXTERNAL_AGGRT_ORIGINATED);
+               }
+       }
+}
+
+static void ospf_handle_external_aggr_update(struct ospf *ospf)
+{
+       struct route_node *rn = NULL;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Process modified aggregators.\n", __func__);
+
+       for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
+               struct ospf_external_aggr_rt *aggr;
+               struct ospf_lsa *lsa = NULL;
+               struct as_external_lsa *asel = NULL;
+               struct external_info ei_aggr;
+               route_tag_t tag = 0;
+
+               if (!rn->info)
+                       continue;
+
+               aggr = rn->info;
+
+               if (aggr->action == OSPF_ROUTE_AGGR_DEL) {
+                       aggr->action = OSPF_ROUTE_AGGR_NONE;
+                       ospf_external_aggr_delete(ospf, rn);
+
+                       if (OSPF_EXTERNAL_RT_COUNT(aggr))
+                               hash_clean(
+                                       aggr->match_extnl_hash,
+                                       (void *)ospf_aggr_handle_external_info);
+
+                       hash_free(aggr->match_extnl_hash);
+                       XFREE(MTYPE_OSPF_EXTERNAL_RT_AGGR, aggr);
+
+               } else if (aggr->action == OSPF_ROUTE_AGGR_MODIFY) {
+
+                       aggr->action = OSPF_ROUTE_AGGR_NONE;
+
+                       /* Prepare the extrenal_info for aggregator */
+                       memset(&ei_aggr, 0, sizeof(struct external_info));
+                       ei_aggr.p = aggr->p;
+                       ei_aggr.tag = aggr->tag;
+                       ei_aggr.type = 0;
+                       ei_aggr.instance = ospf->instance;
+                       ei_aggr.route_map_set.metric = -1;
+                       ei_aggr.route_map_set.metric_type = -1;
+
+                       /* Check if tag modified */
+                       if (CHECK_FLAG(aggr->flags,
+                                      OSPF_EXTERNAL_AGGRT_ORIGINATED)) {
+                               lsa = ospf_external_info_find_lsa(ospf,
+                                                                 &ei_aggr.p);
+                               if (!lsa) {
+                                       flog_warn(EC_OSPF_LSA_MISSING,
+                                                 "%s: Could not refresh/originate %pI4/%d",
+                                                 __func__, &aggr->p.prefix,
+                                                 aggr->p.prefixlen);
+                                       continue;
+                               }
+
+                               asel = (struct as_external_lsa *)lsa->data;
+                               tag = (unsigned long)ntohl(
+                                       asel->e[0].route_tag);
+
+                               /* If tag modified , then re-originate the
+                                * route with modified tag details.
+                                */
+                               if (tag != ei_aggr.tag) {
+                                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                                               zlog_debug(
+                                                       "%s: Route tag changed(old:%d new:%d,So refresh the summary route.(%pI4/%d)",
+                                                       __func__, tag,
+                                                       ei_aggr.tag,
+                                                       &aggr->p.prefix,
+                                                       aggr->p.prefixlen);
+
+                                       ospf_external_lsa_refresh(
+                                               ospf, lsa, &ei_aggr,
+                                               LSA_REFRESH_FORCE, 1);
+                               }
+                       }
+
+                       /* Advertise option modified ?
+                        * If so, handled it here.
+                        */
+                       ospf_aggr_handle_advertise_change(ospf, aggr, &ei_aggr);
+               }
+       }
+}
+
+static int ospf_asbr_external_aggr_process(struct thread *thread)
+{
+       struct ospf *ospf = THREAD_ARG(thread);
+       int operation = 0;
+
+       ospf->t_external_aggr = NULL;
+       operation = ospf->aggr_action;
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: operation:%d\n", __func__, operation);
+
+       switch (operation) {
+       case OSPF_ROUTE_AGGR_ADD:
+               ospf_handle_external_aggr_add(ospf);
+               break;
+       case OSPF_ROUTE_AGGR_DEL:
+       case OSPF_ROUTE_AGGR_MODIFY:
+               ospf_handle_external_aggr_update(ospf);
+               break;
+       default:
+               break;
+       }
+
+       return OSPF_SUCCESS;
+}
+static void ospf_external_aggr_timer(struct ospf *ospf,
+                                    struct ospf_external_aggr_rt *aggr,
+                                    enum ospf_aggr_action_t operation)
+{
+       aggr->action = operation;
+
+       if (ospf->t_external_aggr) {
+               if (ospf->aggr_action == OSPF_ROUTE_AGGR_ADD) {
+
+                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                               zlog_debug(
+                                       "%s: Not required to retsart timer,set is already added.",
+                                       __func__);
+                       return;
+               }
+
+               if (operation == OSPF_ROUTE_AGGR_ADD) {
+                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                               zlog_debug(
+                                       "%s, Restarting Aggregator delay timer.",
+                                       __func__);
+                       THREAD_OFF(ospf->t_external_aggr);
+               }
+       }
+
+       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+               zlog_debug("%s: Start Aggregator delay timer %d(in seconds).",
+                          __func__, ospf->aggr_delay_interval);
+
+       ospf->aggr_action = operation;
+       thread_add_timer(master, ospf_asbr_external_aggr_process, ospf,
+                        ospf->aggr_delay_interval, &ospf->t_external_aggr);
+}
+
+int ospf_asbr_external_aggregator_set(struct ospf *ospf, struct prefix_ipv4 *p,
+                                     route_tag_t tag)
+{
+       struct ospf_external_aggr_rt *aggregator;
+
+       aggregator = ospf_extrenal_aggregator_lookup(ospf, p);
+
+       if (aggregator) {
+               if (CHECK_FLAG(aggregator->flags,
+                              OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
+                       UNSET_FLAG(aggregator->flags,
+                                  OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
+               else if (aggregator->tag == tag)
+                       return OSPF_SUCCESS;
+
+               aggregator->tag = tag;
+
+               ospf_external_aggr_timer(ospf, aggregator,
+                                        OSPF_ROUTE_AGGR_MODIFY);
+       } else {
+               aggregator = ospf_external_aggregator_new(p);
+               if (!aggregator)
+                       return OSPF_FAILURE;
+
+               aggregator->tag = tag;
+
+               ospf_external_aggr_add(ospf, aggregator);
+               ospf_external_aggr_timer(ospf, aggregator, OSPF_ROUTE_AGGR_ADD);
+       }
+
+       return OSPF_SUCCESS;
+}
+
+int ospf_asbr_external_aggregator_unset(struct ospf *ospf,
+                                       struct prefix_ipv4 *p, route_tag_t tag)
+{
+       struct route_node *rn;
+       struct ospf_external_aggr_rt *aggr;
+
+       rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p);
+       if (!rn)
+               return OSPF_INVALID;
+
+       aggr = rn->info;
+
+       if (tag && (tag != aggr->tag))
+               return OSPF_INVALID;
+
+       if (!OSPF_EXTERNAL_RT_COUNT(aggr)) {
+               ospf_external_aggr_delete(ospf, rn);
+               ospf_external_aggregator_free(aggr);
+               return OSPF_SUCCESS;
+       }
+
+       ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_DEL);
+
+       return OSPF_SUCCESS;
+}
+
+int ospf_asbr_external_rt_no_advertise(struct ospf *ospf, struct prefix_ipv4 *p)
+{
+       struct ospf_external_aggr_rt *aggr;
+       route_tag_t tag = 0;
+
+       aggr = ospf_extrenal_aggregator_lookup(ospf, p);
+       if (aggr) {
+               if (CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
+                       return OSPF_SUCCESS;
+
+               SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
+
+               aggr->tag = tag;
+
+               if (!OSPF_EXTERNAL_RT_COUNT(aggr))
+                       return OSPF_SUCCESS;
+
+               ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_MODIFY);
+       } else {
+               aggr = ospf_external_aggregator_new(p);
+
+               if (!aggr)
+                       return OSPF_FAILURE;
+
+               SET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
+               ospf_external_aggr_add(ospf, aggr);
+               ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_ADD);
+       }
+
+       return OSPF_SUCCESS;
+}
+
+int ospf_asbr_external_rt_advertise(struct ospf *ospf, struct prefix_ipv4 *p)
+{
+       struct route_node *rn;
+       struct ospf_external_aggr_rt *aggr;
+
+       rn = route_node_lookup(ospf->rt_aggr_tbl, (struct prefix *)p);
+       if (!rn)
+               return OSPF_INVALID;
+
+       aggr = rn->info;
+
+       if (!CHECK_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
+               return OSPF_INVALID;
+
+       UNSET_FLAG(aggr->flags, OSPF_EXTERNAL_AGGRT_NO_ADVERTISE);
+
+       if (!OSPF_EXTERNAL_RT_COUNT(aggr))
+               return OSPF_SUCCESS;
+
+       ospf_external_aggr_timer(ospf, aggr, OSPF_ROUTE_AGGR_MODIFY);
+       return OSPF_SUCCESS;
+}
+
+int ospf_external_aggregator_timer_set(struct ospf *ospf, unsigned int interval)
+{
+       ospf->aggr_delay_interval = interval;
+       return OSPF_SUCCESS;
+}
index ede6c479063cf4d4415f10ffd9384102733e4a52..7759d45455ee9637c901beb1575f58592b3bba27 100644 (file)
@@ -50,8 +50,57 @@ struct external_info {
        route_tag_t orig_tag;
 
        struct route_map_set_values route_map_set;
-#define ROUTEMAP_METRIC(E)      (E)->route_map_set.metric
+#define ROUTEMAP_METRIC(E) (E)->route_map_set.metric
 #define ROUTEMAP_METRIC_TYPE(E) (E)->route_map_set.metric_type
+
+       /* Back pointer to summary address */
+       struct ospf_external_aggr_rt *aggr_route;
+
+       /* To identify the routes to be originated
+        * after a summary address deletion.
+        */
+       bool to_be_processed;
+};
+
+#define OSPF_EXTL_AGGR_DEFAULT_DELAY 5
+
+#define OSPF_EXTERNAL_RT_COUNT(aggr)                                           \
+       (((struct ospf_external_aggr_rt *)aggr)->match_extnl_hash->count)
+
+enum ospf_aggr_action_t {
+       OSPF_ROUTE_AGGR_NONE = 0,
+       OSPF_ROUTE_AGGR_ADD,
+       OSPF_ROUTE_AGGR_DEL,
+       OSPF_ROUTE_AGGR_MODIFY
+};
+
+#define OSPF_SUCCESS 1
+#define OSPF_FAILURE 0
+#define OSPF_INVALID -1
+
+#define OSPF_EXTERNAL_AGGRT_NO_ADVERTISE 0x1
+#define OSPF_EXTERNAL_AGGRT_ORIGINATED 0x2
+
+/* Data structures for external route aggregator */
+struct ospf_external_aggr_rt {
+       /* Prefix. */
+       struct prefix_ipv4 p;
+
+       /* Bit 1 : Dont advertise.
+        * Bit 2 : Originated as Type-5
+        */
+       uint8_t flags;
+
+       /* Tag for summary route */
+       route_tag_t tag;
+
+       /* Action to be done at the delay
+        * timer expairy.
+        */
+       enum ospf_aggr_action_t action;
+
+       /* Hash Table of external routes */
+       struct hash *match_extnl_hash;
 };
 
 #define OSPF_ASBR_CHECK_DELAY 30
@@ -81,4 +130,36 @@ extern void ospf_asbr_route_install_lsa(struct ospf_lsa *);
 extern struct ospf_lsa *ospf_external_info_find_lsa(struct ospf *,
                                                    struct prefix_ipv4 *p);
 
+/* External Route Aggregator */
+extern void ospf_asbr_external_aggregator_init(struct ospf *instance);
+extern void ospf_external_aggregator_free(struct ospf_external_aggr_rt *aggr);
+extern bool is_valid_summary_addr(struct prefix_ipv4 *p);
+extern struct ospf_external_aggr_rt *
+ospf_external_aggr_match(struct ospf *ospf, struct prefix_ipv4 *p);
+extern void ospf_unlink_ei_from_aggr(struct ospf *ospf,
+                                    struct ospf_external_aggr_rt *aggr,
+                                    struct external_info *ei);
+extern struct ospf_lsa *
+ospf_originate_summary_lsa(struct ospf *ospf,
+                          struct ospf_external_aggr_rt *aggr,
+                          struct external_info *ei);
+extern int ospf_external_aggregator_timer_set(struct ospf *ospf,
+                                             unsigned int interval);
+extern void ospf_external_aggrigator_free(struct ospf_external_aggr_rt *aggr);
+
+extern struct ospf_external_aggr_rt *
+ospf_extrenal_aggregator_lookup(struct ospf *ospf, struct prefix_ipv4 *p);
+
+void ospf_unset_all_aggr_flag(struct ospf *ospf);
+
+extern int ospf_asbr_external_aggregator_set(struct ospf *ospf,
+                                            struct prefix_ipv4 *p,
+                                            route_tag_t tag);
+extern int ospf_asbr_external_aggregator_unset(struct ospf *ospf,
+                                              struct prefix_ipv4 *p,
+                                              route_tag_t tag);
+extern int ospf_asbr_external_rt_no_advertise(struct ospf *ospf,
+                                             struct prefix_ipv4 *p);
+extern int ospf_asbr_external_rt_advertise(struct ospf *ospf,
+                                          struct prefix_ipv4 *p);
 #endif /* _ZEBRA_OSPF_ASBR_H */
index d2a30477b0666c8189e3afdacdfb9dd5f01148ed..3606efc76f1090916497b571448e9165b33385b8 100644 (file)
@@ -179,8 +179,8 @@ ospf_ase_calculate_asbr_route (struct ospf *ospf,
   if (asbr_route == NULL)
     {
       if (IS_DEBUG_OSPF (lsa, LSA))
-       zlog_debug ("ospf_ase_calculate(): Route to ASBR %s not found",
-                   inet_ntoa (asbr.prefix));
+       zlog_debug ("ospf_ase_calculate(): Route to ASBR %pI4 not found",
+                   &asbr.prefix);
       return NULL;
     }
 
@@ -283,7 +283,6 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa)
        struct prefix_ipv4 asbr, p;
        struct route_node *rn;
        struct ospf_route *new, * or ;
-       char buf1[INET_ADDRSTRLEN];
        int ret;
 
        assert(lsa);
@@ -301,11 +300,10 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa)
        }
 
        if (IS_DEBUG_OSPF(lsa, LSA)) {
-               snprintf(buf1, sizeof(buf1), "%s",
-                        inet_ntoa(al->header.adv_router));
                zlog_debug(
-                       "Route[External]: Calculate AS-external-LSA to %s/%d adv_router %s",
-                       inet_ntoa(al->header.id), ip_masklen(al->mask), buf1);
+                       "Route[External]: Calculate AS-external-LSA to %pI4/%d adv_router %pI4",
+                       &al->header.id, ip_masklen(al->mask),
+                       &al->header.adv_router);
        }
 
        /* (1) If the cost specified by the LSA is LSInfinity, or if the
@@ -457,9 +455,8 @@ int ospf_ase_calculate_route(struct ospf *ospf, struct ospf_lsa *lsa)
 
        if (!rn || (or = rn->info) == NULL) {
                if (IS_DEBUG_OSPF(lsa, LSA))
-                       zlog_debug("Route[External]: Adding a new route %s/%d with paths %u",
-                                  inet_ntoa(p.prefix), p.prefixlen,
-                                  listcount(asbr_route->paths));
+                       zlog_debug("Route[External]: Adding a new route %pFX with paths %u",
+                                  &p, listcount(asbr_route->paths));
 
                ospf_route_add(ospf->new_external_route, &p, new, asbr_route);
 
@@ -658,8 +655,8 @@ static int ospf_ase_calculate_timer(struct thread *t)
                        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
                                if (IS_DEBUG_OSPF_NSSA)
                                        zlog_debug(
-                                               "ospf_ase_calculate_timer(): looking at area %s",
-                                               inet_ntoa(area->area_id));
+                                               "ospf_ase_calculate_timer(): looking at area %pI4",
+                                               &area->area_id);
 
                                if (area->external_routing == OSPF_AREA_NSSA)
                                        LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
index d2c5090f2fc293ebc6382a0e3a46bc92acc48cba..46407209529ef17343f268df13da4abe0a0697fb 100644 (file)
@@ -76,9 +76,9 @@ static void ospf_bfd_reg_dereg_nbr(struct ospf_neighbor *nbr, int command)
        bfd_info = (struct bfd_info *)params->bfd_info;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
-               zlog_debug("%s nbr (%s) with BFD. OSPF vrf %s",
+               zlog_debug("%s nbr (%pI4) with BFD. OSPF vrf %s",
                           bfd_get_command_dbg_str(command),
-                          inet_ntoa(nbr->src),
+                          &nbr->src,
                           ospf_vrf_id_to_name(oi->ospf->vrf_id));
 
        cbit = CHECK_FLAG(bfd_info->flags, BFD_FLAG_BFD_CBIT_ON);
@@ -180,8 +180,8 @@ static int ospf_bfd_nbr_replay(ZAPI_CALLBACK_ARGS)
                                        continue;
 
                                if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
-                                       zlog_debug("Replaying nbr (%s) to BFD",
-                                                  inet_ntoa(nbr->src));
+                                       zlog_debug("Replaying nbr (%pI4) to BFD",
+                                                  &nbr->src);
 
                                ospf_bfd_reg_dereg_nbr(nbr,
                                                       ZEBRA_BFD_DEST_UPDATE);
@@ -217,12 +217,9 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
        if ((ifp == NULL) || (p.family != AF_INET))
                return 0;
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&p, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s bfd destination %s %s",
-                          ifp->name, buf, bfd_get_status_str(status));
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: interface %s bfd destination %pFX %s",
+                          ifp->name, &p, bfd_get_status_str(status));
 
        params = IF_DEF_PARAMS(ifp);
        if (!params->bfd_info)
@@ -269,18 +266,18 @@ static int ospf_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
                if ((status == BFD_STATUS_DOWN)
                    && (old_status == BFD_STATUS_UP)) {
                        if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
-                               zlog_debug("NSM[%s:%s]: BFD Down",
+                               zlog_debug("NSM[%s:%pI4]: BFD Down",
                                           IF_NAME(nbr->oi),
-                                          inet_ntoa(nbr->address.u.prefix4));
+                                          &nbr->address.u.prefix4);
 
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
                }
                if ((status == BFD_STATUS_UP)
                    && (old_status == BFD_STATUS_DOWN)) {
                        if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
-                               zlog_debug("NSM[%s:%s]: BFD Up",
+                               zlog_debug("NSM[%s:%pI4]: BFD Up",
                                           IF_NAME(nbr->oi),
-                                          inet_ntoa(nbr->address.u.prefix4));
+                                          &nbr->address.u.prefix4);
                }
        }
 
index e8798e023e2c50324db25f5b8236db717c10a0d2..e15c9c42c77991e7e038a381234e28c46d9179a2 100644 (file)
@@ -41,6 +41,9 @@
 #include "ospfd/ospf_dump.h"
 #include "ospfd/ospf_packet.h"
 #include "ospfd/ospf_network.h"
+#ifndef VTYSH_EXTRACT_PL
+#include "ospfd/ospf_dump_clippy.c"
+#endif
 
 /* Configuration debug option variables. */
 unsigned long conf_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
@@ -55,6 +58,7 @@ unsigned long conf_debug_ospf_ext = 0;
 unsigned long conf_debug_ospf_sr = 0;
 unsigned long conf_debug_ospf_defaultinfo = 0;
 unsigned long conf_debug_ospf_ldp_sync = 0;
+unsigned long conf_debug_ospf_gr = 0;
 
 /* Enable debug option variables -- valid only session. */
 unsigned long term_debug_ospf_packet[5] = {0, 0, 0, 0, 0};
@@ -69,6 +73,7 @@ unsigned long term_debug_ospf_ext = 0;
 unsigned long term_debug_ospf_sr = 0;
 unsigned long term_debug_ospf_defaultinfo;
 unsigned long term_debug_ospf_ldp_sync;
+unsigned long term_debug_ospf_gr = 0;
 
 const char *ospf_redist_string(unsigned int route_type)
 {
@@ -237,20 +242,20 @@ static void ospf_packet_hello_dump(struct stream *s, uint16_t length)
        hello = (struct ospf_hello *)stream_pnt(s);
 
        zlog_debug("Hello");
-       zlog_debug("  NetworkMask %s", inet_ntoa(hello->network_mask));
+       zlog_debug("  NetworkMask %pI4", &hello->network_mask);
        zlog_debug("  HelloInterval %d", ntohs(hello->hello_interval));
        zlog_debug("  Options %d (%s)", hello->options,
                   ospf_options_dump(hello->options));
        zlog_debug("  RtrPriority %d", hello->priority);
        zlog_debug("  RtrDeadInterval %ld",
                   (unsigned long)ntohl(hello->dead_interval));
-       zlog_debug("  DRouter %s", inet_ntoa(hello->d_router));
-       zlog_debug("  BDRouter %s", inet_ntoa(hello->bd_router));
+       zlog_debug("  DRouter %pI4", &hello->d_router);
+       zlog_debug("  BDRouter %pI4", &hello->bd_router);
 
        length -= OSPF_HEADER_SIZE + OSPF_HELLO_MIN_SIZE;
        zlog_debug("  # Neighbors %d", length / 4);
        for (i = 0; length > 0; i++, length -= sizeof(struct in_addr))
-               zlog_debug("    Neighbor %s", inet_ntoa(hello->neighbors[i]));
+               zlog_debug("    Neighbor %pI4", &hello->neighbors[i]);
 }
 
 static char *ospf_dd_flags_dump(uint8_t flags, char *buf, size_t size)
@@ -287,9 +292,9 @@ static void ospf_router_lsa_dump(struct stream *s, uint16_t length)
 
        len = ntohs(rl->header.length) - OSPF_LSA_HEADER_SIZE - 4;
        for (i = 0; len > 0; i++) {
-               zlog_debug("    Link ID %s", inet_ntoa(rl->link[i].link_id));
-               zlog_debug("    Link Data %s",
-                          inet_ntoa(rl->link[i].link_data));
+               zlog_debug("    Link ID %pI4", &rl->link[i].link_id);
+               zlog_debug("    Link Data %pI4",
+                          &rl->link[i].link_data);
                zlog_debug("    Type %d", (uint8_t)rl->link[i].type);
                zlog_debug("    TOS %d", (uint8_t)rl->link[i].tos);
                zlog_debug("    metric %d", ntohs(rl->link[i].metric));
@@ -312,11 +317,11 @@ static void ospf_network_lsa_dump(struct stream *s, uint16_t length)
        zlog_debug ("Network-LSA size %d",
        ntohs (nl->header.length) - OSPF_LSA_HEADER_SIZE);
        */
-       zlog_debug("    Network Mask %s", inet_ntoa(nl->mask));
+       zlog_debug("    Network Mask %pI4", &nl->mask);
        zlog_debug("    # Attached Routers %d", cnt);
        for (i = 0; i < cnt; i++)
-               zlog_debug("      Attached Router %s",
-                          inet_ntoa(nl->routers[i]));
+               zlog_debug("      Attached Router %pI4",
+                          &nl->routers[i]);
 }
 
 static void ospf_summary_lsa_dump(struct stream *s, uint16_t length)
@@ -328,7 +333,7 @@ static void ospf_summary_lsa_dump(struct stream *s, uint16_t length)
        sl = (struct summary_lsa *)stream_pnt(s);
 
        zlog_debug("  Summary-LSA");
-       zlog_debug("    Network Mask %s", inet_ntoa(sl->mask));
+       zlog_debug("    Network Mask %pI4", &sl->mask);
 
        size = ntohs(sl->header.length) - OSPF_LSA_HEADER_SIZE - 4;
        for (i = 0; size > 0; size -= 4, i++)
@@ -344,15 +349,15 @@ static void ospf_as_external_lsa_dump(struct stream *s, uint16_t length)
 
        al = (struct as_external_lsa *)stream_pnt(s);
        zlog_debug("  %s", ospf_lsa_type_msg[al->header.type].str);
-       zlog_debug("    Network Mask %s", inet_ntoa(al->mask));
+       zlog_debug("    Network Mask %pI4", &al->mask);
 
        size = ntohs(al->header.length) - OSPF_LSA_HEADER_SIZE - 4;
        for (i = 0; size > 0; size -= 12, i++) {
                zlog_debug("    bit %s TOS=%d metric %d",
                           IS_EXTERNAL_METRIC(al->e[i].tos) ? "E" : "-",
                           al->e[i].tos & 0x7f, GET_METRIC(al->e[i].metric));
-               zlog_debug("    Forwarding address %s",
-                          inet_ntoa(al->e[i].fwd_addr));
+               zlog_debug("    Forwarding address %pI4",
+                          &al->e[i].fwd_addr);
                zlog_debug("    External Route Tag %" ROUTE_TAG_PRI,
                           al->e[i].route_tag);
        }
@@ -422,8 +427,8 @@ static void ospf_packet_ls_req_dump(struct stream *s, uint16_t length)
                adv_router.s_addr = stream_get_ipv4(s);
 
                zlog_debug("  LS type %d", ls_type);
-               zlog_debug("  Link State ID %s", inet_ntoa(ls_id));
-               zlog_debug("  Advertising Router %s", inet_ntoa(adv_router));
+               zlog_debug("  Link State ID %pI4", &ls_id);
+               zlog_debug("  Advertising Router %pI4", &adv_router);
        }
 
        stream_set_getp(s, sp);
@@ -514,8 +519,8 @@ static void ospf_header_dump(struct ospf_header *ospfh)
        zlog_debug("  Type %d (%s)", ospfh->type,
                   lookup_msg(ospf_packet_type_str, ospfh->type, NULL));
        zlog_debug("  Packet Len %d", ntohs(ospfh->length));
-       zlog_debug("  Router ID %s", inet_ntoa(ospfh->router_id));
-       zlog_debug("  Area ID %s", inet_ntoa(ospfh->area_id));
+       zlog_debug("  Router ID %pI4", &ospfh->router_id);
+       zlog_debug("  Area ID %pI4", &ospfh->area_id);
        zlog_debug("  Checksum 0x%x", ntohs(ospfh->checksum));
        zlog_debug("  AuType %s",
                   lookup_msg(ospf_auth_type_str, auth_type, NULL));
@@ -996,6 +1001,8 @@ static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc,
                                DEBUG_ON(lsa, LSA_INSTALL);
                        else if (strmatch(argv[arg_base]->text, "refresh"))
                                DEBUG_ON(lsa, LSA_REFRESH);
+                       else if (strmatch(argv[arg_base]->text, "aggregate"))
+                               DEBUG_ON(lsa, EXTNL_LSA_AGGR);
                }
 
                return CMD_SUCCESS;
@@ -1013,6 +1020,8 @@ static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc,
                        TERM_DEBUG_ON(lsa, LSA_INSTALL);
                else if (strmatch(argv[arg_base]->text, "refresh"))
                        TERM_DEBUG_ON(lsa, LSA_REFRESH);
+               else if (strmatch(argv[arg_base]->text, "aggregate"))
+                       TERM_DEBUG_ON(lsa, EXTNL_LSA_AGGR);
        }
 
        return CMD_SUCCESS;
@@ -1020,21 +1029,23 @@ static int debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc,
 
 DEFUN (debug_ospf_lsa,
        debug_ospf_lsa_cmd,
-       "debug ospf lsa [<generate|flooding|install|refresh>]",
+       "debug ospf lsa [<generate|flooding|install|refresh|aggregate>]",
        DEBUG_STR
        OSPF_STR
        "OSPF Link State Advertisement\n"
        "LSA Generation\n"
        "LSA Flooding\n"
        "LSA Install/Delete\n"
-       "LSA Refresh\n")
+       "LSA Refresh\n"
+       "External LSA Aggregation\n")
 {
        return debug_ospf_lsa_common(vty, 3, argc, argv);
 }
 
 DEFUN (debug_ospf_instance_lsa,
        debug_ospf_instance_lsa_cmd,
-       "debug ospf (1-65535) lsa [<generate|flooding|install|refresh>]",
+       "debug ospf (1-65535) lsa "
+       "[<generate|flooding|install|refresh|aggregate>]",
        DEBUG_STR
        OSPF_STR
        "Instance ID\n"
@@ -1042,7 +1053,8 @@ DEFUN (debug_ospf_instance_lsa,
        "LSA Generation\n"
        "LSA Flooding\n"
        "LSA Install/Delete\n"
-       "LSA Refresh\n")
+       "LSA Refresh\n"
+       "External LSA Aggregation\n")
 {
        int idx_number = 2;
        unsigned short instance = 0;
@@ -1070,6 +1082,8 @@ static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc,
                                DEBUG_OFF(lsa, LSA_INSTALL);
                        else if (strmatch(argv[arg_base]->text, "refresh"))
                                DEBUG_OFF(lsa, LSA_REFRESH);
+                       else if (strmatch(argv[arg_base]->text, "aggregate"))
+                               DEBUG_OFF(lsa, EXTNL_LSA_AGGR);
                }
 
                return CMD_SUCCESS;
@@ -1087,6 +1101,8 @@ static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc,
                        TERM_DEBUG_OFF(lsa, LSA_INSTALL);
                else if (strmatch(argv[arg_base]->text, "refresh"))
                        TERM_DEBUG_OFF(lsa, LSA_REFRESH);
+               else if (strmatch(argv[arg_base]->text, "aggregate"))
+                       TERM_DEBUG_OFF(lsa, EXTNL_LSA_AGGR);
        }
 
        return CMD_SUCCESS;
@@ -1094,7 +1110,7 @@ static int no_debug_ospf_lsa_common(struct vty *vty, int arg_base, int argc,
 
 DEFUN (no_debug_ospf_lsa,
        no_debug_ospf_lsa_cmd,
-       "no debug ospf lsa [<generate|flooding|install|refresh>]",
+       "no debug ospf lsa [<generate|flooding|install|refresh|aggregate>]",
        NO_STR
        DEBUG_STR
        OSPF_STR
@@ -1102,14 +1118,16 @@ DEFUN (no_debug_ospf_lsa,
        "LSA Generation\n"
        "LSA Flooding\n"
        "LSA Install/Delete\n"
-       "LSA Refres\n")
+       "LSA Refres\n"
+       "External LSA Aggregation\n")
 {
        return no_debug_ospf_lsa_common(vty, 4, argc, argv);
 }
 
 DEFUN (no_debug_ospf_instance_lsa,
        no_debug_ospf_instance_lsa_cmd,
-       "no debug ospf (1-65535) lsa [<generate|flooding|install|refresh>]",
+       "no debug ospf (1-65535) lsa "
+       "[<generate|flooding|install|refresh|aggregate>]",
        NO_STR
        DEBUG_STR
        OSPF_STR
@@ -1118,7 +1136,8 @@ DEFUN (no_debug_ospf_instance_lsa,
        "LSA Generation\n"
        "LSA Flooding\n"
        "LSA Install/Delete\n"
-       "LSA Refres\n")
+       "LSA Refres\n"
+       "External LSA Aggregation\n")
 {
        int idx_number = 3;
        unsigned short instance = 0;
@@ -1501,6 +1520,26 @@ DEFUN(no_debug_ospf_ldp_sync,
        if (vty->node == CONFIG_NODE)
                CONF_DEBUG_OFF(ldp_sync, LDP_SYNC);
        TERM_DEBUG_OFF(ldp_sync, LDP_SYNC);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (debug_ospf_gr,
+       debug_ospf_gr_cmd,
+       "[no$no] debug ospf graceful-restart helper",
+       NO_STR
+       DEBUG_STR OSPF_STR
+       "Gracefull restart\n"
+       "Helper Information\n")
+{
+       if (vty->node == CONFIG_NODE)
+               CONF_DEBUG_ON(gr, GR_HELPER);
+
+       if (!no)
+               TERM_DEBUG_ON(gr, GR_HELPER);
+       else
+               TERM_DEBUG_OFF(gr, GR_HELPER);
+
        return CMD_SUCCESS;
 }
 
@@ -1667,6 +1706,10 @@ static int show_debugging_ospf_common(struct vty *vty, struct ospf *ospf)
        if (IS_DEBUG_OSPF(ldp_sync, LDP_SYNC) == OSPF_DEBUG_LDP_SYNC)
                vty_out(vty, "  OSPF ldp-sync debugging is on\n");
 
+       /* Show debug status for GR helper. */
+       if (IS_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER)
+               vty_out(vty, "  OSPF Graceful Restart Helper debugging is on\n");
+
        vty_out(vty, "\n");
 
        return CMD_SUCCESS;
@@ -1853,6 +1896,13 @@ static int config_write_debug(struct vty *vty)
                vty_out(vty, "debug ospf%s ldp-sync\n", str);
                write = 1;
        }
+
+       /* debug ospf gr helper */
+       if (IS_CONF_DEBUG_OSPF(gr, GR_HELPER) == OSPF_DEBUG_GR_HELPER) {
+               vty_out(vty, "debug ospf%s graceful-restart helper\n", str);
+               write = 1;
+       }
+
        return write;
 }
 
@@ -1882,6 +1932,7 @@ void ospf_debug_init(void)
        install_element(ENABLE_NODE, &no_debug_ospf_sr_cmd);
        install_element(ENABLE_NODE, &no_debug_ospf_default_info_cmd);
        install_element(ENABLE_NODE, &no_debug_ospf_ldp_sync_cmd);
+       install_element(ENABLE_NODE, &debug_ospf_gr_cmd);
 
        install_element(ENABLE_NODE, &show_debugging_ospf_instance_cmd);
        install_element(ENABLE_NODE, &debug_ospf_packet_cmd);
@@ -1922,6 +1973,7 @@ void ospf_debug_init(void)
        install_element(CONFIG_NODE, &no_debug_ospf_sr_cmd);
        install_element(CONFIG_NODE, &no_debug_ospf_default_info_cmd);
        install_element(CONFIG_NODE, &no_debug_ospf_ldp_sync_cmd);
+       install_element(CONFIG_NODE, &debug_ospf_gr_cmd);
 
        install_element(CONFIG_NODE, &debug_ospf_instance_nsm_cmd);
        install_element(CONFIG_NODE, &debug_ospf_instance_lsa_cmd);
index faae27e2cf593f2c4ff0054d792cc1c8a96e2f23..ea607fef7cdbd50bde063060b1d95826bfc7c5be 100644 (file)
@@ -49,6 +49,7 @@
 #define OSPF_DEBUG_LSA_INSTALL  0x04
 #define OSPF_DEBUG_LSA_REFRESH  0x08
 #define OSPF_DEBUG_LSA         0x0F
+#define OSPF_DEBUG_EXTNL_LSA_AGGR 0x10
 
 #define OSPF_DEBUG_ZEBRA_INTERFACE     0x01
 #define OSPF_DEBUG_ZEBRA_REDISTRIBUTE  0x02
@@ -62,6 +63,9 @@
 #define OSPF_DEBUG_DEFAULTINFO 0x20
 #define OSPF_DEBUG_LDP_SYNC 0x40
 
+#define OSPF_DEBUG_GR_HELPER 0x01
+#define OSPF_DEBUG_GR 0x03
+
 /* Macro for setting debug option. */
 #define CONF_DEBUG_PACKET_ON(a, b)         conf_debug_ospf_packet[a] |= (b)
 #define CONF_DEBUG_PACKET_OFF(a, b)        conf_debug_ospf_packet[a] &= ~(b)
 #define IS_DEBUG_OSPF_DEFAULT_INFO IS_DEBUG_OSPF(defaultinfo, DEFAULTINFO)
 
 #define IS_DEBUG_OSPF_LDP_SYNC IS_DEBUG_OSPF(ldp_sync, LDP_SYNC)
+#define IS_DEBUG_OSPF_GR_HELPER IS_DEBUG_OSPF(gr, GR_HELPER)
 
 #define IS_CONF_DEBUG_OSPF_PACKET(a, b)                                        \
        (conf_debug_ospf_packet[a] & OSPF_DEBUG_##b)
@@ -130,6 +135,7 @@ extern unsigned long term_debug_ospf_ext;
 extern unsigned long term_debug_ospf_sr;
 extern unsigned long term_debug_ospf_defaultinfo;
 extern unsigned long term_debug_ospf_ldp_sync;
+extern unsigned long term_debug_ospf_gr;
 
 /* Message Strings. */
 extern char *ospf_lsa_type_str[];
index e24936a4734b23476d52292cdd2888c7d4465812..4b68b006e2b1241b39770e9279cbd285afff598c 100644 (file)
@@ -127,8 +127,8 @@ void ospf_lsa_header_dump(struct lsa_header *lsah)
                   ospf_options_dump(lsah->options));
        zlog_debug("    LS type %d (%s)", lsah->type,
                   (lsah->type ? lsah_type : "unknown type"));
-       zlog_debug("    Link State ID %s", inet_ntoa(lsah->id));
-       zlog_debug("    Advertising Router %s", inet_ntoa(lsah->adv_router));
+       zlog_debug("    Link State ID %pI4", &lsah->id);
+       zlog_debug("    Advertising Router %pI4", &lsah->adv_router);
        zlog_debug("    LS sequence number 0x%lx",
                   (unsigned long)ntohl(lsah->ls_seqnum));
        zlog_debug("    LS checksum 0x%x", ntohs(lsah->checksum));
index 90dc108c0ed7c8b373d9165127ac128147e434c0..4fa61221a64d218542881a2245ce8f526a8a5cae 100644 (file)
@@ -462,6 +462,10 @@ static void set_rmt_itf_addr(struct ext_itf *exti, struct in_addr rmtif)
 static void ospf_extended_lsa_delete(struct ext_itf *exti)
 {
 
+       /* Avoid deleting LSA if Extended is not enable */
+       if (!OspfEXT.enabled)
+               return;
+
        /* Process only Active Extended Prefix/Link LSA */
        if (!CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ACTIVE))
                return;
@@ -755,16 +759,16 @@ static void ospf_ext_ism_change(struct ospf_interface *oi, int old_status)
        if (oi->type == OSPF_IFTYPE_LOOPBACK) {
                exti->stype = PREF_SID;
                exti->type = OPAQUE_TYPE_EXTENDED_PREFIX_LSA;
-               exti->flags = EXT_LPFLG_LSA_ACTIVE;
                exti->instance = get_ext_pref_instance_value();
                exti->area = oi->area;
 
-               osr_debug("EXT (%s): Set Prefix SID to interface %s ",
-                         __func__, oi->ifp->name);
-
                /* Complete SRDB if the interface belongs to a Prefix */
-               if (OspfEXT.enabled)
+               if (OspfEXT.enabled) {
+                       osr_debug("EXT (%s): Set Prefix SID to interface %s ",
+                                 __func__, oi->ifp->name);
+                       exti->flags = EXT_LPFLG_LSA_ACTIVE;
                        ospf_sr_update_local_prefix(oi->ifp, oi->address);
+               }
        } else {
                /* Determine if interface is related to Adj. or LAN Adj. SID */
                if (oi->state == ISM_DR)
@@ -780,9 +784,11 @@ static void ospf_ext_ism_change(struct ospf_interface *oi, int old_status)
                 * Note: Adjacency SID information are completed when ospf
                 * adjacency become up see ospf_ext_link_nsm_change()
                 */
-               osr_debug("EXT (%s): Set %sAdjacency SID for interface %s ",
-                         __func__, exti->stype == ADJ_SID ? "" : "LAN-",
-                         oi->ifp->name);
+               if (OspfEXT.enabled)
+                       osr_debug(
+                               "EXT (%s): Set %sAdjacency SID for interface %s ",
+                               __func__, exti->stype == ADJ_SID ? "" : "LAN-",
+                               oi->ifp->name);
        }
 }
 
@@ -817,7 +823,8 @@ static void ospf_ext_link_nsm_change(struct ospf_neighbor *nbr, int old_status)
        }
 
        /* Remove Extended Link if Neighbor State goes Down or Deleted */
-       if (nbr->state == NSM_Down || nbr->state == NSM_Deleted) {
+       if (OspfEXT.enabled
+           && (nbr->state == NSM_Down || nbr->state == NSM_Deleted)) {
                ospf_ext_link_delete_adj_sid(exti);
                if (CHECK_FLAG(exti->flags, EXT_LPFLG_LSA_ENGAGED))
                        ospf_ext_link_lsa_schedule(exti, FLUSH_THIS_LSA);
@@ -1716,8 +1723,8 @@ static uint16_t show_vty_ext_link_rmt_itf_addr(struct vty *vty,
        top = (struct ext_subtlv_rmt_itf_addr *)tlvh;
 
        vty_out(vty,
-               "  Remote Interface Address Sub-TLV: Length %u\n        Address: %s\n",
-               ntohs(top->header.length), inet_ntoa(top->value));
+               "  Remote Interface Address Sub-TLV: Length %u\n        Address: %pI4\n",
+               ntohs(top->header.length), &top->value);
 
        return TLV_SIZE(tlvh);
 }
@@ -1748,9 +1755,9 @@ static uint16_t show_vty_ext_link_lan_adj_sid(struct vty *vty,
                (struct ext_subtlv_lan_adj_sid *)tlvh;
 
        vty_out(vty,
-               "  LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %s\n\t%s: %u\n",
+               "  LAN-Adj-SID Sub-TLV: Length %u\n\tFlags: 0x%x\n\tMT-ID:0x%x\n\tWeight: 0x%x\n\tNeighbor ID: %pI4\n\t%s: %u\n",
                ntohs(top->header.length), top->flags, top->mtid, top->weight,
-               inet_ntoa(top->neighbor_id),
+               &top->neighbor_id,
                CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG) ? "Label"
                                                                     : "Index",
                CHECK_FLAG(top->flags, EXT_SUBTLV_LINK_ADJ_SID_VFLG)
@@ -1778,10 +1785,10 @@ static uint16_t show_vty_link_info(struct vty *vty, struct tlv_header *ext)
 
        vty_out(vty,
                "  Extended Link TLV: Length %u\n       Link Type: 0x%x\n"
-               "       Link ID: %s\n",
+               "       Link ID: %pI4\n",
                ntohs(top->header.length), top->link_type,
-               inet_ntoa(top->link_id));
-       vty_out(vty, "  Link data: %s\n", inet_ntoa(top->link_data));
+               &top->link_id);
+       vty_out(vty, "  Link data: %pI4\n", &top->link_data);
 
        tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
                                     + EXT_TLV_LINK_SIZE);
@@ -1858,9 +1865,9 @@ static uint16_t show_vty_pref_info(struct vty *vty, struct tlv_header *ext)
 
        vty_out(vty,
                "  Extended Prefix TLV: Length %u\n\tRoute Type: %u\n"
-               "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %s/%u\n",
+               "\tAddress Family: 0x%x\n\tFlags: 0x%x\n\tAddress: %pI4/%u\n",
                ntohs(top->header.length), top->route_type, top->af, top->flags,
-               inet_ntoa(top->address), top->pref_length);
+               &top->address, top->pref_length);
 
        tlvh = (struct tlv_header *)((char *)(ext) + TLV_HDR_SIZE
                                     + EXT_TLV_PREFIX_SIZE);
index 58afb2b39282c0dcecdd5f45e21146363becfecf..cb2b7c23651221cef90f35e0f3e4704d7b045df5 100644 (file)
@@ -154,12 +154,15 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf,
        struct ospf_interface *oi;
        struct external_info *ei;
        struct listnode *node;
+       struct as_external_lsa *al;
+       struct prefix_ipv4 p;
+       struct ospf_external_aggr_rt *aggr;
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "%s:LSA[Type%d:%s]: Process self-originated LSA seq 0x%x",
+                       "%s:LSA[Type%d:%pI4]: Process self-originated LSA seq 0x%x",
                        ospf_get_name(ospf), new->data->type,
-                       inet_ntoa(new->data->id), ntohl(new->data->ls_seqnum));
+                       &new->data->id, ntohl(new->data->ls_seqnum));
 
        /* If we're here, we installed a self-originated LSA that we received
           from a neighbor, i.e. it's more recent.  We must see whether we want
@@ -222,12 +225,51 @@ static void ospf_process_self_originated_lsa(struct ospf *ospf,
                        ospf_translated_nssa_refresh(ospf, NULL, new);
                        return;
                }
+
+               al = (struct as_external_lsa *)new->data;
+               p.family = AF_INET;
+               p.prefixlen = ip_masklen(al->mask);
+               p.prefix = new->data->id;
+
                ei = ospf_external_info_check(ospf, new);
-               if (ei)
+               if (ei) {
+                       if (ospf_external_aggr_match(ospf, &ei->p)) {
+                               if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                                       zlog_debug(
+                                               "%s, Matching external aggregate route found for %pI4, so don't refresh it.",
+                                               __func__,
+                                               &ei->p.prefix);
+
+                               /* Aggregated external route shouldn't
+                                * be in LSDB.
+                                */
+                               if (!IS_LSA_MAXAGE(new))
+                                       ospf_lsa_flush_as(ospf, new);
+
+                               return;
+                       }
+
                        ospf_external_lsa_refresh(ospf, new, ei,
-                                                 LSA_REFRESH_FORCE);
-               else
-                       ospf_lsa_flush_as(ospf, new);
+                                                 LSA_REFRESH_FORCE, false);
+               } else {
+                       aggr = (struct ospf_external_aggr_rt *)
+                               ospf_extrenal_aggregator_lookup(ospf, &p);
+                       if (aggr) {
+                               struct external_info ei_aggr;
+
+                               memset(&ei_aggr, 0,
+                                       sizeof(struct external_info));
+                               ei_aggr.p = aggr->p;
+                               ei_aggr.tag = aggr->tag;
+                               ei_aggr.instance = ospf->instance;
+                               ei_aggr.route_map_set.metric = -1;
+                               ei_aggr.route_map_set.metric_type = -1;
+
+                               ospf_external_lsa_refresh(ospf, new, &ei_aggr,
+                                                 LSA_REFRESH_FORCE, true);
+                       } else
+                               ospf_lsa_flush_as(ospf, new);
+               }
                break;
        case OSPF_OPAQUE_AREA_LSA:
                ospf_opaque_lsa_refresh(new);
@@ -276,8 +318,8 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "%s:LSA[Flooding]: start, NBR %s (%s), cur(%p), New-LSA[%s]",
-                       ospf_get_name(ospf), inet_ntoa(nbr->router_id),
+                       "%s:LSA[Flooding]: start, NBR %pI4 (%s), cur(%p), New-LSA[%s]",
+                       ospf_get_name(ospf), &nbr->router_id,
                        lookup_msg(ospf_nsm_state_msg, nbr->state, NULL),
                        (void *)current, dump_lsa_key(new));
 
@@ -337,6 +379,45 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
        SET_FLAG(new->flags, OSPF_LSA_RECEIVED);
        (void)ospf_lsa_is_self_originated(ospf, new); /* Let it set the flag */
 
+       /* Received Grace LSA */
+       if (IS_GRACE_LSA(new)) {
+
+               if (IS_LSA_MAXAGE(new)) {
+
+                       /*  Handling Max age grace LSA.*/
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug(
+                                       "%s, Received a maxage GRACE-LSA from router %pI4",
+                                       __PRETTY_FUNCTION__,
+                                       &new->data->adv_router);
+
+                       if (current) {
+                               ospf_process_maxage_grace_lsa(ospf, new, nbr);
+                       } else {
+                               if (IS_DEBUG_OSPF_GR_HELPER)
+                                       zlog_debug(
+                                               "%s, Grace LSA doesn't exist in lsdb, so discarding grace lsa",
+                                               __PRETTY_FUNCTION__);
+                               return -1;
+                       }
+               } else {
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug(
+                                       "%s, Received a GRACE-LSA from router %pI4",
+                                       __PRETTY_FUNCTION__,
+                                       &new->data->adv_router);
+
+                       if (ospf_process_grace_lsa(ospf, new, nbr)
+                           == OSPF_GR_NOT_HELPER) {
+                               if (IS_DEBUG_OSPF_GR_HELPER)
+                                       zlog_debug(
+                                               "%s, Not moving to HELPER role, So discarding grace LSA",
+                                               __PRETTY_FUNCTION__);
+                               return -1;
+                       }
+               }
+       }
+
        /* Install the new LSA in the link state database
           (replacing the current database copy).  This may cause the
           routing table calculation to be scheduled.  In addition,
@@ -373,17 +454,21 @@ static int ospf_flood_through_interface(struct ospf_interface *oi,
        struct ospf_neighbor *onbr;
        struct route_node *rn;
        int retx_flag;
+       char buf[PREFIX_STRLEN];
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
                        "%s:ospf_flood_through_interface(): considering int %s, INBR(%s), LSA[%s] AGE %u",
-                       ospf_get_name(oi->ospf), IF_NAME(oi), inbr ? inet_ntoa(inbr->router_id) : "NULL",
+                       ospf_get_name(oi->ospf), IF_NAME(oi),
+                       inbr ?
+                       inet_ntop(AF_INET, &inbr->router_id, buf, sizeof(buf)) :
+                       "NULL",
                        dump_lsa_key(lsa), ntohs(lsa->data->ls_age));
 
        if (!ospf_if_is_enable(oi))
                return 0;
 
-       /* Remember if new LSA is aded to a retransmit list. */
+       /* Remember if new LSA is added to a retransmit list. */
        retx_flag = 0;
 
        /* Each of the neighbors attached to this interface are examined,
@@ -398,8 +483,8 @@ static int ospf_flood_through_interface(struct ospf_interface *oi,
                onbr = rn->info;
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_flood_through_interface(): considering nbr %s(%s) (%s)",
-                               inet_ntoa(onbr->router_id),
+                               "ospf_flood_through_interface(): considering nbr %pI4(%s) (%s)",
+                               &onbr->router_id,
                                ospf_get_name(oi->ospf),
                                lookup_msg(ospf_nsm_state_msg, onbr->state,
                                           NULL));
@@ -734,9 +819,9 @@ void ospf_ls_request_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
         * the common function "ospf_lsdb_add()" -- endo.
         */
        if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
-               zlog_debug("RqstL(%lu)++, NBR(%s(%s)), LSA[%s]",
+               zlog_debug("RqstL(%lu)++, NBR(%pI4(%s)), LSA[%s]",
                           ospf_ls_request_count(nbr),
-                          inet_ntoa(nbr->router_id),
+                          &nbr->router_id,
                           ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa));
 
        ospf_lsdb_add(&nbr->ls_req, lsa);
@@ -761,9 +846,9 @@ void ospf_ls_request_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
        }
 
        if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */
-               zlog_debug("RqstL(%lu)--, NBR(%s(%s)), LSA[%s]",
+               zlog_debug("RqstL(%lu)--, NBR(%pI4(%s)), LSA[%s]",
                           ospf_ls_request_count(nbr),
-                          inet_ntoa(nbr->router_id),
+                          &nbr->router_id,
                           ospf_get_name(nbr->oi->ospf), dump_lsa_key(lsa));
 
        ospf_lsdb_delete(&nbr->ls_req, lsa);
@@ -823,9 +908,9 @@ void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
                if (old) {
                        old->retransmit_counter--;
                        if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
-                               zlog_debug("RXmtL(%lu)--, NBR(%s(%s)), LSA[%s]",
+                               zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]",
                                           ospf_ls_retransmit_count(nbr),
-                                          inet_ntoa(nbr->router_id),
+                                          &nbr->router_id,
                                           ospf_get_name(nbr->oi->ospf),
                                           dump_lsa_key(old));
                        ospf_lsdb_delete(&nbr->ls_rxmt, old);
@@ -840,9 +925,9 @@ void ospf_ls_retransmit_add(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
                 * the common function "ospf_lsdb_add()" -- endo.
                 */
                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
-                       zlog_debug("RXmtL(%lu)++, NBR(%s(%s)), LSA[%s]",
+                       zlog_debug("RXmtL(%lu)++, NBR(%pI4(%s)), LSA[%s]",
                                   ospf_ls_retransmit_count(nbr),
-                                  inet_ntoa(nbr->router_id),
+                                  &nbr->router_id,
                                   ospf_get_name(nbr->oi->ospf),
                                   dump_lsa_key(lsa));
                ospf_lsdb_add(&nbr->ls_rxmt, lsa);
@@ -855,9 +940,9 @@ void ospf_ls_retransmit_delete(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
        if (ospf_ls_retransmit_lookup(nbr, lsa)) {
                lsa->retransmit_counter--;
                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING)) /* -- endo. */
-                       zlog_debug("RXmtL(%lu)--, NBR(%s(%s)), LSA[%s]",
+                       zlog_debug("RXmtL(%lu)--, NBR(%pI4(%s)), LSA[%s]",
                                   ospf_ls_retransmit_count(nbr),
-                                  inet_ntoa(nbr->router_id),
+                                  &nbr->router_id,
                                   ospf_get_name(nbr->oi->ospf),
                                   dump_lsa_key(lsa));
                ospf_lsdb_delete(&nbr->ls_rxmt, lsa);
@@ -936,7 +1021,7 @@ void ospf_ls_retransmit_delete_nbr_as(struct ospf *ospf, struct ospf_lsa *lsa)
 
 
 /* Sets ls_age to MaxAge and floods throu the area.
-   When we implement ASE routing, there will be anothe function
+   When we implement ASE routing, there will be another function
    flushing an LSA from the whole domain. */
 void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area)
 {
@@ -945,8 +1030,8 @@ void ospf_lsa_flush_area(struct ospf_lsa *lsa, struct ospf_area *area)
           retransmissions */
        lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("%s: MAXAGE set to LSA %s", __func__,
-                          inet_ntoa(lsa->data->id));
+               zlog_debug("%s: MAXAGE set to LSA %pI4", __func__,
+                          &lsa->data->id);
        monotime(&lsa->tv_recv);
        lsa->tv_orig = lsa->tv_recv;
        ospf_flood_through_area(area, NULL, lsa);
diff --git a/ospfd/ospf_gr_helper.c b/ospfd/ospf_gr_helper.c
new file mode 100644 (file)
index 0000000..9c029a4
--- /dev/null
@@ -0,0 +1,1079 @@
+/*
+ * OSPF Graceful Restart helper functions.
+ *
+ * Copyright (C) 2020-21 Vmware, Inc.
+ * Rajesh Kumar Girada
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <zebra.h>
+
+#include "thread.h"
+#include "memory.h"
+#include "linklist.h"
+#include "prefix.h"
+#include "if.h"
+#include "table.h"
+#include "vty.h"
+#include "filter.h"
+#include "log.h"
+#include "jhash.h"
+
+#include "ospfd/ospfd.h"
+#include "ospfd/ospf_interface.h"
+#include "ospfd/ospf_asbr.h"
+#include "ospfd/ospf_lsa.h"
+#include "ospfd/ospf_lsdb.h"
+#include "ospfd/ospf_neighbor.h"
+#include "ospfd/ospf_spf.h"
+#include "ospfd/ospf_flood.h"
+#include "ospfd/ospf_route.h"
+#include "ospfd/ospf_zebra.h"
+#include "ospfd/ospf_dump.h"
+#include "ospfd/ospf_errors.h"
+#include "ospfd/ospf_nsm.h"
+#include "ospfd/ospf_ism.h"
+#include "ospfd/ospf_gr_helper.h"
+
+static const char * const ospf_exit_reason_desc[] = {
+       "Unknown reason",
+       "Helper inprogress",
+       "Topology Change",
+       "Grace timer expiry",
+       "Successful graceful restart",
+};
+
+static const char * const ospf_restart_reason_desc[] = {
+       "Unknown restart",
+       "Software restart",
+       "Software reload/upgrade",
+       "Switch to redundant control processor",
+};
+
+static const char * const ospf_rejected_reason_desc[] = {
+       "Unknown reason",
+       "Helper support disabled",
+       "Neighbour is not in FULL state",
+       "Supports only planned restart but received unplanned",
+       "Topo change due to change in lsa rxmt list",
+       "LSA age is more than Grace interval",
+};
+
+static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa);
+static bool ospf_check_change_in_rxmt_list(struct ospf_neighbor *nbr);
+
+static unsigned int ospf_enable_rtr_hash_key(const void *data)
+{
+       const struct advRtr *rtr = data;
+
+       return jhash_1word(rtr->advRtrAddr.s_addr, 0);
+}
+
+static bool ospf_enable_rtr_hash_cmp(const void *d1, const void *d2)
+{
+       const struct advRtr *rtr1 = (struct advRtr *)d1;
+       const struct advRtr *rtr2 = (struct advRtr *)d2;
+
+       return (rtr1->advRtrAddr.s_addr == rtr2->advRtrAddr.s_addr);
+}
+
+static void *ospf_enable_rtr_hash_alloc(void *p)
+{
+       struct advRtr *rid;
+
+       rid = XCALLOC(MTYPE_OSPF_GR_HELPER, sizeof(struct advRtr));
+       rid->advRtrAddr.s_addr = ((struct in_addr *)p)->s_addr;
+
+       return rid;
+}
+
+static void ospf_disable_rtr_hash_free(void *rtr)
+{
+       XFREE(MTYPE_OSPF_GR_HELPER, rtr);
+}
+
+static void ospf_enable_rtr_hash_destroy(struct ospf *ospf)
+{
+       if (ospf->enable_rtr_list == NULL)
+               return;
+
+       hash_clean(ospf->enable_rtr_list, ospf_disable_rtr_hash_free);
+       hash_free(ospf->enable_rtr_list);
+       ospf->enable_rtr_list = NULL;
+}
+
+/*
+ * GR exit reason strings
+ */
+const char *ospf_exit_reason2str(unsigned int reason)
+{
+       if (reason < array_size(ospf_exit_reason_desc))
+               return(ospf_exit_reason_desc[reason]);
+       else
+               return "Invalid reason";
+}
+
+/*
+ * GR restart reason strings
+ */
+const char *ospf_restart_reason2str(unsigned int reason)
+{
+       if (reason < array_size(ospf_restart_reason_desc))
+               return(ospf_restart_reason_desc[reason]);
+       else
+               return "Invalid reason";
+}
+
+/*
+ * GR rejected reason strings
+ */
+const char *ospf_rejected_reason2str(unsigned int reason)
+{
+       if (reason < array_size(ospf_rejected_reason_desc))
+               return(ospf_rejected_reason_desc[reason]);
+       else
+               return "Invalid reason";
+}
+
+/*
+ * Initialize GR helper config data structures.
+ *
+ * OSPF
+ *    OSPF pointer
+ *
+ * Returns:
+ *    Nothing
+ */
+void ospf_gr_helper_init(struct ospf *ospf)
+{
+       int rc;
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug("%s, GR Helper init.", __PRETTY_FUNCTION__);
+
+       ospf->is_helper_supported = OSPF_GR_FALSE;
+       ospf->strict_lsa_check = OSPF_GR_TRUE;
+       ospf->only_planned_restart = OSPF_GR_FALSE;
+       ospf->supported_grace_time = OSPF_MAX_GRACE_INTERVAL;
+       ospf->last_exit_reason = OSPF_GR_HELPER_EXIT_NONE;
+       ospf->active_restarter_cnt = 0;
+
+       ospf->enable_rtr_list =
+               hash_create(ospf_enable_rtr_hash_key, ospf_enable_rtr_hash_cmp,
+                           "OSPF enable router hash");
+
+       rc = ospf_register_opaque_functab(
+               OSPF_OPAQUE_LINK_LSA, OPAQUE_TYPE_GRACE_LSA, NULL, NULL, NULL,
+               NULL, NULL, NULL, NULL, show_ospf_grace_lsa_info, NULL, NULL,
+               NULL, NULL);
+       if (rc != 0) {
+               flog_warn(EC_OSPF_OPAQUE_REGISTRATION,
+                         "%s: Failed to register Grace LSA functions",
+                               __func__);
+       }
+}
+
+/*
+ * De-Initialize GR helper config data structures.
+ *
+ * OSPF
+ *    OSPF pointer
+ *
+ * Returns:
+ *    Nothing
+ */
+void ospf_gr_helper_stop(struct ospf *ospf)
+{
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug("%s, GR helper deinit.", __PRETTY_FUNCTION__);
+
+       ospf_enable_rtr_hash_destroy(ospf);
+
+       ospf_delete_opaque_functab(OSPF_OPAQUE_LINK_LSA, OPAQUE_TYPE_GRACE_LSA);
+}
+
+/*
+ * Extracting tlv info from GRACE LSA.
+ *
+ * lsa
+ *   ospf grace lsa
+ *
+ * Returns:
+ * interval : grace interval.
+ * addr     : RESTARTER address.
+ * reason   : Restarting reason.
+ */
+static int ospf_extract_grace_lsa_fields(struct ospf_lsa *lsa,
+                                        uint32_t *interval,
+                                        struct in_addr *addr, uint8_t *reason)
+{
+       struct lsa_header *lsah = NULL;
+       struct tlv_header *tlvh = NULL;
+       struct grace_tlv_graceperiod *grace_period;
+       struct grace_tlv_restart_reason *gr_reason;
+       struct grace_tlv_restart_addr *restart_addr;
+       uint16_t length = 0;
+       int sum = 0;
+
+       lsah = (struct lsa_header *)lsa->data;
+
+       length = ntohs(lsah->length);
+
+       /* Check LSA len */
+       if (length <= OSPF_LSA_HEADER_SIZE) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug("%s: Malformed packet: Invalid LSA len:%d",
+                                  __func__, length);
+               return OSPF_GR_FAILURE;
+       }
+
+       length -= OSPF_LSA_HEADER_SIZE;
+
+       for (tlvh = TLV_HDR_TOP(lsah); sum < length;
+            tlvh = TLV_HDR_NEXT(tlvh)) {
+
+               /* Check TLV len against overall LSA */
+               if (sum + TLV_SIZE(tlvh) > length) {
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug("%s: Malformed packet: Invalid TLV len:%zu",
+                                          __func__, TLV_SIZE(tlvh));
+                       return OSPF_GR_FAILURE;
+               }
+
+               switch (ntohs(tlvh->type)) {
+               case GRACE_PERIOD_TYPE:
+                       if (TLV_SIZE(tlvh) <
+                           sizeof(struct grace_tlv_graceperiod)) {
+                               zlog_debug("%s: Malformed packet: Invalid grace TLV len:%zu",
+                                          __func__, TLV_SIZE(tlvh));
+                               return OSPF_GR_FAILURE;
+                       }
+
+                       grace_period = (struct grace_tlv_graceperiod *)tlvh;
+                       *interval = ntohl(grace_period->interval);
+                       sum += TLV_SIZE(tlvh);
+
+                       /* Check if grace interval is valid */
+                       if (*interval > OSPF_MAX_GRACE_INTERVAL
+                           || *interval < OSPF_MIN_GRACE_INTERVAL)
+                               return OSPF_GR_FAILURE;
+                       break;
+               case RESTART_REASON_TYPE:
+                       if (TLV_SIZE(tlvh) <
+                           sizeof(struct grace_tlv_restart_reason)) {
+                               zlog_debug("%s: Malformed packet: Invalid reason TLV len:%zu",
+                                          __func__, TLV_SIZE(tlvh));
+                               return OSPF_GR_FAILURE;
+                       }
+
+                       gr_reason = (struct grace_tlv_restart_reason *)tlvh;
+                       *reason = gr_reason->reason;
+                       sum += TLV_SIZE(tlvh);
+
+                       if (*reason >= OSPF_GR_INVALID_REASON_CODE)
+                               return OSPF_GR_FAILURE;
+                       break;
+               case RESTARTER_IP_ADDR_TYPE:
+                       if (TLV_SIZE(tlvh) <
+                           sizeof(struct grace_tlv_restart_addr)) {
+                               zlog_debug("%s: Malformed packet: Invalid addr TLV len:%zu",
+                                          __func__, TLV_SIZE(tlvh));
+                               return OSPF_GR_FAILURE;
+                       }
+
+                       restart_addr = (struct grace_tlv_restart_addr *)tlvh;
+                       addr->s_addr = restart_addr->addr.s_addr;
+                       sum += TLV_SIZE(tlvh);
+                       break;
+               default:
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug(
+                                       "%s, Malformed packet.Invalid TLV type:%d",
+                                       __PRETTY_FUNCTION__, ntohs(tlvh->type));
+                       return OSPF_GR_FAILURE;
+               }
+       }
+
+       return OSPF_GR_SUCCESS;
+}
+
+/*
+ * Grace timer expiry handler.
+ * HELPER aborts its role at grace timer expiry.
+ *
+ * thread
+ *    thread pointer
+ *
+ * Returns:
+ *    Nothing
+ */
+static int ospf_handle_grace_timer_expiry(struct thread *thread)
+{
+       struct ospf_neighbor *nbr = THREAD_ARG(thread);
+
+       nbr->gr_helper_info.t_grace_timer = NULL;
+
+       ospf_gr_helper_exit(nbr, OSPF_GR_HELPER_GRACE_TIMEOUT);
+       return OSPF_GR_SUCCESS;
+}
+
+/*
+ * Process Grace LSA.If it is eligible move to HELPER role.
+ * Ref rfc3623 section 3.1
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * lsa
+ *    Grace LSA received from RESTARTER.
+ *
+ * nbr
+ *    ospf neighbour which requets the router to act as
+ *    HELPER.
+ *
+ * Returns:
+ *    status.
+ *    If supported as HELPER : OSPF_GR_HELPER_INPROGRESS
+ *    If Not supported as HELPER : OSPF_GR_HELPER_NONE
+ */
+int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
+                          struct ospf_neighbor *nbr)
+{
+       struct in_addr restart_addr = {0};
+       uint8_t restart_reason = 0;
+       uint32_t grace_interval = 0;
+       uint32_t actual_grace_interval = 0;
+       struct advRtr lookup;
+       struct ospf_neighbor *restarter = NULL;
+       struct ospf_interface *oi = nbr->oi;
+       int ret;
+
+
+       /* Extract the grace lsa packet fields */
+       ret = ospf_extract_grace_lsa_fields(lsa, &grace_interval, &restart_addr,
+                                           &restart_reason);
+       if (ret != OSPF_GR_SUCCESS) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug("%s, Wrong Grace LSA packet.",
+                                  __PRETTY_FUNCTION__);
+               return OSPF_GR_NOT_HELPER;
+       }
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug(
+                       "%s, Grace LSA received from %pI4, grace interval:%u, restartreason :%s",
+                       __PRETTY_FUNCTION__, &restart_addr,
+                       grace_interval,
+                       ospf_restart_reason2str(restart_reason));
+
+       /* Incase of broadcast links, if RESTARTER is DR_OTHER,
+        * grace LSA might be received from DR, so need to get
+        * actual neighbour info , here RESTARTER.
+        */
+       if (oi->type != OSPF_IFTYPE_POINTOPOINT) {
+               restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restart_addr);
+
+               if (!restarter) {
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug(
+                                       "%s, Restarter is not a nbr(%pI4) for this router.",
+                                       __PRETTY_FUNCTION__,
+                                       &restart_addr);
+                       return OSPF_GR_NOT_HELPER;
+               }
+       } else
+               restarter = nbr;
+
+       /* Verify Helper enabled globally */
+       if (!ospf->is_helper_supported) {
+               /* Verify that Helper support is enabled for the
+                * current neighbour router-id.
+                */
+               lookup.advRtrAddr.s_addr = restarter->router_id.s_addr;
+
+               if (!hash_lookup(ospf->enable_rtr_list, &lookup)) {
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug(
+                                       "%s, HELPER support is disabled, So not a HELPER",
+                                       __PRETTY_FUNCTION__);
+                       restarter->gr_helper_info.rejected_reason =
+                               OSPF_HELPER_SUPPORT_DISABLED;
+                       return OSPF_GR_NOT_HELPER;
+               }
+       }
+
+
+       /* Check neighbour is in FULL state and
+        * became a adjacency.
+        */
+       if (!IS_NBR_STATE_FULL(restarter)) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, This Neighbour %pI4 is not in FULL state.",
+                               __PRETTY_FUNCTION__, &restarter->src);
+               restarter->gr_helper_info.rejected_reason =
+                       OSPF_HELPER_NOT_A_VALID_NEIGHBOUR;
+               return OSPF_GR_NOT_HELPER;
+       }
+
+       /* Based on the restart reason from grace lsa
+        * check the current router is supporting or not
+        */
+       if (ospf->only_planned_restart
+           && !OSPF_GR_IS_PLANNED_RESTART(restart_reason)) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, Router supports only planned restarts but received the GRACE LSA for an unplanned restart.",
+                               __PRETTY_FUNCTION__);
+               restarter->gr_helper_info.rejected_reason =
+                       OSPF_HELPER_PLANNED_ONLY_RESTART;
+               return OSPF_GR_NOT_HELPER;
+       }
+
+       /* Check the retranmission list of this
+        * neighbour, check any change in lsas.
+        */
+       if (ospf->strict_lsa_check && !ospf_ls_retransmit_isempty(restarter)
+           && ospf_check_change_in_rxmt_list(restarter)) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, Changed LSA in Rxmt list. So not Helper.",
+                               __PRETTY_FUNCTION__);
+               restarter->gr_helper_info.rejected_reason =
+                       OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST;
+               return OSPF_GR_NOT_HELPER;
+       }
+
+       /*LSA age must be less than the grace period */
+       if (ntohs(lsa->data->ls_age) >= grace_interval) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, Grace LSA age(%d) is more than the graceinterval(%d)",
+                               __PRETTY_FUNCTION__, lsa->data->ls_age,
+                               grace_interval);
+               restarter->gr_helper_info.rejected_reason =
+                       OSPF_HELPER_LSA_AGE_MORE;
+               return OSPF_GR_NOT_HELPER;
+       }
+
+       /* check supported grace period configured
+        * if configured, use this to start the grace
+        * timer otherwise use the interval received
+        * in grace LSA packet.
+        */
+       actual_grace_interval = grace_interval;
+       if (grace_interval > ospf->supported_grace_time) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, Received grace period %d is larger than supported grace %d",
+                               __PRETTY_FUNCTION__, grace_interval,
+                               ospf->supported_grace_time);
+               actual_grace_interval = ospf->supported_grace_time;
+       }
+
+       if (OSPF_GR_IS_ACTIVE_HELPER(restarter)) {
+               if (restarter->gr_helper_info.t_grace_timer)
+                       THREAD_OFF(restarter->gr_helper_info.t_grace_timer);
+
+               if (ospf->active_restarter_cnt > 0)
+                       ospf->active_restarter_cnt--;
+
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, Router is already acting as a HELPER for this nbr,so restart the grace timer",
+                               __PRETTY_FUNCTION__);
+       } else {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, This Router becomes a HELPER for the neighbour %pI4",
+                               __PRETTY_FUNCTION__, &restarter->src);
+       }
+
+       /* Became a Helper to the RESTART neighbour.
+        * Change the helper status.
+        */
+       restarter->gr_helper_info.gr_helper_status = OSPF_GR_ACTIVE_HELPER;
+       restarter->gr_helper_info.recvd_grace_period = grace_interval;
+       restarter->gr_helper_info.actual_grace_period = actual_grace_interval;
+       restarter->gr_helper_info.gr_restart_reason = restart_reason;
+       restarter->gr_helper_info.rejected_reason = OSPF_HELPER_REJECTED_NONE;
+
+       /* Incremnet the active restarer count */
+       ospf->active_restarter_cnt++;
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug("%s, Grace timer started.interval:%d",
+                          __PRETTY_FUNCTION__, actual_grace_interval);
+
+       /* Start the grace timer */
+       thread_add_timer(master, ospf_handle_grace_timer_expiry, restarter,
+                        actual_grace_interval,
+                        &restarter->gr_helper_info.t_grace_timer);
+
+       return OSPF_GR_ACTIVE_HELPER;
+}
+
+/*
+ * API to check any change in the neighbor's
+ * retransmission list.
+ *
+ * nbr
+ *    ospf neighbor
+ *
+ * Returns:
+ *    TRUE  - if any change in the lsa.
+ *    FALSE - no change in the lsas.
+ */
+static bool ospf_check_change_in_rxmt_list(struct ospf_neighbor *nbr)
+{
+       struct route_node *rn;
+       struct ospf_lsa *lsa;
+       struct route_table *tbl;
+
+       tbl = nbr->ls_rxmt.type[OSPF_ROUTER_LSA].db;
+       LSDB_LOOP (tbl, rn, lsa)
+               if (lsa->to_be_acknowledged)
+                       return OSPF_GR_TRUE;
+       tbl = nbr->ls_rxmt.type[OSPF_NETWORK_LSA].db;
+       LSDB_LOOP (tbl, rn, lsa)
+               if (lsa->to_be_acknowledged)
+                       return OSPF_GR_TRUE;
+
+       tbl = nbr->ls_rxmt.type[OSPF_SUMMARY_LSA].db;
+       LSDB_LOOP (tbl, rn, lsa)
+               if (lsa->to_be_acknowledged)
+                       return OSPF_GR_TRUE;
+
+       tbl = nbr->ls_rxmt.type[OSPF_ASBR_SUMMARY_LSA].db;
+       LSDB_LOOP (tbl, rn, lsa)
+               if (lsa->to_be_acknowledged)
+                       return OSPF_GR_TRUE;
+
+       tbl = nbr->ls_rxmt.type[OSPF_AS_EXTERNAL_LSA].db;
+       LSDB_LOOP (tbl, rn, lsa)
+               if (lsa->to_be_acknowledged)
+                       return OSPF_GR_TRUE;
+
+       tbl = nbr->ls_rxmt.type[OSPF_AS_NSSA_LSA].db;
+       LSDB_LOOP (tbl, rn, lsa)
+               if (lsa->to_be_acknowledged)
+                       return OSPF_GR_TRUE;
+
+       return OSPF_GR_FALSE;
+}
+
+/*
+ * Actions to be taken  when topo change detected
+ * HELPER will exit upon topo change.
+ *
+ * ospf
+ *    ospf pointer
+ * lsa
+ *    topo change occured due to this lsa type (1 to 5 and 7)
+ *
+ * Returns:
+ *    Nothing
+ */
+void ospf_helper_handle_topo_chg(struct ospf *ospf, struct ospf_lsa *lsa)
+{
+       struct listnode *node;
+       struct ospf_interface *oi;
+
+       if (!ospf->active_restarter_cnt)
+               return;
+
+       /* Topo change not required to be handled if strict
+        * LSA check is disbaled for this router.
+        */
+       if (!ospf->strict_lsa_check)
+               return;
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug(
+                       "%s, Topo change detected due to lsa LSID:%pI4 type:%d",
+                       __PRETTY_FUNCTION__, &lsa->data->id,
+                       lsa->data->type);
+
+       lsa->to_be_acknowledged = OSPF_GR_TRUE;
+
+       for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+               struct route_node *rn = NULL;
+
+               if (ospf_interface_neighbor_count(oi) == 0)
+                       continue;
+
+               /* Ref rfc3623 section 3.2.3.b
+                * If change due to external LSA and if the area is
+                * stub, then it is not a topo change. Since Type-5
+                * lsas will not be flooded in stub area.
+                */
+               if ((oi->area->external_routing == OSPF_AREA_STUB)
+                   && (lsa->data->type == OSPF_AS_EXTERNAL_LSA)) {
+                       continue;
+               }
+
+               for (rn = route_top(oi->nbrs); rn; rn = route_next(rn)) {
+                       struct ospf_neighbor *nbr = NULL;
+
+                       if (!rn->info)
+                               continue;
+
+                       nbr = rn->info;
+
+                       if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                               ospf_gr_helper_exit(nbr,
+                                                   OSPF_GR_HELPER_TOPO_CHG);
+               }
+       }
+}
+
+/*
+ * Api to exit from HELPER role to take all actions
+ * required at exit.
+ * Ref rfc3623 section 3.2
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * nbr
+ *    OSPF neighbour for which it is acting as HELPER.
+ *
+ * reason
+ *    The reason for exiting from HELPER.
+ *
+ * Returns:
+ *    Nothing.
+ */
+void ospf_gr_helper_exit(struct ospf_neighbor *nbr,
+                        enum ospf_helper_exit_reason reason)
+{
+       struct ospf_interface *oi = nbr->oi;
+       struct ospf *ospf = oi->ospf;
+
+       if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
+               return;
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s",
+                          __PRETTY_FUNCTION__, &nbr->src,
+                          ospf_exit_reason2str(reason));
+
+       /* Reset helper status*/
+       nbr->gr_helper_info.gr_helper_status = OSPF_GR_NOT_HELPER;
+       nbr->gr_helper_info.helper_exit_reason = reason;
+       nbr->gr_helper_info.actual_grace_period = 0;
+       nbr->gr_helper_info.recvd_grace_period = 0;
+       nbr->gr_helper_info.gr_restart_reason = 0;
+       ospf->last_exit_reason = reason;
+
+       if (ospf->active_restarter_cnt <= 0) {
+               zlog_err(
+                       "OSPF GR-Helper: active_restarter_cnt should be greater than zero here.");
+               return;
+       }
+       /* Decrement active Restarter count */
+       ospf->active_restarter_cnt--;
+
+       /* If the exit not triggered due to grace timer
+        * expairy , stop the grace timer.
+        */
+       if (reason != OSPF_GR_HELPER_GRACE_TIMEOUT)
+               THREAD_OFF(nbr->gr_helper_info.t_grace_timer);
+
+       /* check exit triggered due to successful completion
+        * of graceful restart.
+        * If no, bringdown the neighbour.
+        */
+       if (reason != OSPF_GR_HELPER_COMPLETED) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug(
+                               "%s, Failed GR exit, so bringing down the neighbour",
+                               __PRETTY_FUNCTION__);
+               OSPF_NSM_EVENT_EXECUTE(nbr, NSM_KillNbr);
+       }
+
+       /*Recalculate the DR for the network segment */
+       ospf_dr_election(oi);
+
+       /* Originate a router LSA */
+       ospf_router_lsa_update_area(oi->area);
+
+       /* Originate network lsa if it is an DR in the LAN */
+       if (oi->state == ISM_DR)
+               ospf_network_lsa_update(oi);
+}
+
+/*
+ * Process Maxage Grace LSA.
+ * It is a indication for successful completion of GR.
+ * If router acting as HELPER, It exits from helper role.
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * lsa
+ *    Grace LSA received from RESTARTER.
+ *
+ * nbr
+ *    ospf neighbour which requets the router to act as
+ *    HELPER.
+ *
+ * Returns:
+ *    Nothing.
+ */
+void ospf_process_maxage_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
+                                  struct ospf_neighbor *nbr)
+{
+       struct in_addr restartAddr = {0};
+       uint8_t restartReason = 0;
+       uint32_t graceInterval = 0;
+       struct ospf_neighbor *restarter = NULL;
+       struct ospf_interface *oi = nbr->oi;
+       int ret;
+
+       /* Extract the grace lsa packet fields */
+       ret = ospf_extract_grace_lsa_fields(lsa, &graceInterval, &restartAddr,
+                                           &restartReason);
+       if (ret != OSPF_GR_SUCCESS) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug("%s, Wrong Grace LSA packet.",
+                                  __PRETTY_FUNCTION__);
+               return;
+       }
+
+       if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug("%s, GraceLSA received for neighbour %pI4",
+                          __PRETTY_FUNCTION__, &restartAddr);
+
+       /* In case of broadcast links, if RESTARTER is DR_OTHER,
+        * grace LSA might be received from DR, so fetching the
+        * actual neighbour information using restarter address.
+        */
+       if (oi->type != OSPF_IFTYPE_POINTOPOINT) {
+               restarter = ospf_nbr_lookup_by_addr(oi->nbrs, &restartAddr);
+
+               if (!restarter) {
+                       if (IS_DEBUG_OSPF_GR_HELPER)
+                               zlog_debug(
+                                       "%s, Restarter is not a neighbour for this router.",
+                                       __PRETTY_FUNCTION__);
+                       return;
+               }
+       } else {
+               restarter = nbr;
+       }
+
+       ospf_gr_helper_exit(restarter, OSPF_GR_HELPER_COMPLETED);
+}
+
+/* Configuration handlers */
+/*
+ * Disable/Enable HELPER support on router level.
+ *
+ * ospf
+ *    OSPFpointer.
+ *
+ * status
+ *    TRUE/FALSE
+ *
+ * Returns:
+ *    Nothing.
+ */
+void ospf_gr_helper_support_set(struct ospf *ospf, bool support)
+{
+       struct ospf_interface *oi;
+       struct listnode *node;
+       struct advRtr lookup;
+
+       if (ospf->is_helper_supported == support)
+               return;
+
+       ospf->is_helper_supported = support;
+
+       /* If helper support disabled, cease HELPER role for all
+        * supporting neighbors.
+        */
+       if (support == OSPF_GR_FALSE) {
+               for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+                       struct route_node *rn = NULL;
+
+                       if (ospf_interface_neighbor_count(oi) == 0)
+                               continue;
+
+                       for (rn = route_top(oi->nbrs); rn;
+                            rn = route_next(rn)) {
+                               struct ospf_neighbor *nbr = NULL;
+
+                               if (!rn->info)
+                                       continue;
+
+                               nbr = rn->info;
+
+                               lookup.advRtrAddr.s_addr =
+                                       nbr->router_id.s_addr;
+                               /* check if helper support enabled for the
+                                * correspodning routerid.If enabled, dont
+                                * dont exit from helper role.
+                                */
+                               if (hash_lookup(ospf->enable_rtr_list, &lookup))
+                                       continue;
+
+                               if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                                       ospf_gr_helper_exit(
+                                               nbr, OSPF_GR_HELPER_TOPO_CHG);
+                       }
+               }
+       }
+}
+
+/*
+ * Enable/Disable HELPER support on a specified advertagement
+ * router.
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * advRtr
+ *    HELPER support for given Advertisement Router.
+ *
+ * support
+ *    True - Enable Helper Support.
+ *    False - Disable Helper Support.
+ *
+ * Returns:
+ *    Nothing.
+ */
+
+void ospf_gr_helper_support_set_per_routerid(struct ospf *ospf,
+                                            struct in_addr *advrtr,
+                                            bool support)
+{
+       struct advRtr temp;
+       struct advRtr *rtr;
+       struct ospf_interface *oi;
+       struct listnode *node;
+
+       temp.advRtrAddr.s_addr = advrtr->s_addr;
+
+       if (support == OSPF_GR_FALSE) {
+               /*Delete the routerid from the enable router hash table */
+               rtr = hash_lookup(ospf->enable_rtr_list, &temp);
+
+               if (rtr) {
+                       hash_release(ospf->enable_rtr_list, rtr);
+                       ospf_disable_rtr_hash_free(rtr);
+               }
+
+               /* If helper support is enabled globally
+                * no action is required.
+                */
+               if (ospf->is_helper_supported)
+                       return;
+
+               /* Cease the HELPER role fore neighbours from the
+                * specified advertisement router.
+                */
+               for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+                       struct route_node *rn = NULL;
+
+                       if (ospf_interface_neighbor_count(oi) == 0)
+                               continue;
+
+                       for (rn = route_top(oi->nbrs); rn;
+                            rn = route_next(rn)) {
+                               struct ospf_neighbor *nbr = NULL;
+
+                               if (!rn->info)
+                                       continue;
+
+                               nbr = rn->info;
+
+                               if (nbr->router_id.s_addr != advrtr->s_addr)
+                                       continue;
+
+                               if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                                       ospf_gr_helper_exit(
+                                               nbr, OSPF_GR_HELPER_TOPO_CHG);
+                       }
+               }
+
+       } else {
+               /* Add the routerid to the enable router hash table */
+               hash_get(ospf->enable_rtr_list, &temp,
+                        ospf_enable_rtr_hash_alloc);
+       }
+}
+
+/*
+ * Api to enable/disable strict lsa check on the HELPER.
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * enabled
+ *    True - disable the lsa check.
+ *    False - enable the strict lsa check.
+ *
+ * Returns:
+ *    Nothing.
+ */
+void ospf_gr_helper_lsa_check_set(struct ospf *ospf, bool enabled)
+{
+       if (ospf->strict_lsa_check == enabled)
+               return;
+
+       ospf->strict_lsa_check = enabled;
+}
+
+/*
+ * Api to set the supported grace interval in this router.
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * interval
+ *    The supported grace interval..
+ *
+ * Returns:
+ *    Nothing.
+ */
+void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf,
+                                           uint32_t interval)
+{
+       ospf->supported_grace_time = interval;
+}
+
+/*
+ * Api to set the supported restart reason.
+ *
+ * ospf
+ *    OSPF pointer.
+ *
+ * planned_only
+ *    True: support only planned restart.
+ *    False: support for planned/unplanned restarts.
+ *
+ * Returns:
+ *    Nothing.
+ */
+void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
+                                                     bool planned_only)
+{
+       ospf->only_planned_restart = planned_only;
+}
+
+/*
+ * Api to display the grace LSA information.
+ *
+ * vty
+ *    vty pointer.
+ * lsa
+ *    Grace LSA.
+ * json
+ *    json object
+ *
+ * Returns:
+ *    Nothing.
+ */
+static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa)
+{
+       struct lsa_header *lsah = NULL;
+       struct tlv_header *tlvh = NULL;
+       struct grace_tlv_graceperiod *gracePeriod;
+       struct grace_tlv_restart_reason *grReason;
+       struct grace_tlv_restart_addr *restartAddr;
+       uint16_t length = 0;
+       int sum = 0;
+
+       lsah = (struct lsa_header *)lsa->data;
+
+       length = ntohs(lsah->length);
+
+       if (length <= OSPF_LSA_HEADER_SIZE) {
+               vty_out(vty, "%% Invalid LSA length: %d\n", length);
+               return;
+       }
+
+       length -= OSPF_LSA_HEADER_SIZE;
+
+       vty_out(vty, "  TLV info:\n");
+
+       for (tlvh = TLV_HDR_TOP(lsah); sum < length;
+            tlvh = TLV_HDR_NEXT(tlvh)) {
+               /* Check TLV len */
+               if (sum + TLV_SIZE(tlvh) > length) {
+                       vty_out(vty, "%% Invalid TLV length: %zu\n",
+                               TLV_SIZE(tlvh));
+                       return;
+               }
+
+               switch (ntohs(tlvh->type)) {
+               case GRACE_PERIOD_TYPE:
+                       if (TLV_SIZE(tlvh) <
+                           sizeof(struct grace_tlv_graceperiod)) {
+                               vty_out(vty,
+                                       "%% Invalid grace TLV length %zu\n",
+                                       TLV_SIZE(tlvh));
+                               return;
+                       }
+
+                       gracePeriod = (struct grace_tlv_graceperiod *)tlvh;
+                       sum += TLV_SIZE(tlvh);
+
+                       vty_out(vty, "   Grace period:%d\n",
+                               ntohl(gracePeriod->interval));
+                       break;
+               case RESTART_REASON_TYPE:
+                       if (TLV_SIZE(tlvh) <
+                           sizeof(struct grace_tlv_restart_reason)) {
+                               vty_out(vty,
+                                       "%% Invalid reason TLV length %zu\n",
+                                       TLV_SIZE(tlvh));
+                               return;
+                       }
+
+                       grReason = (struct grace_tlv_restart_reason *)tlvh;
+                       sum += TLV_SIZE(tlvh);
+
+                       vty_out(vty, "   Restart reason:%s\n",
+                               ospf_restart_reason2str(grReason->reason));
+                       break;
+               case RESTARTER_IP_ADDR_TYPE:
+                       if (TLV_SIZE(tlvh) <
+                           sizeof(struct grace_tlv_restart_addr)) {
+                               vty_out(vty,
+                                       "%% Invalid addr TLV length %zu\n",
+                                       TLV_SIZE(tlvh));
+                               return;
+                       }
+
+                       restartAddr = (struct grace_tlv_restart_addr *)tlvh;
+                       sum += TLV_SIZE(tlvh);
+
+                       vty_out(vty, "   Restarter address:%pI4\n",
+                               &restartAddr->addr);
+                       break;
+               default:
+                       vty_out(vty, "   Unknown TLV type %d\n",
+                               ntohs(tlvh->type));
+
+                       break;
+               }
+       }
+}
diff --git a/ospfd/ospf_gr_helper.h b/ospfd/ospf_gr_helper.h
new file mode 100644 (file)
index 0000000..c355bb4
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * OSPF Graceful Restart helper functions.
+ *
+ * Copyright (C) 2020-21 Vmware, Inc.
+ * Rajesh Kumar Girada
+ *
+ * This file is part of GNU Zebra.
+ *
+ * GNU Zebra is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * GNU Zebra is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ZEBRA_OSPF_GR_HELPER_H
+#define _ZEBRA_OSPF_GR_HELPER_H
+
+#define OSPF_GR_NOT_HELPER 0
+#define OSPF_GR_ACTIVE_HELPER 1
+
+#define OSPF_GR_HELPER_NO_LSACHECK 0
+#define OSPF_GR_HELPER_LSACHECK 1
+
+#define OSPF_MAX_GRACE_INTERVAL 1800
+#define OSPF_MIN_GRACE_INTERVAL 1
+
+enum ospf_helper_exit_reason {
+       OSPF_GR_HELPER_EXIT_NONE = 0,
+       OSPF_GR_HELPER_INPROGRESS,
+       OSPF_GR_HELPER_TOPO_CHG,
+       OSPF_GR_HELPER_GRACE_TIMEOUT,
+       OSPF_GR_HELPER_COMPLETED
+};
+
+enum ospf_gr_restart_reason {
+       OSPF_GR_UNKNOWN_RESTART = 0,
+       OSPF_GR_SW_RESTART = 1,
+       OSPF_GR_SW_UPGRADE = 2,
+       OSPF_GR_SWITCH_REDUNDANT_CARD = 3,
+       OSPF_GR_INVALID_REASON_CODE = 4
+};
+
+enum ospf_gr_helper_rejected_reason {
+       OSPF_HELPER_REJECTED_NONE,
+       OSPF_HELPER_SUPPORT_DISABLED,
+       OSPF_HELPER_NOT_A_VALID_NEIGHBOUR,
+       OSPF_HELPER_PLANNED_ONLY_RESTART,
+       OSPF_HELPER_TOPO_CHANGE_RTXMT_LIST,
+       OSPF_HELPER_LSA_AGE_MORE
+};
+
+/* Ref RFC3623 appendex-A */
+/* Grace period TLV */
+#define GRACE_PERIOD_TYPE 1
+#define GRACE_PERIOD_LENGTH 4
+
+struct grace_tlv_graceperiod {
+       struct tlv_header header;
+       uint32_t interval;
+};
+
+/* Restart reason TLV */
+#define RESTART_REASON_TYPE 2
+#define RESTART_REASON_LENGTH 1
+
+struct grace_tlv_restart_reason {
+       struct tlv_header header;
+       uint8_t reason;
+       uint8_t reserved[3];
+};
+
+/* Restarter ip address TLV */
+#define RESTARTER_IP_ADDR_TYPE 3
+#define RESTARTER_IP_ADDR_LEN 4
+
+struct grace_tlv_restart_addr {
+       struct tlv_header header;
+       struct in_addr addr;
+};
+
+struct ospf_helper_info {
+
+       /* Grace interval received from
+        * Restarting Router.
+        */
+       uint32_t recvd_grace_period;
+
+       /* Grace interval used for grace
+        * gracetimer.
+        */
+       uint32_t actual_grace_period;
+
+       /* Grace timer,This Router acts as
+        * helper until this timer until
+        * this timer expires*/
+       struct thread *t_grace_timer;
+
+       /* Helper status */
+       uint32_t gr_helper_status;
+
+       /* Helper exit reason*/
+       enum ospf_helper_exit_reason helper_exit_reason;
+
+       /* Planned/Unplanned restart*/
+       enum ospf_gr_restart_reason  gr_restart_reason;
+
+       /* Helper rejected reason */
+       enum ospf_gr_helper_rejected_reason rejected_reason;
+};
+
+struct advRtr {
+       struct in_addr advRtrAddr;
+};
+
+#define OSPF_HELPER_ENABLE_RTR_COUNT(ospf) (ospf->enable_rtr_list->count)
+
+/* Check for planned restart */
+#define OSPF_GR_IS_PLANNED_RESTART(reason)                                     \
+       ((reason == OSPF_GR_SW_RESTART) || (reason == OSPF_GR_SW_UPGRADE))
+
+/* Check the router is HELPER for current neighbour */
+#define OSPF_GR_IS_ACTIVE_HELPER(N)                                                         \
+       ((N)->gr_helper_info.gr_helper_status == OSPF_GR_ACTIVE_HELPER)
+
+/* Check the LSA is GRACE LSA */
+#define IS_GRACE_LSA(lsa)                                                      \
+       ((lsa->data->type == OSPF_OPAQUE_LINK_LSA)                             \
+        && (GET_OPAQUE_TYPE(ntohl(lsa->data->id.s_addr))                      \
+            == OPAQUE_TYPE_GRACE_LSA))
+
+/* Check neighbour is in FULL state */
+#define IS_NBR_STATE_FULL(nbr) (nsm_should_adj(nbr) && (nbr->state == NSM_Full))
+
+/* Check neighbour is DR_OTHER and state is 2_WAY */
+#define IS_NBR_STATE_2_WAY_WITH_DROTHER(nbr)                                   \
+       ((ospf_get_nbr_ism_role(nbr) == ISM_DROther)                           \
+        && (nbr->state == NSM_TwoWay))
+
+#define OSPF_GR_FALSE false
+#define OSPF_GR_TRUE true
+
+#define OSPF_GR_SUCCESS 1
+#define OSPF_GR_FAILURE 0
+#define OSPF_GR_INVALID -1
+
+const char *ospf_exit_reason2str(unsigned int reason);
+const char *ospf_restart_reason2str(unsigned int reason);
+const char *ospf_rejected_reason2str(unsigned int reason);
+
+extern void ospf_gr_helper_init(struct ospf *ospf);
+extern void ospf_gr_helper_stop(struct ospf *ospf);
+extern int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
+                                 struct ospf_neighbor *nbr);
+extern void ospf_gr_helper_exit(struct ospf_neighbor *nbr,
+                               enum ospf_helper_exit_reason reason);
+extern void ospf_process_maxage_grace_lsa(struct ospf *ospf,
+                                         struct ospf_lsa *lsa,
+                                         struct ospf_neighbor *nbr);
+extern void ospf_helper_handle_topo_chg(struct ospf *ospf,
+                                       struct ospf_lsa *lsa);
+extern void ospf_gr_helper_support_set(struct ospf *ospf, bool support);
+extern void ospf_gr_helper_support_set_per_routerid(struct ospf *ospf,
+                                                   struct in_addr *rid,
+                                                   bool support);
+extern void ospf_gr_helper_lsa_check_set(struct ospf *ospf, bool lsacheck);
+extern void ospf_gr_helper_supported_gracetime_set(struct ospf *ospf,
+                                                  uint32_t interval);
+extern void ospf_gr_helper_set_supported_planned_only_restart(struct ospf *ospf,
+                                                            bool planned_only);
+#endif /* _ZEBRA_OSPF_HELPER_H */
index 87929e43698d7907444c04a1c516e09b2afa3151..f805899b81a07e1eb8e42fdbc314e0bcb253c7c4 100644 (file)
@@ -76,8 +76,8 @@ static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt,
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "ospf_ia_network_route(): processing summary route to %s/%d",
-                       inet_ntoa(p->prefix), p->prefixlen);
+                       "ospf_ia_network_route(): processing summary route to %pFX",
+                       p);
 
        /* Find a route to the same dest */
        if ((rn1 = route_node_lookup(rt, (struct prefix *)p))) {
@@ -113,8 +113,8 @@ static void ospf_ia_network_route(struct ospf *ospf, struct route_table *rt,
        else {    /* no route */
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_ia_network_route(): add new route to %s/%d",
-                               inet_ntoa(p->prefix), p->prefixlen);
+                               "ospf_ia_network_route(): add new route to %pFX",
+                               p);
                ospf_route_add(rt, p, new_or, abr_or);
        }
 }
@@ -129,8 +129,8 @@ static void ospf_ia_router_route(struct ospf *ospf, struct route_table *rtrs,
        int ret;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_ia_router_route(): considering %s/%d",
-                          inet_ntoa(p->prefix), p->prefixlen);
+               zlog_debug("ospf_ia_router_route(): considering %pFX", p);
+
        /* Find a route to the same dest */
        rn = route_node_get(rtrs, (struct prefix *)p);
 
@@ -202,8 +202,8 @@ static int process_summary_lsa(struct ospf_area *area, struct route_table *rt,
        sl = (struct summary_lsa *)lsa->data;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("process_summary_lsa(): LS ID: %s",
-                          inet_ntoa(sl->header.id));
+               zlog_debug("process_summary_lsa(): LS ID: %pI4",
+                          &sl->header.id);
 
        metric = GET_METRIC(sl->metric);
 
@@ -524,8 +524,8 @@ static int process_transit_summary_lsa(struct ospf_area *area,
        sl = (struct summary_lsa *)lsa->data;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("process_transit_summaries(): LS ID: %s",
-                          inet_ntoa(lsa->data->id));
+               zlog_debug("process_transit_summaries(): LS ID: %pI4",
+                          &lsa->data->id);
        metric = GET_METRIC(sl->metric);
 
        if (metric == OSPF_LS_INFINITY) {
index 6bfdb1e9e0c019f6b54caef7d27db02f52f7e32a..e461345fe5400b29388e2ab4b7faf2437fd435fc 100644 (file)
@@ -535,6 +535,7 @@ static struct ospf_if_params *ospf_new_if_params(void)
        UNSET_IF_PARAM(oip, auth_simple);
        UNSET_IF_PARAM(oip, auth_crypt);
        UNSET_IF_PARAM(oip, auth_type);
+       UNSET_IF_PARAM(oip, if_area);
 
        oip->auth_crypt = list_new();
 
@@ -579,8 +580,8 @@ void ospf_free_if_params(struct interface *ifp, struct in_addr addr)
            && !OSPF_IF_PARAM_CONFIGURED(oip, type)
            && !OSPF_IF_PARAM_CONFIGURED(oip, auth_simple)
            && !OSPF_IF_PARAM_CONFIGURED(oip, auth_type)
-           && listcount(oip->auth_crypt) == 0
-           && ntohl(oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER) {
+           && !OSPF_IF_PARAM_CONFIGURED(oip, if_area)
+           && listcount(oip->auth_crypt) == 0) {
                ospf_del_if_params(oip);
                rn->info = NULL;
                route_unlock_node(rn);
@@ -796,9 +797,36 @@ int ospf_if_up(struct ospf_interface *oi)
 
 int ospf_if_down(struct ospf_interface *oi)
 {
+       struct ospf *ospf;
+
        if (oi == NULL)
                return 0;
 
+       ospf = oi->ospf;
+
+       /* Cease the HELPER role for all the neighbours
+        * of this interface.
+        */
+       if (ospf->is_helper_supported) {
+               struct route_node *rn = NULL;
+
+               if (ospf_interface_neighbor_count(oi)) {
+                       for (rn = route_top(oi->nbrs); rn;
+                            rn = route_next(rn)) {
+                               struct ospf_neighbor *nbr = NULL;
+
+                               if (!rn->info)
+                                       continue;
+
+                               nbr = rn->info;
+
+                               if (OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                                       ospf_gr_helper_exit(
+                                               nbr, OSPF_GR_HELPER_TOPO_CHG);
+                       }
+               }
+       }
+
        OSPF_ISM_EVENT_EXECUTE(oi, ISM_InterfaceDown);
        /* delete position in router LSA */
        oi->lsa_pos_beg = 0;
@@ -950,17 +978,17 @@ struct ospf_vl_data *ospf_vl_lookup(struct ospf *ospf, struct ospf_area *area,
        struct listnode *node;
 
        if (IS_DEBUG_OSPF_EVENT) {
-               zlog_debug("%s: Looking for %s", __func__, inet_ntoa(vl_peer));
+               zlog_debug("%s: Looking for %pI4", __func__, &vl_peer);
                if (area)
-                       zlog_debug("%s: in area %s", __func__,
-                                  inet_ntoa(area->area_id));
+                       zlog_debug("%s: in area %pI4", __func__,
+                                  &area->area_id);
        }
 
        for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("%s: VL %s, peer %s", __func__,
+                       zlog_debug("%s: VL %s, peer %pI4", __func__,
                                   vl_data->vl_oi->ifp->name,
-                                  inet_ntoa(vl_data->vl_peer));
+                                  &vl_data->vl_peer);
 
                if (area
                    && !IPV4_ADDR_SAME(&vl_data->vl_area_id, &area->area_id))
@@ -1082,9 +1110,9 @@ static int ospf_vl_set_params(struct ospf_area *area,
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("%s: %s peer address: %s, cost: %d,%schanged",
+               zlog_debug("%s: %s peer address: %pI4, cost: %d,%schanged",
                           __func__, vl_data->vl_oi->ifp->name,
-                          inet_ntoa(vl_data->peer_addr), voi->output_cost,
+                          &vl_data->peer_addr, voi->output_cost,
                           (changed ? " " : " un"));
 
        return changed;
@@ -1101,19 +1129,19 @@ void ospf_vl_up_check(struct ospf_area *area, struct in_addr rid,
 
        if (IS_DEBUG_OSPF_EVENT) {
                zlog_debug("ospf_vl_up_check(): Start");
-               zlog_debug("ospf_vl_up_check(): Router ID is %s",
-                          inet_ntoa(rid));
-               zlog_debug("ospf_vl_up_check(): Area is %s",
-                          inet_ntoa(area->area_id));
+               zlog_debug("ospf_vl_up_check(): Router ID is %pI4",
+                          &rid);
+               zlog_debug("ospf_vl_up_check(): Area is %pI4",
+                          &area->area_id);
        }
 
        for (ALL_LIST_ELEMENTS_RO(ospf->vlinks, node, vl_data)) {
                if (IS_DEBUG_OSPF_EVENT) {
-                       zlog_debug("%s: considering VL, %s in area %s",
+                       zlog_debug("%s: considering VL, %s in area %pI4",
                                   __func__, vl_data->vl_oi->ifp->name,
-                                  inet_ntoa(vl_data->vl_area_id));
-                       zlog_debug("%s: peer ID: %s", __func__,
-                                  inet_ntoa(vl_data->vl_peer));
+                                  &vl_data->vl_area_id);
+                       zlog_debug("%s: peer ID: %pI4", __func__,
+                                  &vl_data->vl_peer);
                }
 
                if (IPV4_ADDR_SAME(&vl_data->vl_peer, &rid)
@@ -1171,8 +1199,8 @@ int ospf_full_virtual_nbrs(struct ospf_area *area)
 {
        if (IS_DEBUG_OSPF_EVENT) {
                zlog_debug(
-                       "counting fully adjacent virtual neighbors in area %s",
-                       inet_ntoa(area->area_id));
+                       "counting fully adjacent virtual neighbors in area %pI4",
+                       &area->area_id);
                zlog_debug("there are %d of them", area->full_vls);
        }
 
@@ -1249,6 +1277,9 @@ void ospf_if_interface(struct interface *ifp)
 static int ospf_ifp_create(struct interface *ifp)
 {
        struct ospf *ospf = NULL;
+       struct ospf_if_params *params;
+       struct route_node *rn;
+       uint32_t count = 0;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
                zlog_debug(
@@ -1270,6 +1301,19 @@ static int ospf_ifp_create(struct interface *ifp)
        if (!ospf)
                return 0;
 
+       params = IF_DEF_PARAMS(ifp);
+       if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+               count++;
+
+       for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
+               if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
+                       count++;
+
+       if (count > 0) {
+               ospf->if_ospf_cli_count += count;
+               ospf_interface_area_set(ospf, ifp);
+       }
+
        ospf_if_recalculate_output_cost(ifp);
 
        ospf_if_update(ospf, ifp);
@@ -1335,7 +1379,10 @@ static int ospf_ifp_down(struct interface *ifp)
 
 static int ospf_ifp_destroy(struct interface *ifp)
 {
+       struct ospf *ospf;
+       struct ospf_if_params *params;
        struct route_node *rn;
+       uint32_t count = 0;
 
        if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
                zlog_debug(
@@ -1346,6 +1393,22 @@ static int ospf_ifp_destroy(struct interface *ifp)
 
        hook_call(ospf_if_delete, ifp);
 
+       ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+       if (ospf) {
+               params = IF_DEF_PARAMS(ifp);
+               if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+                       count++;
+
+               for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
+                       if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
+                               count++;
+
+               if (count > 0) {
+                       ospf->if_ospf_cli_count -= count;
+                       ospf_interface_area_unset(ospf, ifp);
+               }
+       }
+
        for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next(rn))
                if (rn->info)
                        ospf_if_free((struct ospf_interface *)rn->info);
index 86712c61985d1344fa616cc0c68623c13661c01a..36e97f877906de225d4369006fa559c5886e0e4d 100644 (file)
@@ -201,7 +201,7 @@ static void ospf_dr_change(struct ospf *ospf, struct route_table *nbrs)
        }
 }
 
-static int ospf_dr_election(struct ospf_interface *oi)
+int ospf_dr_election(struct ospf_interface *oi)
 {
        struct in_addr old_dr, old_bdr;
        int old_state, new_state;
@@ -223,8 +223,8 @@ static int ospf_dr_election(struct ospf_interface *oi)
 
        new_state = ospf_ism_state(oi);
 
-       zlog_debug("DR-Election[1st]: Backup %s", inet_ntoa(BDR(oi)));
-       zlog_debug("DR-Election[1st]: DR     %s", inet_ntoa(DR(oi)));
+       zlog_debug("DR-Election[1st]: Backup %pI4", &BDR(oi));
+       zlog_debug("DR-Election[1st]: DR     %pI4", &DR(oi));
 
        if (new_state != old_state
            && !(new_state == ISM_DROther && old_state < ISM_DROther)) {
@@ -233,8 +233,8 @@ static int ospf_dr_election(struct ospf_interface *oi)
 
                new_state = ospf_ism_state(oi);
 
-               zlog_debug("DR-Election[2nd]: Backup %s", inet_ntoa(BDR(oi)));
-               zlog_debug("DR-Election[2nd]: DR     %s", inet_ntoa(DR(oi)));
+               zlog_debug("DR-Election[2nd]: Backup %pI4", &BDR(oi));
+               zlog_debug("DR-Election[2nd]: DR     %pI4", &DR(oi));
        }
 
        list_delete(&el_list);
index 8d21403695faf7a8657ca5bcd4f84bdbe7aa3328..c41ba6c843e6e7f5cf068f43f71c23d0ede14d12 100644 (file)
        } while (0)
 
 /* Macro for OSPF ISM timer turn off. */
-#define OSPF_ISM_TIMER_OFF(X)                                                  \
-       do {                                                                   \
-               if (X) {                                                       \
-                       thread_cancel(X);                                      \
-                       (X) = NULL;                                            \
-               }                                                              \
-       } while (0)
+#define OSPF_ISM_TIMER_OFF(X) thread_cancel(&(X))
 
 /* Macro for OSPF schedule event. */
 #define OSPF_ISM_EVENT_SCHEDULE(I, E)                                          \
@@ -99,6 +93,7 @@
 extern int ospf_ism_event(struct thread *);
 extern void ism_change_status(struct ospf_interface *, int);
 extern int ospf_hello_timer(struct thread *thread);
+extern int ospf_dr_election(struct ospf_interface *oi);
 
 DECLARE_HOOK(ospf_ism_change,
             (struct ospf_interface * oi, int state, int oldstate),
index cdb0eae2c40eb499a8d7a367c7a9e68bb6faa510..68792ebcc2e7a1ffddd41bce0f13e83737f2a63a 100644 (file)
@@ -99,8 +99,7 @@ int ospf_ldp_sync_announce_update(struct ldp_igp_sync_announce announce)
        FOR_ALL_INTERFACES (vrf, ifp)
                ospf_ldp_sync_if_start(ifp, true);
 
-       THREAD_TIMER_OFF(ospf->ldp_sync_cmd.t_hello);
-       ospf->ldp_sync_cmd.t_hello = NULL;
+       THREAD_OFF(ospf->ldp_sync_cmd.t_hello);
        ospf->ldp_sync_cmd.sequence = 0;
        ospf_ldp_sync_hello_timer_add(ospf);
 
@@ -140,7 +139,7 @@ int ospf_ldp_sync_hello_update(struct ldp_igp_sync_hello hello)
                FOR_ALL_INTERFACES (vrf, ifp)
                        ospf_ldp_sync_if_start(ifp, true);
        } else {
-               THREAD_TIMER_OFF(ospf->ldp_sync_cmd.t_hello);
+               THREAD_OFF(ospf->ldp_sync_cmd.t_hello);
                ospf_ldp_sync_hello_timer_add(ospf);
        }
        ospf->ldp_sync_cmd.sequence = hello.sequence;
@@ -249,8 +248,7 @@ void ospf_ldp_sync_if_complete(struct interface *ifp)
        if (ldp_sync_info && ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED) {
                if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP)
                        ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP;
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-               ldp_sync_info->t_holddown = NULL;
+               THREAD_OFF(ldp_sync_info->t_holddown);
                ospf_if_recalculate_output_cost(ifp);
        }
 }
@@ -274,10 +272,7 @@ void ospf_ldp_sync_ldp_fail(struct interface *ifp)
        if (ldp_sync_info &&
            ldp_sync_info->enabled == LDP_IGP_SYNC_ENABLED &&
            ldp_sync_info->state != LDP_IGP_SYNC_STATE_NOT_REQUIRED) {
-               if (ldp_sync_info->t_holddown != NULL) {
-                       THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-                       ldp_sync_info->t_holddown = NULL;
-               }
+               THREAD_OFF(ldp_sync_info->t_holddown);
                ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
                ospf_if_recalculate_output_cost(ifp);
        }
@@ -340,8 +335,9 @@ void ospf_ldp_sync_if_remove(struct interface *ifp, bool remove)
         *  restore cost
         */
        ols_debug("ldp_sync: Removed from if %s", ifp->name);
-       if (ldp_sync_info->t_holddown)
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+
+       THREAD_OFF(ldp_sync_info->t_holddown);
+
        ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
        ospf_if_recalculate_output_cost(ifp);
        if (!CHECK_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG))
@@ -390,7 +386,6 @@ static int ospf_ldp_sync_holddown_timer(struct thread *thread)
                ldp_sync_info = params->ldp_sync_info;
 
                ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_UP;
-               ldp_sync_info->t_holddown = NULL;
 
                ols_debug("ldp_sync: holddown timer expired for %s state: %s",
                          ifp->name, "Sync achieved");
@@ -440,7 +435,6 @@ static int ospf_ldp_sync_hello_timer(struct thread *thread)
         */
        ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
        if (ospf) {
-               ospf->ldp_sync_cmd.t_hello = NULL;
                vrf = vrf_lookup_by_id(ospf->vrf_id);
 
                FOR_ALL_INTERFACES (vrf, ifp)
@@ -490,8 +484,8 @@ void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove)
                UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE);
                UNSET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_HOLDDOWN);
                ospf->ldp_sync_cmd.holddown = LDP_IGP_SYNC_HOLDDOWN_DEFAULT;
-               THREAD_TIMER_OFF(ospf->ldp_sync_cmd.t_hello);
-               ospf->ldp_sync_cmd.t_hello = NULL;
+
+               THREAD_OFF(ospf->ldp_sync_cmd.t_hello);
 
                /* turn off LDP-IGP Sync on all OSPF interfaces */
                vrf = vrf_lookup_by_id(ospf->vrf_id);
@@ -984,8 +978,7 @@ DEFPY (no_mpls_ldp_sync,
        SET_FLAG(ldp_sync_info->flags, LDP_SYNC_FLAG_IF_CONFIG);
        ldp_sync_info->enabled = LDP_IGP_SYNC_DEFAULT;
        ldp_sync_info->state = LDP_IGP_SYNC_STATE_NOT_REQUIRED;
-       THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
-       ldp_sync_info->t_holddown = NULL;
+       THREAD_OFF(ldp_sync_info->t_holddown);
        ospf_if_recalculate_output_cost(ifp);
 
        return CMD_SUCCESS;
index 8095219146457679a4edeb46a2e12f01c0c69658..42fc3288cde21167a18495ab71c300ab723bd701 100644 (file)
@@ -98,8 +98,8 @@ int ospf_lsa_refresh_delay(struct ospf_lsa *lsa)
 
                if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                        zlog_debug(
-                               "LSA[Type%d:%s]: Refresh timer delay %d seconds",
-                               lsa->data->type, inet_ntoa(lsa->data->id),
+                               "LSA[Type%d:%pI4]: Refresh timer delay %d seconds",
+                               lsa->data->type, &lsa->data->id,
                                delay);
 
                assert(delay > 0);
@@ -164,6 +164,7 @@ struct ospf_lsa *ospf_lsa_new(void)
        new->tv_orig = new->tv_recv;
        new->refresh_list = -1;
        new->vrf_id = VRF_DEFAULT;
+       new->to_be_acknowledged = 0;
 
        return new;
 }
@@ -280,8 +281,8 @@ struct lsa_header *ospf_lsa_data_dup(struct lsa_header *lsah)
 void ospf_lsa_data_free(struct lsa_header *lsah)
 {
        if (IS_DEBUG_OSPF(lsa, LSA))
-               zlog_debug("LSA[Type%d:%s]: data freed %p", lsah->type,
-                          inet_ntoa(lsah->id), (void *)lsah);
+               zlog_debug("LSA[Type%d:%pI4]: data freed %p", lsah->type,
+                          &lsah->id, (void *)lsah);
 
        XFREE(MTYPE_OSPF_LSA_DATA, lsah);
 }
@@ -296,8 +297,8 @@ const char *dump_lsa_key(struct ospf_lsa *lsa)
 
        if (lsa != NULL && (lsah = lsa->data) != NULL) {
                char id[INET_ADDRSTRLEN], ar[INET_ADDRSTRLEN];
-               strlcpy(id, inet_ntoa(lsah->id), sizeof(id));
-               strlcpy(ar, inet_ntoa(lsah->adv_router), sizeof(ar));
+               inet_ntop(AF_INET, &lsah->id, id, sizeof(id));
+               inet_ntop(AF_INET, &lsah->adv_router, ar, sizeof(ar));
 
                snprintf(buf, sizeof(buf), "Type%d,id(%s),ar(%s)", lsah->type,
                         id, ar);
@@ -627,10 +628,8 @@ static int lsa_link_ptomp_set(struct stream **s, struct ospf_interface *oi)
                                                cost);
                                        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                                                zlog_debug(
-                                                       "PointToMultipoint: set link to %s",
-                                                       inet_ntoa(
-                                                               oi->address->u
-                                                                       .prefix4));
+                                                       "PointToMultipoint: set link to %pI4",
+                                                       &oi->address->u.prefix4);
                                }
 
        return links;
@@ -836,8 +835,8 @@ static struct ospf_lsa *ospf_router_lsa_originate(struct ospf_area *area)
        ospf_flood_through_area(area, NULL, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Originate router-LSA %p",
-                          new->data->type, inet_ntoa(new->data->id),
+               zlog_debug("LSA[Type%d:%pI4]: Originate router-LSA %p",
+                          new->data->type, &new->data->id,
                           (void *)new);
                ospf_lsa_header_dump(new->data);
        }
@@ -875,8 +874,8 @@ static struct ospf_lsa *ospf_router_lsa_refresh(struct ospf_lsa *lsa)
 
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: router-LSA refresh",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: router-LSA refresh",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -928,9 +927,9 @@ int ospf_router_lsa_update(struct ospf *ospf)
                else if (!IPV4_ADDR_SAME(&lsa->data->id, &ospf->router_id)) {
                        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                                zlog_debug(
-                                       "LSA[Type%d:%s]: Refresh router-LSA for Area %s",
+                                       "LSA[Type%d:%pI4]: Refresh router-LSA for Area %s",
                                        lsa->data->type,
-                                       inet_ntoa(lsa->data->id), area_str);
+                                       &lsa->data->id, area_str);
                        ospf_refresher_unregister_lsa(ospf, lsa);
                        ospf_lsa_flush_area(lsa, area);
                        ospf_lsa_unlock(&area->router_lsa_self);
@@ -1058,8 +1057,8 @@ void ospf_network_lsa_update(struct ospf_interface *oi)
        ospf_flood_through_area(oi->area, NULL, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Originate network-LSA %p",
-                          new->data->type, inet_ntoa(new->data->id),
+               zlog_debug("LSA[Type%d:%pI4]: Originate network-LSA %p",
+                          new->data->type, &new->data->id,
                           (void *)new);
                ospf_lsa_header_dump(new->data);
        }
@@ -1081,8 +1080,8 @@ static struct ospf_lsa *ospf_network_lsa_refresh(struct ospf_lsa *lsa)
        if (oi == NULL) {
                if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                        zlog_debug(
-                               "LSA[Type%d:%s]: network-LSA refresh: no oi found, ick, ignoring.",
-                               lsa->data->type, inet_ntoa(lsa->data->id));
+                               "LSA[Type%d:%pI4]: network-LSA refresh: no oi found, ick, ignoring.",
+                               lsa->data->type, &lsa->data->id);
                        ospf_lsa_header_dump(lsa->data);
                }
                return NULL;
@@ -1111,8 +1110,8 @@ static struct ospf_lsa *ospf_network_lsa_refresh(struct ospf_lsa *lsa)
        ospf_flood_through_area(area, NULL, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: network-LSA refresh",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: network-LSA refresh",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1230,8 +1229,8 @@ struct ospf_lsa *ospf_summary_lsa_originate(struct prefix_ipv4 *p,
        ospf_flood_through_area(area, NULL, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Originate summary-LSA %p",
-                          new->data->type, inet_ntoa(new->data->id),
+               zlog_debug("LSA[Type%d:%pI4]: Originate summary-LSA %p",
+                          new->data->type, &new->data->id,
                           (void *)new);
                ospf_lsa_header_dump(new->data);
        }
@@ -1266,8 +1265,8 @@ static struct ospf_lsa *ospf_summary_lsa_refresh(struct ospf *ospf,
 
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: summary-LSA refresh",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: summary-LSA refresh",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1373,8 +1372,8 @@ struct ospf_lsa *ospf_summary_asbr_lsa_originate(struct prefix_ipv4 *p,
        ospf_flood_through_area(area, NULL, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Originate summary-ASBR-LSA %p",
-                          new->data->type, inet_ntoa(new->data->id),
+               zlog_debug("LSA[Type%d:%pI4]: Originate summary-ASBR-LSA %p",
+                          new->data->type, &new->data->id,
                           (void *)new);
                ospf_lsa_header_dump(new->data);
        }
@@ -1407,8 +1406,8 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_refresh(struct ospf *ospf,
        ospf_flood_through_area(new->area, NULL, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: summary-ASBR-LSA refresh",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: summary-ASBR-LSA refresh",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1757,8 +1756,8 @@ static struct ospf_lsa *ospf_lsa_translated_nssa_new(struct ospf *ospf,
            == NULL) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_nssa_translate_originate(): Could not originate Translated Type-5 for %s",
-                               inet_ntoa(ei.p.prefix));
+                               "ospf_nssa_translate_originate(): Could not originate Translated Type-5 for %pI4",
+                               &ei.p.prefix);
                return NULL;
        }
 
@@ -1791,8 +1790,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
        if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_translated_nssa_originate(): Could not translate Type-7, Id %s, to Type-5",
-                               inet_ntoa(type7->data->id));
+                               "ospf_translated_nssa_originate(): Could not translate Type-7, Id %pI4, to Type-5",
+                               &type7->data->id);
                return NULL;
        }
 
@@ -1801,8 +1800,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
        if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
                flog_warn(
                        EC_OSPF_LSA_INSTALL_FAILURE,
-                       "ospf_lsa_translated_nssa_originate(): Could not install LSA id %s",
-                       inet_ntoa(type7->data->id));
+                       "ospf_lsa_translated_nssa_originate(): Could not install LSA id %pI4",
+                       &type7->data->id);
                return NULL;
        }
 
@@ -1811,8 +1810,8 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
                        "ospf_translated_nssa_originate(): translated Type 7, installed:");
                ospf_lsa_header_dump(new->data);
                zlog_debug("   Network mask: %d", ip_masklen(extnew->mask));
-               zlog_debug("   Forward addr: %s",
-                          inet_ntoa(extnew->e[0].fwd_addr));
+               zlog_debug("   Forward addr: %pI4",
+                          &extnew->e[0].fwd_addr);
        }
 
        ospf->lsa_originate_count++;
@@ -1877,8 +1876,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
        if (!type7) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_translated_nssa_refresh(): no Type-7 found for Type-5 LSA Id %s",
-                               inet_ntoa(type5->data->id));
+                               "ospf_translated_nssa_refresh(): no Type-7 found for Type-5 LSA Id %pI4",
+                               &type5->data->id);
                return NULL;
        }
 
@@ -1886,8 +1885,8 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
        if (type5 == NULL || !CHECK_FLAG(type5->flags, OSPF_LSA_LOCAL_XLT)) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_translated_nssa_refresh(): No translated Type-5 found for Type-7 with Id %s",
-                               inet_ntoa(type7->data->id));
+                               "ospf_translated_nssa_refresh(): No translated Type-5 found for Type-7 with Id %pI4",
+                               &type7->data->id);
                return NULL;
        }
 
@@ -1898,16 +1897,16 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
        if ((new = ospf_lsa_translated_nssa_new(ospf, type7)) == NULL) {
                if (IS_DEBUG_OSPF_NSSA)
                        zlog_debug(
-                               "ospf_translated_nssa_refresh(): Could not translate Type-7 for %s to Type-5",
-                               inet_ntoa(type7->data->id));
+                               "ospf_translated_nssa_refresh(): Could not translate Type-7 for %pI4 to Type-5",
+                               &type7->data->id);
                return NULL;
        }
 
        if (!(new = ospf_lsa_install(ospf, NULL, new))) {
                flog_warn(
                        EC_OSPF_LSA_INSTALL_FAILURE,
-                       "ospf_translated_nssa_refresh(): Could not install translated LSA, Id %s",
-                       inet_ntoa(type7->data->id));
+                       "ospf_translated_nssa_refresh(): Could not install translated LSA, Id %pI4",
+                       &type7->data->id);
                return NULL;
        }
 
@@ -1978,16 +1977,12 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
                return NULL;
        }
 
-       /* Check the AS-external-LSA should be originated. */
-       if (!ospf_redistribute_check(ospf, ei, NULL))
-               return NULL;
-
        /* Create new AS-external-LSA instance. */
        if ((new = ospf_external_lsa_new(ospf, ei, NULL)) == NULL) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "LSA[Type5:%s]: Could not originate AS-external-LSA",
-                               inet_ntoa(ei->p.prefix));
+                               "LSA[Type5:%pI4]: Could not originate AS-external-LSA",
+                               &ei->p.prefix);
                return NULL;
        }
 
@@ -2009,8 +2004,8 @@ struct ospf_lsa *ospf_external_lsa_originate(struct ospf *ospf,
 
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Originate AS-external-LSA %p",
-                          new->data->type, inet_ntoa(new->data->id),
+               zlog_debug("LSA[Type%d:%pI4]: Originate AS-external-LSA %p",
+                          new->data->type, &new->data->id,
                           (void *)new);
                ospf_lsa_header_dump(new->data);
        }
@@ -2057,6 +2052,7 @@ static struct external_info *ospf_default_external_info(struct ospf *ospf)
 void ospf_external_lsa_rid_change(struct ospf *ospf)
 {
        struct external_info *ei;
+       struct ospf_external_aggr_rt *aggr;
        int type;
 
        for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
@@ -2088,9 +2084,21 @@ void ospf_external_lsa_rid_change(struct ospf *ospf)
                                                (struct prefix_ipv4 *)&ei->p))
                                        continue;
 
-                               if (!ospf_external_lsa_originate(ospf, ei))
+                               if (!ospf_redistribute_check(ospf, ei, NULL))
+                                       continue;
+
+                               aggr = ospf_external_aggr_match(ospf, &ei->p);
+                               if (aggr) {
+                                       if (IS_DEBUG_OSPF(lsa, EXTNL_LSA_AGGR))
+                                               zlog_debug(
+                                                       "Originate Summary LSA after reset/router-ID change");
+                                       /* Here the LSA is originated as new */
+                                       ospf_originate_summary_lsa(ospf, aggr,
+                                                                  ei);
+                               } else if (!ospf_external_lsa_originate(ospf,
+                                                                       ei))
                                        flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
-                                               "LSA: AS-external-LSA was not originated.");
+                                                 "LSA: AS-external-LSA was not originated.");
                        }
                }
        }
@@ -2116,9 +2124,8 @@ void ospf_nssa_lsa_flush(struct ospf *ospf, struct prefix_ipv4 *p)
                        if (!lsa) {
                                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                                        zlog_debug(
-                                               "LSA: There is no such AS-NSSA-LSA %s/%d in LSDB",
-                                               inet_ntoa(p->prefix),
-                                               p->prefixlen);
+                                               "LSA: There is no such AS-NSSA-LSA %pFX in LSDB",
+                                               p);
                                continue;
                        }
                        ospf_ls_retransmit_delete_nbr_area(area, lsa);
@@ -2138,15 +2145,14 @@ void ospf_external_lsa_flush(struct ospf *ospf, uint8_t type,
        struct ospf_lsa *lsa;
 
        if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
-               zlog_debug("LSA: Flushing AS-external-LSA %s/%d",
-                          inet_ntoa(p->prefix), p->prefixlen);
+               zlog_debug("LSA: Flushing AS-external-LSA %pFX", p);
 
        /* First lookup LSA from LSDB. */
        if (!(lsa = ospf_external_info_find_lsa(ospf, p))) {
                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                        zlog_debug(
-                               "LSA: There is no such AS-external-LSA %s/%d in LSDB",
-                               inet_ntoa(p->prefix), p->prefixlen);
+                               "LSA: There is no such AS-external-LSA %pFX in LSDB",
+                               p);
                return;
        }
 
@@ -2194,8 +2200,9 @@ void ospf_external_lsa_refresh_default(struct ospf *ospf)
        if (ei && lsa) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug("LSA[Type5:0.0.0.0]: Refresh AS-external-LSA %p",
-                                  (void *)lsa);
-               ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE);
+                               (void *)lsa);
+               ospf_external_lsa_refresh(ospf, lsa, ei, LSA_REFRESH_FORCE,
+                                         false);
        } else if (ei && !lsa) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
@@ -2228,15 +2235,51 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type,
                        if (ei) {
                                if (!is_prefix_default(&ei->p)) {
                                        struct ospf_lsa *lsa;
+                                       struct ospf_external_aggr_rt *aggr;
 
+                                       aggr = ospf_external_aggr_match(ospf,
+                                                               &ei->p);
                                        lsa = ospf_external_info_find_lsa(
-                                               ospf, &ei->p);
-                                       if (lsa)
+                                                               ospf, &ei->p);
+                                       if (aggr) {
+                                               /* Check the AS-external-LSA
+                                                * should be originated.
+                                                */
+                                               if (!ospf_redistribute_check(
+                                                           ospf, ei, NULL)) {
+
+                                                       ospf_unlink_ei_from_aggr(
+                                                               ospf, aggr, ei);
+                                                       continue;
+                                               }
+
+                                               if (IS_DEBUG_OSPF(
+                                                           lsa,
+                                                           EXTNL_LSA_AGGR))
+                                                       zlog_debug(
+                                                               "%s: Send Aggreate LSA (%pFX/%d)",
+                                                               __func__,
+                                                               &aggr->p.prefix,
+                                                               aggr->p.prefixlen);
+
+                                               ospf_originate_summary_lsa(
+                                                       ospf, aggr, ei);
+
+                                       } else if (lsa) {
+
+                                               if (IS_LSA_MAXAGE(lsa))
+                                                       force = LSA_REFRESH_FORCE;
+
                                                ospf_external_lsa_refresh(
-                                                       ospf, lsa, ei, force);
-                                       else
+                                                       ospf, lsa, ei, force,
+                                                       false);
+                                       } else {
+                                               if (!ospf_redistribute_check(
+                                                           ospf, ei, NULL))
+                                                       continue;
                                                ospf_external_lsa_originate(
                                                        ospf, ei);
+                                       }
                                }
                        }
                }
@@ -2246,27 +2289,31 @@ void ospf_external_lsa_refresh_type(struct ospf *ospf, uint8_t type,
 /* Refresh AS-external-LSA. */
 struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf,
                                           struct ospf_lsa *lsa,
-                                          struct external_info *ei, int force)
+                                          struct external_info *ei, int force,
+                                          bool is_aggr)
 {
        struct ospf_lsa *new;
-       int changed;
+       int changed = 0;
 
        /* Check the AS-external-LSA should be originated. */
-       if (!ospf_redistribute_check(ospf, ei, &changed)) {
-               if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
-                       zlog_debug(
-                               "LSA[Type%d:%s]: Could not be refreshed, redist check fail",
-                               lsa->data->type, inet_ntoa(lsa->data->id));
-               ospf_external_lsa_flush(ospf, ei->type, &ei->p,
-                                       ei->ifindex /*, ei->nexthop */);
-               return NULL;
-       }
+       if (!is_aggr)
+               if (!ospf_redistribute_check(ospf, ei, &changed)) {
+                       if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
+                               zlog_debug(
+                                       "LSA[Type%d:%s] Could not be refreshed, redist check fail",
+                                       lsa->data->type,
+                                       inet_ntoa(lsa->data->id));
+
+                       ospf_external_lsa_flush(ospf, ei->type, &ei->p,
+                                               ei->ifindex /*, ei->nexthop */);
+                       return NULL;
+               }
 
        if (!changed && !force) {
                if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                        zlog_debug(
-                               "LSA[Type%d:%s]: Not refreshed, not changed/forced",
-                               lsa->data->type, inet_ntoa(lsa->data->id));
+                               "LSA[Type%d:%pI4]: Not refreshed, not changed/forced",
+                               lsa->data->type, &lsa->data->id);
                return NULL;
        }
 
@@ -2280,8 +2327,8 @@ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf,
 
        if (new == NULL) {
                if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
-                       zlog_debug("LSA[Type%d:%s]: Could not be refreshed",
-                                  lsa->data->type, inet_ntoa(lsa->data->id));
+                       zlog_debug("LSA[Type%d:%pI4]: Could not be refreshed",
+                                  lsa->data->type, &lsa->data->id);
                return NULL;
        }
 
@@ -2306,8 +2353,8 @@ struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *ospf,
 
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: AS-external-LSA refresh",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: AS-external-LSA refresh",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -2578,8 +2625,19 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
 
        /* Do comparision and record if recalc needed. */
        rt_recalc = 0;
-       if (old == NULL || ospf_lsa_different(old, lsa))
+       if (old == NULL || ospf_lsa_different(old, lsa)) {
+               /* Ref rfc3623 section 3.2.3
+                * Installing new lsa or change in the existing LSA
+                * or flushing existing LSA leads to topo change
+                * and trigger SPF caculation.
+                * So, router should be aborted from HELPER role
+                * if it is detected as TOPO  change.
+                */
+               if (CHECK_LSA_TYPE_1_TO_5_OR_7(lsa->data->type))
+                       ospf_helper_handle_topo_chg(ospf, lsa);
+
                rt_recalc = 1;
+       }
 
        /*
           Sequence number check (Section 14.1 of rfc 2328)
@@ -2671,8 +2729,6 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
 
        /* Debug logs. */
        if (IS_DEBUG_OSPF(lsa, LSA_INSTALL)) {
-               char area_str[INET_ADDRSTRLEN];
-
                switch (lsa->data->type) {
                case OSPF_AS_EXTERNAL_LSA:
                case OSPF_OPAQUE_AS_LSA:
@@ -2682,13 +2738,11 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
                                              new->data->type, NULL));
                        break;
                default:
-                       strlcpy(area_str, inet_ntoa(new->area->area_id),
-                               sizeof(area_str));
-                       zlog_debug("LSA[%s]: Install %s to Area %s",
+                       zlog_debug("LSA[%s]: Install %s to Area %pI4",
                                   dump_lsa_key(new),
                                   lookup_msg(ospf_lsa_type_msg,
                                              new->data->type, NULL),
-                                  area_str);
+                                  &new->area->area_id);
                        break;
                }
        }
@@ -2699,8 +2753,8 @@ struct ospf_lsa *ospf_lsa_install(struct ospf *ospf, struct ospf_interface *oi,
         */
        if (IS_LSA_MAXAGE(new)) {
                if (IS_DEBUG_OSPF(lsa, LSA_INSTALL))
-                       zlog_debug("LSA[Type%d:%s]: Install LSA 0x%p, MaxAge",
-                                  new->data->type, inet_ntoa(new->data->id),
+                       zlog_debug("LSA[Type%d:%pI4]: Install LSA 0x%p, MaxAge",
+                                  new->data->type, &new->data->id,
                                   (void *)lsa);
                ospf_lsa_maxage(ospf, lsa);
        }
@@ -2776,16 +2830,16 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
                        if (IS_LSA_SELF(lsa))
                                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                                        zlog_debug(
-                                               "LSA[Type%d:%s]: LSA 0x%lx is self-originated: ",
+                                               "LSA[Type%d:%pI4]: LSA 0x%lx is self-originated: ",
                                                lsa->data->type,
-                                               inet_ntoa(lsa->data->id),
+                                               &lsa->data->id,
                                                (unsigned long)lsa);
 
                        if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                                zlog_debug(
-                                       "LSA[Type%d:%s]: MaxAge LSA removed from list",
+                                       "LSA[Type%d:%pI4]: MaxAge LSA removed from list",
                                        lsa->data->type,
-                                       inet_ntoa(lsa->data->id));
+                                       &lsa->data->id);
 
                        if (CHECK_FLAG(lsa->flags, OSPF_LSA_PREMATURE_AGE)) {
                                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
@@ -2802,9 +2856,9 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
                        } else {
                                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                                        zlog_debug(
-                                               "%s: LSA[Type%d:%s]: No associated LSDB!",
+                                               "%s: LSA[Type%d:%pI4]: No associated LSDB!",
                                                __func__, lsa->data->type,
-                                               inet_ntoa(lsa->data->id));
+                                               &lsa->data->id);
                        }
                }
 
@@ -2861,8 +2915,8 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
        if (CHECK_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE)) {
                if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
                        zlog_debug(
-                               "LSA[Type%d:%s]: %p already exists on MaxAge LSA list",
-                               lsa->data->type, inet_ntoa(lsa->data->id),
+                               "LSA[Type%d:%pI4]: %p already exists on MaxAge LSA list",
+                               lsa->data->type, &lsa->data->id,
                                (void *)lsa);
                return;
        }
@@ -3097,8 +3151,8 @@ struct ospf_lsa *ospf_lsa_lookup_by_header(struct ospf_area *area,
 
        if (match == NULL)
                if (IS_DEBUG_OSPF(lsa, LSA) == OSPF_DEBUG_LSA)
-                       zlog_debug("LSA[Type%d:%s]: Lookup by header, NO MATCH",
-                                  lsah->type, inet_ntoa(lsah->id));
+                       zlog_debug("LSA[Type%d:%pI4]: Lookup by header, NO MATCH",
+                                  lsah->type, &lsah->id);
 
        return match;
 }
@@ -3194,8 +3248,8 @@ int ospf_lsa_flush_schedule(struct ospf *ospf, struct ospf_lsa *lsa)
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
-                       lsa->data->type, inet_ntoa(lsa->data->id));
+                       "LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH",
+                       lsa->data->type, &lsa->data->id);
 
        /* Force given lsa's age to MaxAge. */
        lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
@@ -3232,9 +3286,9 @@ void ospf_flush_self_originated_lsas_now(struct ospf *ospf)
                if ((lsa = area->router_lsa_self) != NULL) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
+                                       "LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH",
                                        lsa->data->type,
-                                       inet_ntoa(lsa->data->id));
+                                       &lsa->data->id);
 
                        ospf_refresher_unregister_lsa(ospf, lsa);
                        ospf_lsa_flush_area(lsa, area);
@@ -3247,9 +3301,9 @@ void ospf_flush_self_originated_lsas_now(struct ospf *ospf)
                            && oi->state == ISM_DR && oi->full_nbrs > 0) {
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH",
+                                               "LSA[Type%d:%pI4]: Schedule self-originated LSA to FLUSH",
                                                lsa->data->type,
-                                               inet_ntoa(lsa->data->id));
+                                               &lsa->data->id);
 
                                ospf_refresher_unregister_lsa(
                                        ospf, oi->network_lsa_self);
@@ -3351,8 +3405,8 @@ struct in_addr ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb,
                if (ip_masklen(al->mask) == p->prefixlen) {
                        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                                zlog_debug(
-                                       "ospf_lsa_unique_id(): Can't get Link State ID for %s/%d",
-                                       inet_ntoa(p->prefix), p->prefixlen);
+                                       "ospf_lsa_unique_id(): Can't get Link State ID for %pFX",
+                                       p);
                        /*        id.s_addr = 0; */
                        id.s_addr = 0xffffffff;
                        return id;
@@ -3368,9 +3422,8 @@ struct in_addr ospf_lsa_unique_id(struct ospf *ospf, struct ospf_lsdb *lsdb,
                        if (lsa) {
                                if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                                        zlog_debug(
-                                               "ospf_lsa_unique_id(): Can't get Link State ID for %s/%d",
-                                               inet_ntoa(p->prefix),
-                                               p->prefixlen);
+                                               "ospf_lsa_unique_id(): Can't get Link State ID for %pFX",
+                                               p);
                                /*            id.s_addr = 0; */
                                id.s_addr = 0xffffffff;
                                return id;
@@ -3444,7 +3497,11 @@ void ospf_schedule_lsa_flush_area(struct ospf_area *area, struct ospf_lsa *lsa)
 struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
 {
        struct external_info *ei;
+       struct ospf_external_aggr_rt *aggr;
        struct ospf_lsa *new = NULL;
+       struct as_external_lsa *al;
+       struct prefix_ipv4 p;
+
        assert(CHECK_FLAG(lsa->flags, OSPF_LSA_SELF));
        assert(IS_LSA_SELF(lsa));
        assert(lsa->lock > 0);
@@ -3467,14 +3524,37 @@ struct ospf_lsa *ospf_lsa_refresh(struct ospf *ospf, struct ospf_lsa *lsa)
                /* Translated from NSSA Type-5s are refreshed when
                 * from refresh of Type-7 - do not refresh these directly.
                 */
+
+               al = (struct as_external_lsa *)lsa->data;
+               p.family = AF_INET;
+               p.prefixlen = ip_masklen(al->mask);
+               p.prefix = lsa->data->id;
+
                if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
                        break;
                ei = ospf_external_info_check(ospf, lsa);
                if (ei)
-                       new = ospf_external_lsa_refresh(ospf, lsa, ei,
-                                                       LSA_REFRESH_FORCE);
-               else
-                       ospf_lsa_flush_as(ospf, lsa);
+                       new = ospf_external_lsa_refresh(
+                               ospf, lsa, ei, LSA_REFRESH_FORCE, false);
+               else {
+                       aggr = (struct ospf_external_aggr_rt *)
+                               ospf_extrenal_aggregator_lookup(ospf, &p);
+                       if (aggr) {
+                               struct external_info ei_aggr;
+
+                               memset(&ei_aggr, 0,
+                                       sizeof(struct external_info));
+                               ei_aggr.p = aggr->p;
+                               ei_aggr.tag = aggr->tag;
+                               ei_aggr.instance = ospf->instance;
+                               ei_aggr.route_map_set.metric = -1;
+                               ei_aggr.route_map_set.metric_type = -1;
+
+                               ospf_external_lsa_refresh(ospf, lsa, &ei_aggr,
+                                                 LSA_REFRESH_FORCE, true);
+                       } else
+                               ospf_lsa_flush_as(ospf, lsa);
+               }
                break;
        case OSPF_OPAQUE_LINK_LSA:
        case OSPF_OPAQUE_AREA_LSA:
@@ -3518,8 +3598,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa)
 
                if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
                        zlog_debug(
-                               "LSA[Refresh:Type%d:%s]: age %d, added to index %d",
-                               lsa->data->type, inet_ntoa(lsa->data->id),
+                               "LSA[Refresh:Type%d:%pI4]: age %d, added to index %d",
+                               lsa->data->type, &lsa->data->id,
                                LS_AGE(lsa), index);
 
                if (!ospf->lsa_refresh_queue.qs[index])
@@ -3531,8 +3611,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa)
 
                if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
                        zlog_debug(
-                               "LSA[Refresh:Type%d:%s]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)",
-                               lsa->data->type, inet_ntoa(lsa->data->id),
+                               "LSA[Refresh:Type%d:%pI4]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)",
+                               lsa->data->type, &lsa->data->id,
                                (void *)lsa, index);
        }
 }
@@ -3603,9 +3683,9 @@ int ospf_lsa_refresh_walker(struct thread *t)
                                               lsa)) {
                                if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
                                        zlog_debug(
-                                               "LSA[Refresh:Type%d:%s]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)",
+                                               "LSA[Refresh:Type%d:%pI4]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)",
                                                lsa->data->type,
-                                               inet_ntoa(lsa->data->id),
+                                               &lsa->data->id,
                                                (void *)lsa, i);
 
                                assert(lsa->lock > 0);
@@ -3636,3 +3716,34 @@ int ospf_lsa_refresh_walker(struct thread *t)
 
        return 0;
 }
+
+/* Flush the LSAs for the specific area */
+void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
+                             int type)
+{
+       struct ospf_area *area;
+       struct route_node *rn;
+       struct ospf_lsa *lsa;
+
+       area = ospf_area_get(ospf, area_id);
+
+       switch (type) {
+       case OSPF_AS_EXTERNAL_LSA:
+               if ((area->external_routing == OSPF_AREA_NSSA) ||
+                   (area->external_routing == OSPF_AREA_STUB)) {
+                       LSDB_LOOP (EXTERNAL_LSDB(ospf), rn, lsa)
+                               if (IS_LSA_SELF(lsa) &&
+                                   !(CHECK_FLAG(lsa->flags,
+                                                OSPF_LSA_LOCAL_XLT)))
+                                       ospf_lsa_flush_area(lsa, area);
+               }
+               break;
+       case OSPF_AS_NSSA_LSA:
+               LSDB_LOOP (NSSA_LSDB(area), rn, lsa)
+                       if (IS_LSA_SELF(lsa))
+                               ospf_lsa_flush_area(lsa, area);
+               break;
+       default:
+               break;
+       }
+}
index 4033659bffbe8ae2095400db45642a265a35dc0b..c5de287948103b0bd61d8dec551a43d96f73dcd5 100644 (file)
@@ -119,6 +119,9 @@ struct ospf_lsa {
 
        /* VRF Id */
        vrf_id_t vrf_id;
+
+       /*For topo chg detection in HELPER role*/
+       bool to_be_acknowledged;
 };
 
 /* OSPF LSA Link Type. */
@@ -221,6 +224,11 @@ struct as_external_lsa {
        if (!(T))                                                              \
        (T) = thread_add_timer(master, (F), 0, 2)
 
+#define CHECK_LSA_TYPE_1_TO_5_OR_7(type)                                       \
+       ((type == OSPF_ROUTER_LSA) || (type == OSPF_NETWORK_LSA)               \
+        || (type == OSPF_SUMMARY_LSA) || (type == OSPF_ASBR_SUMMARY_LSA)      \
+        || (type == OSPF_AS_EXTERNAL_LSA) || (type == OSPF_AS_NSSA_LSA))
+
 /* Prototypes. */
 /* XXX: Eek, time functions, similar are in lib/thread.c */
 extern struct timeval int2tv(int);
@@ -305,7 +313,8 @@ extern void ospf_external_lsa_refresh_type(struct ospf *, uint8_t,
                                           unsigned short, int);
 extern struct ospf_lsa *ospf_external_lsa_refresh(struct ospf *,
                                                  struct ospf_lsa *,
-                                                 struct external_info *, int);
+                                                 struct external_info *, int,
+                                                 bool aggr);
 extern struct in_addr ospf_lsa_unique_id(struct ospf *, struct ospf_lsdb *,
                                         uint8_t, struct prefix_ipv4 *);
 extern void ospf_schedule_lsa_flood_area(struct ospf_area *, struct ospf_lsa *);
@@ -331,5 +340,6 @@ extern struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *,
                                                     struct ospf_lsa *);
 extern struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *,
                                                       struct ospf_lsa *);
-
+extern void ospf_flush_lsa_from_area(struct ospf *ospf, struct in_addr area_id,
+                                    int type);
 #endif /* _ZEBRA_OSPF_LSA_H */
index c4dc0136edaeae7b512ba9cd8e9fe5360c83cf14..ae22cec414ad4f791135d32e79e87f14c3b98e6c 100644 (file)
@@ -56,3 +56,5 @@ DEFINE_MTYPE(OSPFD, OSPF_ROUTER_INFO, "OSPF Router Info parameters")
 DEFINE_MTYPE(OSPFD, OSPF_PCE_PARAMS, "OSPF PCE parameters")
 DEFINE_MTYPE(OSPFD, OSPF_EXT_PARAMS, "OSPF Extended parameters")
 DEFINE_MTYPE(OSPFD, OSPF_SR_PARAMS, "OSPF Segment Routing parameters")
+DEFINE_MTYPE(OSPFD, OSPF_GR_HELPER, "OSPF Graceful Restart Helper")
+DEFINE_MTYPE(OSPFD, OSPF_EXTERNAL_RT_AGGR, "OSPF External Route Summarisation")
index 861de64c25d3f0de9869af16832026c6308b5208..624b1d33063c0d7adbc27ca79840a7d0259af784 100644 (file)
@@ -55,5 +55,7 @@ DECLARE_MTYPE(OSPF_ROUTER_INFO)
 DECLARE_MTYPE(OSPF_PCE_PARAMS)
 DECLARE_MTYPE(OSPF_SR_PARAMS)
 DECLARE_MTYPE(OSPF_EXT_PARAMS)
+DECLARE_MTYPE(OSPF_GR_HELPER)
+DECLARE_MTYPE(OSPF_EXTERNAL_RT_AGGR)
 
 #endif /* _QUAGGA_OSPF_MEMORY_H */
index 46dfc505ef0f0475968d7419571246632c56c04d..2fa43923ab3c5cbe4bfdaeaba58ce9d853a06867 100644 (file)
@@ -43,6 +43,7 @@
 #include "ospfd/ospf_flood.h"
 #include "ospfd/ospf_dump.h"
 #include "ospfd/ospf_bfd.h"
+#include "ospfd/ospf_gr_helper.h"
 
 /* Fill in the the 'key' as appropriate to retrieve the entry for nbr
  * from the ospf_interface's nbrs table. Indexed by interface address
@@ -99,6 +100,14 @@ struct ospf_neighbor *ospf_nbr_new(struct ospf_interface *oi)
        nbr->crypt_seqnum = 0;
 
        ospf_bfd_info_nbr_create(oi, nbr);
+
+       /* Initialize GR Helper info*/
+       nbr->gr_helper_info.recvd_grace_period = 0;
+       nbr->gr_helper_info.actual_grace_period = 0;
+       nbr->gr_helper_info.gr_helper_status = OSPF_GR_NOT_HELPER;
+       nbr->gr_helper_info.helper_exit_reason = OSPF_GR_HELPER_EXIT_NONE;
+       nbr->gr_helper_info.gr_restart_reason = OSPF_GR_UNKNOWN_RESTART;
+
        return nbr;
 }
 
@@ -142,6 +151,8 @@ void ospf_nbr_free(struct ospf_neighbor *nbr)
 
        ospf_bfd_info_free(&nbr->bfd_info);
 
+       OSPF_NSM_TIMER_OFF(nbr->gr_helper_info.t_grace_timer);
+
        nbr->oi = NULL;
        XFREE(MTYPE_OSPF_NEIGHBOR, nbr);
 }
@@ -173,8 +184,8 @@ void ospf_nbr_delete(struct ospf_neighbor *nbr)
                        rn->info = NULL;
                        route_unlock_node(rn);
                } else
-                       zlog_info("Can't find neighbor %s in the interface %s",
-                                 inet_ntoa(nbr->src), IF_NAME(oi));
+                       zlog_info("Can't find neighbor %pI4 in the interface %s",
+                                 &nbr->src, IF_NAME(oi));
 
                route_unlock_node(rn);
        } else {
@@ -273,8 +284,8 @@ void ospf_nbr_add_self(struct ospf_interface *oi, struct in_addr router_id)
                /* There is already pseudo neighbor. */
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "router_id %s already present in neighbor table. node refcount %u",
-                               inet_ntoa(router_id), rn->lock);
+                               "router_id %pI4 already present in neighbor table. node refcount %u",
+                               &router_id, route_node_get_lock_count(rn));
                route_unlock_node(rn);
        } else
                rn->info = oi->nbr_self;
@@ -390,8 +401,8 @@ void ospf_renegotiate_optional_capabilities(struct ospf *top)
 
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "Renegotiate optional capabilities with neighbor(%s)",
-                                       inet_ntoa(nbr->router_id));
+                                       "Renegotiate optional capabilities with neighbor(%pI4)",
+                                       &nbr->router_id);
 
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
                }
@@ -448,8 +459,8 @@ static struct ospf_neighbor *ospf_nbr_add(struct ospf_interface *oi,
                nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("NSM[%s:%s]: start", IF_NAME(oi),
-                          inet_ntoa(nbr->router_id));
+               zlog_debug("NSM[%s:%pI4]: start", IF_NAME(oi),
+                          &nbr->router_id);
 
        return nbr;
 }
index 91dfc7a276dbeb11094aad106257ced2e30ce605..758693e28948fd79f72c07e807d550c66c2984c1 100644 (file)
@@ -22,6 +22,7 @@
 #ifndef _ZEBRA_OSPF_NEIGHBOR_H
 #define _ZEBRA_OSPF_NEIGHBOR_H
 
+#include <ospfd/ospf_gr_helper.h>
 #include <ospfd/ospf_packet.h>
 
 /* Neighbor Data Structure */
@@ -88,6 +89,9 @@ struct ospf_neighbor {
 
        /* BFD information */
        void *bfd_info;
+
+       /* ospf graceful restart HELPER info */
+       struct ospf_helper_info gr_helper_info;
 };
 
 /* Macros. */
@@ -113,5 +117,4 @@ extern struct ospf_neighbor *ospf_nbr_lookup_by_addr(struct route_table *,
 extern struct ospf_neighbor *ospf_nbr_lookup_by_routerid(struct route_table *,
                                                         struct in_addr *);
 extern void ospf_renegotiate_optional_capabilities(struct ospf *top);
-
 #endif /* _ZEBRA_OSPF_NEIGHBOR_H */
index 3a1547978a8dd80cb66e8871128c4eb9d4e9054f..00fbdc21a1dff4721f5f425f8d508865454b2691 100644 (file)
@@ -53,14 +53,14 @@ int ospf_if_add_allspfrouters(struct ospf *top, struct prefix *p,
        if (ret < 0)
                flog_err(
                        EC_LIB_SOCKET,
-                       "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?",
-                       top->fd, inet_ntoa(p->u.prefix4), ifindex,
+                       "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?",
+                       top->fd, &p->u.prefix4, ifindex,
                        safe_strerror(errno));
        else {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "interface %s [%u] join AllSPFRouters Multicast group.",
-                               inet_ntoa(p->u.prefix4), ifindex);
+                               "interface %pI4 [%u] join AllSPFRouters Multicast group.",
+                               &p->u.prefix4, ifindex);
        }
 
        return ret;
@@ -76,14 +76,14 @@ int ospf_if_drop_allspfrouters(struct ospf *top, struct prefix *p,
                                        ifindex);
        if (ret < 0)
                flog_err(EC_LIB_SOCKET,
-                        "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllSPFRouters): %s",
-                        top->fd, inet_ntoa(p->u.prefix4), ifindex,
+                        "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllSPFRouters): %s",
+                        top->fd, &p->u.prefix4, ifindex,
                         safe_strerror(errno));
        else {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "interface %s [%u] leave AllSPFRouters Multicast group.",
-                               inet_ntoa(p->u.prefix4), ifindex);
+                               "interface %pI4 [%u] leave AllSPFRouters Multicast group.",
+                               &p->u.prefix4, ifindex);
        }
 
        return ret;
@@ -101,13 +101,13 @@ int ospf_if_add_alldrouters(struct ospf *top, struct prefix *p,
        if (ret < 0)
                flog_err(
                        EC_LIB_SOCKET,
-                       "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllDRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?",
-                       top->fd, inet_ntoa(p->u.prefix4), ifindex,
+                       "can't setsockopt IP_ADD_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s; perhaps a kernel limit on # of multicast group memberships has been exceeded?",
+                       top->fd, &p->u.prefix4, ifindex,
                        safe_strerror(errno));
        else
                zlog_debug(
-                       "interface %s [%u] join AllDRouters Multicast group.",
-                       inet_ntoa(p->u.prefix4), ifindex);
+                       "interface %pI4 [%u] join AllDRouters Multicast group.",
+                       &p->u.prefix4, ifindex);
 
        return ret;
 }
@@ -122,13 +122,13 @@ int ospf_if_drop_alldrouters(struct ospf *top, struct prefix *p,
                                        ifindex);
        if (ret < 0)
                flog_err(EC_LIB_SOCKET,
-                        "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %s, ifindex %u, AllDRouters): %s",
-                        top->fd, inet_ntoa(p->u.prefix4), ifindex,
+                        "can't setsockopt IP_DROP_MEMBERSHIP (fd %d, addr %pI4, ifindex %u, AllDRouters): %s",
+                        top->fd, &p->u.prefix4, ifindex,
                         safe_strerror(errno));
        else
                zlog_debug(
-                       "interface %s [%u] leave AllDRouters Multicast group.",
-                       inet_ntoa(p->u.prefix4), ifindex);
+                       "interface %pI4 [%u] leave AllDRouters Multicast group.",
+                       &p->u.prefix4, ifindex);
 
        return ret;
 }
@@ -161,8 +161,8 @@ int ospf_if_ipmulticast(struct ospf *top, struct prefix *p, ifindex_t ifindex)
        ret = setsockopt_ipv4_multicast_if(top->fd, p->u.prefix4, ifindex);
        if (ret < 0)
                flog_err(EC_LIB_SOCKET,
-                        "can't setsockopt IP_MULTICAST_IF(fd %d, addr %s, ifindex %u): %s",
-                        top->fd, inet_ntoa(p->u.prefix4), ifindex,
+                        "can't setsockopt IP_MULTICAST_IF(fd %d, addr %pI4, ifindex %u): %s",
+                        top->fd, &p->u.prefix4, ifindex,
                         safe_strerror(errno));
 #endif
 
@@ -201,7 +201,6 @@ int ospf_sock_init(struct ospf *ospf)
                        flog_err(EC_LIB_SOCKET,
                                 "Can't set IP_HDRINCL option for fd %d: %s",
                                 ospf_sock, safe_strerror(errno));
-                       close(ospf_sock);
                        break;
                }
 #elif defined(IPTOS_PREC_INTERNETCONTROL)
@@ -213,7 +212,6 @@ int ospf_sock_init(struct ospf *ospf)
                        flog_err(EC_LIB_SOCKET,
                                 "can't set sockopt IP_TOS %d to socket %d: %s",
                                 tos, ospf_sock, safe_strerror(errno));
-                       close(ospf_sock); /* Prevent sd leak. */
                        break;
                }
 #else /* !IPTOS_PREC_INTERNETCONTROL */
index dffbfb7d17b43e93a49c1ac95f969c6d28f534cd..26e7855e8c86e910ca696154841e7e75744c3389 100644 (file)
@@ -66,11 +66,19 @@ static int ospf_inactivity_timer(struct thread *thread)
        nbr->t_inactivity = NULL;
 
        if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
-               zlog_debug("NSM[%s:%s:%s]: Timer (Inactivity timer expire)",
-                          IF_NAME(nbr->oi), inet_ntoa(nbr->router_id),
+               zlog_debug("NSM[%s:%pI4:%s]: Timer (Inactivity timer expire)",
+                          IF_NAME(nbr->oi), &nbr->router_id,
                           ospf_get_name(nbr->oi->ospf));
 
-       OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
+       /* Dont trigger NSM_InactivityTimer event , if the current
+        * router acting as HELPER for this neighbour.
+        */
+       if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
+               OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_InactivityTimer);
+       else if (IS_DEBUG_OSPF_GR_HELPER)
+               zlog_debug(
+                       "%s, Acting as HELPER for this neighbour, So inactivitytimer event will not be fired.",
+                       __PRETTY_FUNCTION__);
 
        return 0;
 }
@@ -83,8 +91,8 @@ static int ospf_db_desc_timer(struct thread *thread)
        nbr->t_db_desc = NULL;
 
        if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
-               zlog_debug("NSM[%s:%s:%s]: Timer (DD Retransmit timer expire)",
-                          IF_NAME(nbr->oi), inet_ntoa(nbr->src),
+               zlog_debug("NSM[%s:%pI4:%s]: Timer (DD Retransmit timer expire)",
+                          IF_NAME(nbr->oi), &nbr->src,
                           ospf_get_name(nbr->oi->ospf));
 
        /* resent last send DD packet. */
@@ -144,7 +152,7 @@ static void nsm_timer_set(struct ospf_neighbor *nbr)
 /* 10.4 of RFC2328, indicate whether an adjacency is appropriate with
  * the given neighbour
  */
-static int nsm_should_adj(struct ospf_neighbor *nbr)
+int nsm_should_adj(struct ospf_neighbor *nbr)
 {
        struct ospf_interface *oi = nbr->oi;
 
@@ -390,9 +398,9 @@ static int nsm_kill_nbr(struct ospf_neighbor *nbr)
 
                if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
                        zlog_debug(
-                               "NSM[%s:%s:%s]: Down (PollIntervalTimer scheduled)",
+                               "NSM[%s:%pI4:%s]: Down (PollIntervalTimer scheduled)",
                                IF_NAME(nbr->oi),
-                               inet_ntoa(nbr->address.u.prefix4),
+                               &nbr->address.u.prefix4,
                                ospf_get_name(nbr->oi->ospf));
        }
 
@@ -589,8 +597,8 @@ static void nsm_notice_state_change(struct ospf_neighbor *nbr, int next_state,
 {
        /* Logging change of status. */
        if (IS_DEBUG_OSPF(nsm, NSM_STATUS))
-               zlog_debug("NSM[%s:%s:%s]: State change %s -> %s (%s)",
-                          IF_NAME(nbr->oi), inet_ntoa(nbr->router_id),
+               zlog_debug("NSM[%s:%pI4:%s]: State change %s -> %s (%s)",
+                          IF_NAME(nbr->oi), &nbr->router_id,
                           ospf_get_name(nbr->oi->ospf),
                           lookup_msg(ospf_nsm_state_msg, nbr->state, NULL),
                           lookup_msg(ospf_nsm_state_msg, next_state, NULL),
@@ -600,8 +608,8 @@ static void nsm_notice_state_change(struct ospf_neighbor *nbr, int next_state,
        if (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_CHANGES)
            && (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL)
                || (next_state == NSM_Full) || (next_state < nbr->state)))
-               zlog_notice("AdjChg: Nbr %s(%s) on %s: %s -> %s (%s)",
-                           inet_ntoa(nbr->router_id),
+               zlog_notice("AdjChg: Nbr %pI4(%s) on %s: %s -> %s (%s)",
+                           &nbr->router_id,
                            ospf_get_name(nbr->oi->ospf), IF_NAME(nbr->oi),
                            lookup_msg(ospf_nsm_state_msg, nbr->state, NULL),
                            lookup_msg(ospf_nsm_state_msg, next_state, NULL),
@@ -683,13 +691,17 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state)
 
                if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
                        zlog_info(
-                               "%s:[%s:%s], %s -> %s): scheduling new router-LSA origination",
-                               __func__, inet_ntoa(nbr->router_id),
+                               "%s:[%pI4:%s], %s -> %s): scheduling new router-LSA origination",
+                               __func__, &nbr->router_id,
                                ospf_get_name(oi->ospf),
                                lookup_msg(ospf_nsm_state_msg, old_state, NULL),
                                lookup_msg(ospf_nsm_state_msg, state, NULL));
 
-               ospf_router_lsa_update_area(oi->area);
+               /* Dont originate router LSA if the current
+                * router is acting as a HELPER for this neighbour.
+                */
+               if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                       ospf_router_lsa_update_area(oi->area);
 
                if (oi->type == OSPF_IFTYPE_VIRTUALLINK) {
                        vl_area = ospf_area_lookup_by_area_id(
@@ -699,15 +711,21 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state)
                                ospf_router_lsa_update_area(vl_area);
                }
 
-               /* Originate network-LSA. */
-               if (oi->state == ISM_DR) {
-                       if (oi->network_lsa_self && oi->full_nbrs == 0) {
-                               ospf_lsa_flush_area(oi->network_lsa_self,
-                                                   oi->area);
-                               ospf_lsa_unlock(&oi->network_lsa_self);
-                               oi->network_lsa_self = NULL;
-                       } else
-                               ospf_network_lsa_update(oi);
+               /* Dont originate/flush network LSA if the current
+                * router is acting as a HELPER for this neighbour.
+                */
+               if (!OSPF_GR_IS_ACTIVE_HELPER(nbr)) {
+                       /* Originate network-LSA. */
+                       if (oi->state == ISM_DR) {
+                               if (oi->network_lsa_self
+                                   && oi->full_nbrs == 0) {
+                                       ospf_lsa_flush_area(
+                                               oi->network_lsa_self, oi->area);
+                                       ospf_lsa_unlock(&oi->network_lsa_self);
+                                       oi->network_lsa_self = NULL;
+                               } else
+                                       ospf_network_lsa_update(oi);
+                       }
                }
        }
 
@@ -731,10 +749,10 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state)
                        OSPF_DD_FLAG_I | OSPF_DD_FLAG_M | OSPF_DD_FLAG_MS;
                if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
                        zlog_info(
-                               "%s: Initializing [DD]: %s with seqnum:%x , flags:%x",
+                               "%s: Initializing [DD]: %pI4 with seqnum:%x , flags:%x",
                                (oi->ospf->name) ? oi->ospf->name
                                                 : VRF_DEFAULT_NAME,
-                               inet_ntoa(nbr->router_id), nbr->dd_seqnum,
+                               &nbr->router_id, nbr->dd_seqnum,
                                nbr->dd_flags);
                ospf_db_desc_send(nbr);
        }
@@ -759,8 +777,8 @@ int ospf_nsm_event(struct thread *thread)
        event = THREAD_VAL(thread);
 
        if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
-               zlog_debug("NSM[%s:%s:%s]: %s (%s)", IF_NAME(nbr->oi),
-                          inet_ntoa(nbr->router_id),
+               zlog_debug("NSM[%s:%pI4:%s]: %s (%s)", IF_NAME(nbr->oi),
+                          &nbr->router_id,
                           ospf_get_name(nbr->oi->ospf),
                           lookup_msg(ospf_nsm_state_msg, nbr->state, NULL),
                           ospf_nsm_event_str[event]);
@@ -784,8 +802,8 @@ int ospf_nsm_event(struct thread *thread)
                         */
                        flog_err(
                                EC_OSPF_FSM_INVALID_STATE,
-                               "NSM[%s:%s:%s]: %s (%s): Warning: action tried to change next_state to %s",
-                               IF_NAME(nbr->oi), inet_ntoa(nbr->router_id),
+                               "NSM[%s:%pI4:%s]: %s (%s): Warning: action tried to change next_state to %s",
+                               IF_NAME(nbr->oi), &nbr->router_id,
                                ospf_get_name(nbr->oi->ospf),
                                lookup_msg(ospf_nsm_state_msg, nbr->state,
                                           NULL),
index dcfba84d8b475bc847519b724ed5488d16687ccd..24cf05009ce231b4caaba777c6988fa3f77450b4 100644 (file)
 #define OSPF_NSM_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr, (V), &(T))
 
 /* Macro for OSPF NSM timer turn off. */
-#define OSPF_NSM_TIMER_OFF(X)                                                  \
-       do {                                                                   \
-               if (X) {                                                       \
-                       thread_cancel(X);                                      \
-                       (X) = NULL;                                            \
-               }                                                              \
-       } while (0)
+#define OSPF_NSM_TIMER_OFF(X) thread_cancel(&(X))
 
 /* Macro for OSPF NSM schedule event. */
 #define OSPF_NSM_EVENT_SCHEDULE(N, E)                                          \
@@ -81,7 +75,7 @@ extern void ospf_check_nbr_loading(struct ospf_neighbor *);
 extern int ospf_db_summary_isempty(struct ospf_neighbor *);
 extern int ospf_db_summary_count(struct ospf_neighbor *);
 extern void ospf_db_summary_clear(struct ospf_neighbor *);
-
+extern int nsm_should_adj(struct ospf_neighbor *nbr);
 DECLARE_HOOK(ospf_nsm_change,
             (struct ospf_neighbor * on, int state, int oldstate),
             (on, state, oldstate))
index 061ada5b167e318dee0ad7609da2323af7809fe8..eb0c4a949ae909ff1b99824daaa01686b8a23322 100644 (file)
@@ -1159,7 +1159,8 @@ void ospf_opaque_config_write_debug(struct vty *vty)
        return;
 }
 
-void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa)
+void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
+                            json_object *json)
 {
        struct lsa_header *lsah = lsa->data;
        uint32_t lsid = ntohl(lsah->id.s_addr);
@@ -1169,13 +1170,17 @@ void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa)
 
        /* Switch output functionality by vty address. */
        if (vty != NULL) {
-               vty_out(vty, "  Opaque-Type %u (%s)\n", opaque_type,
-                       ospf_opaque_type_name(opaque_type));
-               vty_out(vty, "  Opaque-ID   0x%x\n", opaque_id);
-
-               vty_out(vty, "  Opaque-Info: %u octets of data%s\n",
-                       ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE,
-                       VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)");
+               if (!json) {
+                       vty_out(vty, "  Opaque-Type %u (%s)\n", opaque_type,
+                               ospf_opaque_type_name(opaque_type));
+                       vty_out(vty, "  Opaque-ID   0x%x\n", opaque_id);
+
+                       vty_out(vty, "  Opaque-Info: %u octets of data%s\n",
+                               ntohs(lsah->length) - OSPF_LSA_HEADER_SIZE,
+                               VALID_OPAQUE_INFO_LEN(lsah)
+                                       ? ""
+                                       : "(Invalid length?)");
+               }
        } else {
                zlog_debug("    Opaque-Type %u (%s)", opaque_type,
                           ospf_opaque_type_name(opaque_type));
@@ -1200,7 +1205,7 @@ void ospf_opaque_lsa_dump(struct stream *s, uint16_t length)
        struct ospf_lsa lsa;
 
        lsa.data = (struct lsa_header *)stream_pnt(s);
-       show_opaque_info_detail(NULL, &lsa);
+       show_opaque_info_detail(NULL, &lsa, NULL);
        return;
 }
 
@@ -1469,8 +1474,8 @@ static int ospf_opaque_type10_lsa_originate(struct thread *t)
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s",
-                       inet_ntoa(area->area_id));
+                       "Timer[Type10-LSA]: Originate Opaque-LSAs for Area %pI4",
+                       &area->area_id);
 
        rc = opaque_lsa_originate_callback(ospf_opaque_type10_funclist, area);
 
@@ -1626,8 +1631,8 @@ struct ospf_lsa *ospf_opaque_lsa_refresh(struct ospf_lsa *lsa)
                 * LSA from the routing domain.
                 */
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("LSA[Type%d:%s]: Flush stray Opaque-LSA",
-                                  lsa->data->type, inet_ntoa(lsa->data->id));
+                       zlog_debug("LSA[Type%d:%pI4]: Flush stray Opaque-LSA",
+                                  lsa->data->type, &lsa->data->id);
 
                lsa->data->ls_age = htons(OSPF_LSA_MAXAGE);
                ospf_lsa_flush(ospf, lsa);
@@ -1701,8 +1706,8 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
                if ((top = area->ospf) == NULL) {
                        flog_warn(
                                EC_OSPF_LSA,
-                               "ospf_opaque_lsa_reoriginate_schedule: AREA(%s) -> TOP?",
-                               inet_ntoa(area->area_id));
+                               "ospf_opaque_lsa_reoriginate_schedule: AREA(%pI4) -> TOP?",
+                               &area->area_id);
                        goto out;
                }
                if (!list_isempty(ospf_opaque_type10_funclist)
@@ -1710,8 +1715,8 @@ void ospf_opaque_lsa_reoriginate_schedule(void *lsa_type_dependent,
                    && area->t_opaque_lsa_self != NULL) {
                        flog_warn(
                                EC_OSPF_LSA,
-                               "Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%s) has already started",
-                               opaque_type, inet_ntoa(area->area_id));
+                               "Type-10 Opaque-LSA (opaque_type=%u): Common origination for AREA(%pI4) has already started",
+                               opaque_type, &area->area_id);
                        goto out;
                }
                func = ospf_opaque_type10_lsa_reoriginate_timer;
@@ -1927,8 +1932,8 @@ static int ospf_opaque_type10_lsa_reoriginate_timer(struct thread *t)
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "Timer[Type10-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for Area %s",
-                       oipt->opaque_type, inet_ntoa(area->area_id));
+                       "Timer[Type10-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for Area %pI4",
+                       oipt->opaque_type, &area->area_id);
 
        rc = (*functab->lsa_originator)(area);
 out:
index 96155608b28335ff20f385c817e5e238179d9f58..f02f34c9af4096bcbc9cd41ca1cac395db48a1d6 100644 (file)
@@ -24,6 +24,7 @@
 #define _ZEBRA_OSPF_OPAQUE_H
 
 #include "vty.h"
+#include <lib/json.h>
 
 #define IS_OPAQUE_LSA(type)                                                    \
        ((type) == OSPF_OPAQUE_LINK_LSA || (type) == OSPF_OPAQUE_AREA_LSA      \
@@ -148,7 +149,8 @@ extern void ospf_opaque_nsm_change(struct ospf_neighbor *nbr, int old_status);
 extern void ospf_opaque_config_write_router(struct vty *vty, struct ospf *ospf);
 extern void ospf_opaque_config_write_if(struct vty *vty, struct interface *ifp);
 extern void ospf_opaque_config_write_debug(struct vty *vty);
-extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa);
+extern void show_opaque_info_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                   json_object *json);
 extern void ospf_opaque_lsa_dump(struct stream *s, uint16_t length);
 
 extern void ospf_opaque_lsa_originate_schedule(struct ospf_interface *oi,
index 61aae695b3baa7c0086f38dbbb539a9dad5b3d0e..ef39b6c2f67c1e118b64ada6dec57016c47665d0 100644 (file)
@@ -54,6 +54,7 @@
 #include "ospfd/ospf_dump.h"
 #include "ospfd/ospf_errors.h"
 #include "ospfd/ospf_zebra.h"
+#include "ospfd/ospf_gr_helper.h"
 
 /*
  * OSPF Fragmentation / fragmented writes
@@ -467,11 +468,7 @@ static int ospf_ls_req_timer(struct thread *thread)
 
 void ospf_ls_req_event(struct ospf_neighbor *nbr)
 {
-       if (nbr->t_ls_req) {
-               thread_cancel(nbr->t_ls_req);
-               nbr->t_ls_req = NULL;
-       }
-       nbr->t_ls_req = NULL;
+       thread_cancel(&nbr->t_ls_req);
        thread_add_event(master, ospf_ls_req_timer, nbr, 0, &nbr->t_ls_req);
 }
 
@@ -605,15 +602,15 @@ static void ospf_write_frags(int fd, struct ospf_packet *op, struct ip *iph,
                if (ret < 0)
                        flog_err(
                                EC_LIB_SOCKET,
-                               "*** ospf_write_frags: sendmsg failed to %s, id %d, off %d, len %d, mtu %u failed with %s",
-                               inet_ntoa(iph->ip_dst), iph->ip_id, iph->ip_off,
+                               "*** ospf_write_frags: sendmsg failed to %pI4, id %d, off %d, len %d, mtu %u failed with %s",
+                               &iph->ip_dst, iph->ip_id, iph->ip_off,
                                iph->ip_len, mtu, safe_strerror(errno));
 
                if (IS_DEBUG_OSPF_PACKET(type - 1, SEND)) {
                        zlog_debug(
-                               "ospf_write_frags: sent id %d, off %d, len %d to %s",
+                               "ospf_write_frags: sent id %d, off %d, len %d to %pI4",
                                iph->ip_id, iph->ip_off, iph->ip_len,
-                               inet_ntoa(iph->ip_dst));
+                               &iph->ip_dst);
                }
 
                iph->ip_off += offset;
@@ -658,8 +655,8 @@ static int ospf_write(struct thread *thread)
        if (ospf->fd < 0 || ospf->oi_running == 0) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_write failed to send, fd %d, instance %u"
-                               ,ospf->fd, ospf->oi_running);
+                               "ospf_write failed to send, fd %d, instance %u",
+                               ospf->fd, ospf->oi_running);
                return -1;
        }
 
@@ -798,15 +795,15 @@ static int ospf_write(struct thread *thread)
                sockopt_iphdrincl_swab_systoh(&iph);
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_write to %s, id %d, off %d, len %d, interface %s, mtu %u:",
-                               inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off,
+                               "ospf_write to %pI4, id %d, off %d, len %d, interface %s, mtu %u:",
+                               &iph.ip_dst, iph.ip_id, iph.ip_off,
                                iph.ip_len, oi->ifp->name, oi->ifp->mtu);
 
                if (ret < 0)
                        flog_err(
                                EC_LIB_SOCKET,
-                               "*** sendmsg in ospf_write failed to %s, id %d, off %d, len %d, interface %s, mtu %u: %s",
-                               inet_ntoa(iph.ip_dst), iph.ip_id, iph.ip_off,
+                               "*** sendmsg in ospf_write failed to %pI4, id %d, off %d, len %d, interface %s, mtu %u: %s",
+                               &iph.ip_dst, iph.ip_id, iph.ip_off,
                                iph.ip_len, oi->ifp->name, oi->ifp->mtu,
                                safe_strerror(errno));
 
@@ -819,9 +816,9 @@ static int ospf_write(struct thread *thread)
                                ospf_packet_dump(op->s);
                        }
 
-                       zlog_debug("%s sent to [%s] via [%s].",
+                       zlog_debug("%s sent to [%pI4] via [%s].",
                                   lookup_msg(ospf_packet_type_str, type, NULL),
-                                  inet_ntoa(op->dst), IF_NAME(oi));
+                                  &op->dst, IF_NAME(oi));
 
                        if (IS_DEBUG_OSPF_PACKET(type - 1, DETAIL))
                                zlog_debug(
@@ -895,10 +892,10 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
        if (IPV4_ADDR_SAME(&ospfh->router_id, &oi->ospf->router_id)) {
                if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV)) {
                        zlog_debug(
-                               "ospf_header[%s/%s]: selforiginated, dropping.",
+                               "ospf_header[%s/%pI4]: selforiginated, dropping.",
                                lookup_msg(ospf_packet_type_str, ospfh->type,
                                           NULL),
-                               inet_ntoa(iph->ip_src));
+                               &iph->ip_src);
                }
                return;
        }
@@ -915,8 +912,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                if (oi->address->prefixlen != p.prefixlen) {
                        flog_warn(
                                EC_OSPF_PACKET,
-                               "Packet %s [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
-                               inet_ntoa(ospfh->router_id), IF_NAME(oi),
+                               "Packet %pI4 [Hello:RECV]: NetworkMask mismatch on %s (configured prefix length is %d, but hello packet indicates %d).",
+                               &ospfh->router_id, IF_NAME(oi),
                                (int)oi->address->prefixlen, (int)p.prefixlen);
                        return;
                }
@@ -924,8 +921,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
        /* Compare Router Dead Interval. */
        if (OSPF_IF_PARAM(oi, v_wait) != ntohl(hello->dead_interval)) {
                flog_warn(EC_OSPF_PACKET,
-                         "Packet %s [Hello:RECV]: RouterDeadInterval mismatch (expected %u, but received %u).",
-                         inet_ntoa(ospfh->router_id),
+                         "Packet %pI4 [Hello:RECV]: RouterDeadInterval mismatch (expected %u, but received %u).",
+                         &ospfh->router_id,
                          OSPF_IF_PARAM(oi, v_wait),
                          ntohl(hello->dead_interval));
                return;
@@ -937,8 +934,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                    != ntohs(hello->hello_interval)) {
                        flog_warn(
                                EC_OSPF_PACKET,
-                               "Packet %s [Hello:RECV]: HelloInterval mismatch (expected %u, but received %u).",
-                               inet_ntoa(ospfh->router_id),
+                               "Packet %pI4 [Hello:RECV]: HelloInterval mismatch (expected %u, but received %u).",
+                               &ospfh->router_id,
                                OSPF_IF_PARAM(oi, v_hello),
                                ntohs(hello->hello_interval));
                        return;
@@ -946,8 +943,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("Packet %s [Hello:RECV]: Options %s vrf %s",
-                          inet_ntoa(ospfh->router_id),
+               zlog_debug("Packet %pI4 [Hello:RECV]: Options %s vrf %s",
+                          &ospfh->router_id,
                           ospf_options_dump(hello->options),
                           ospf_vrf_id_to_name(oi->ospf->vrf_id));
 
@@ -961,8 +958,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                 * relationship.
                 */
                flog_warn(EC_OSPF_PACKET,
-                         "Packet %s [Hello:RECV]: T-bit on, drop it.",
-                         inet_ntoa(ospfh->router_id));
+                         "Packet %pI4 [Hello:RECV]: T-bit on, drop it.",
+                         &ospfh->router_id);
                return;
        }
 #endif /* REJECT_IF_TBIT_ON */
@@ -974,8 +971,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                 * the bit should be set in DD packet only.
                 */
                flog_warn(EC_OSPF_PACKET,
-                         "Packet %s [Hello:RECV]: O-bit abuse?",
-                         inet_ntoa(ospfh->router_id));
+                         "Packet %pI4 [Hello:RECV]: O-bit abuse?",
+                         &ospfh->router_id);
 #ifdef STRICT_OBIT_USAGE_CHECK
                return; /* Reject this packet. */
 #else                  /* STRICT_OBIT_USAGE_CHECK */
@@ -992,14 +989,14 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                      && !CHECK_FLAG(hello->options, OSPF_OPTION_E))) {
                        flog_warn(
                                EC_OSPF_PACKET,
-                               "NSSA-Packet-%s[Hello:RECV]: my options: %x, his options %x",
-                               inet_ntoa(ospfh->router_id), OPTIONS(oi),
+                               "NSSA-Packet-%pI4[Hello:RECV]: my options: %x, his options %x",
+                               &ospfh->router_id, OPTIONS(oi),
                                hello->options);
                        return;
                }
                if (IS_DEBUG_OSPF_NSSA)
-                       zlog_debug("NSSA-Hello:RECV:Packet from %s:",
-                                  inet_ntoa(ospfh->router_id));
+                       zlog_debug("NSSA-Hello:RECV:Packet from %pI4:",
+                                  &ospfh->router_id);
        } else
                /* The setting of the E-bit found in the Hello Packet's Options
                   field must match this area's ExternalRoutingCapability A
@@ -1010,8 +1007,8 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                    != CHECK_FLAG(hello->options, OSPF_OPTION_E)) {
                flog_warn(
                        EC_OSPF_PACKET,
-                       "Packet %s [Hello:RECV]: my options: %x, his options %x",
-                       inet_ntoa(ospfh->router_id), OPTIONS(oi),
+                       "Packet %pI4 [Hello:RECV]: my options: %x, his options %x",
+                       &ospfh->router_id, OPTIONS(oi),
                        hello->options);
                return;
        }
@@ -1058,7 +1055,16 @@ static void ospf_hello(struct ip *iph, struct ospf_header *ospfh,
                OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_TwoWayReceived);
                nbr->options |= hello->options;
        } else {
-               OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_OneWayReceived);
+               /* If the router is DR_OTHER, RESTARTER will not wait
+                * until it receives the hello from it if it receives
+                * from DR and BDR.
+                * So, helper might receives ONW_WAY hello from
+                * RESTARTER. So not allowing to change the state if it
+                * receives one_way hellow when it acts as HELPER for
+                * that specific neighbor.
+                */
+               if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                       OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_OneWayReceived);
                /* Set neighbor information. */
                nbr->priority = hello->priority;
                nbr->d_router = hello->d_router;
@@ -1137,8 +1143,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi,
                if (IS_OPAQUE_LSA(lsah->type)
                    && !CHECK_FLAG(nbr->options, OSPF_OPTION_O)) {
                        flog_warn(EC_OSPF_PACKET,
-                                 "LSA[Type%d:%s]: Opaque capability mismatch?",
-                                 lsah->type, inet_ntoa(lsah->id));
+                                 "LSA[Type%d:%pI4]: Opaque capability mismatch?",
+                                 lsah->type, &lsah->id);
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
                        return;
                }
@@ -1152,8 +1158,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi,
                        if (oi->area->external_routing == OSPF_AREA_STUB) {
                                flog_warn(
                                        EC_OSPF_PACKET,
-                                       "Packet [DD:RECV]: LSA[Type%d:%s] from %s area.",
-                                       lsah->type, inet_ntoa(lsah->id),
+                                       "Packet [DD:RECV]: LSA[Type%d:%pI4] from %s area.",
+                                       lsah->type, &lsah->id,
                                        (oi->area->external_routing
                                         == OSPF_AREA_STUB)
                                                ? "STUB"
@@ -1208,8 +1214,8 @@ static void ospf_db_desc_proc(struct stream *s, struct ospf_interface *oi,
                         */
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "Packet [DD:RECV]: LSA received Type %d, ID %s is not recent.",
-                                       lsah->type, inet_ntoa(lsah->id));
+                                       "Packet [DD:RECV]: LSA received Type %d, ID %pI4 is not recent.",
+                                       lsah->type, &lsah->id);
                        ospf_lsa_discard(new);
                }
        }
@@ -1277,8 +1283,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
 
        nbr = ospf_nbr_lookup(oi, iph, ospfh);
        if (nbr == NULL) {
-               flog_warn(EC_OSPF_PACKET, "Packet[DD]: Unknown Neighbor %s",
-                         inet_ntoa(ospfh->router_id));
+               flog_warn(EC_OSPF_PACKET, "Packet[DD]: Unknown Neighbor %pI4",
+                         &ospfh->router_id);
                return;
        }
 
@@ -1287,8 +1293,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
            && (ntohs(dd->mtu) > oi->ifp->mtu)) {
                flog_warn(
                        EC_OSPF_PACKET,
-                       "Packet[DD]: Neighbor %s MTU %u is larger than [%s]'s MTU %u",
-                       inet_ntoa(nbr->router_id), ntohs(dd->mtu), IF_NAME(oi),
+                       "Packet[DD]: Neighbor %pI4 MTU %u is larger than [%s]'s MTU %u",
+                       &nbr->router_id, ntohs(dd->mtu), IF_NAME(oi),
                        oi->ifp->mtu);
                return;
        }
@@ -1314,8 +1320,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
            && (!CHECK_FLAG(dd->options, OSPF_OPTION_NP))) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "Packet[DD]: Neighbour %s: Has NSSA capability, sends with N bit clear in DD options",
-                               inet_ntoa(nbr->router_id));
+                               "Packet[DD]: Neighbour %pI4: Has NSSA capability, sends with N bit clear in DD options",
+                               &nbr->router_id);
                SET_FLAG(dd->options, OSPF_OPTION_NP);
        }
 
@@ -1325,8 +1331,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                 * In Hello protocol, optional capability must have checked
                 * to prevent this T-bit enabled router be my neighbor.
                 */
-               flog_warn(EC_OSPF_PACKET, "Packet[DD]: Neighbor %s: T-bit on?",
-                         inet_ntoa(nbr->router_id));
+               flog_warn(EC_OSPF_PACKET, "Packet[DD]: Neighbor %pI4: T-bit on?",
+                         &nbr->router_id);
                return;
        }
 #endif /* REJECT_IF_TBIT_ON */
@@ -1346,9 +1352,9 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
 
        if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
                zlog_info(
-                       "%s:Packet[DD]: Neighbor %s state is %s, seq_num:0x%x, local:0x%x",
+                       "%s:Packet[DD]: Neighbor %pI4 state is %s, seq_num:0x%x, local:0x%x",
                        (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME,
-                       inet_ntoa(nbr->router_id),
+                       &nbr->router_id,
                        lookup_msg(ospf_nsm_state_msg, nbr->state, NULL),
                        ntohl(dd->dd_seqnum), nbr->dd_seqnum);
 
@@ -1359,8 +1365,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
        case NSM_TwoWay:
                if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
                        zlog_info(
-                               "Packet[DD]: Neighbor %s state is %s, packet discarded.",
-                               inet_ntoa(nbr->router_id),
+                               "Packet[DD]: Neighbor %pI4 state is %s, packet discarded.",
+                               &nbr->router_id,
                                lookup_msg(ospf_nsm_state_msg, nbr->state,
                                           NULL));
                break;
@@ -1382,8 +1388,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                                if (CHECK_FLAG(oi->ospf->config,
                                               OSPF_LOG_ADJACENCY_DETAIL))
                                        zlog_info(
-                                               "Packet[DD]: Neighbor %s Negotiation done (Slave).",
-                                               inet_ntoa(nbr->router_id));
+                                               "Packet[DD]: Neighbor %pI4 Negotiation done (Slave).",
+                                               &nbr->router_id);
 
                                nbr->dd_seqnum = ntohl(dd->dd_seqnum);
 
@@ -1396,8 +1402,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                                if (CHECK_FLAG(oi->ospf->config,
                                               OSPF_LOG_ADJACENCY_DETAIL))
                                        zlog_info(
-                                               "Packet[DD]: Neighbor %s: Initial DBD from Slave, ignoring.",
-                                               inet_ntoa(nbr->router_id));
+                                               "Packet[DD]: Neighbor %pI4: Initial DBD from Slave, ignoring.",
+                                               &nbr->router_id);
                                break;
                        }
                }
@@ -1407,14 +1413,14 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                         && IPV4_ADDR_CMP(&nbr->router_id, &oi->ospf->router_id)
                                    < 0) {
                        zlog_info(
-                               "Packet[DD]: Neighbor %s Negotiation done (Master).",
-                               inet_ntoa(nbr->router_id));
+                               "Packet[DD]: Neighbor %pI4 Negotiation done (Master).",
+                               &nbr->router_id);
                        /* Reset I, leaving MS */
                        UNSET_FLAG(nbr->dd_flags, OSPF_DD_FLAG_I);
                } else {
                        flog_warn(EC_OSPF_PACKET,
-                                 "Packet[DD]: Neighbor %s Negotiation fails.",
-                                 inet_ntoa(nbr->router_id));
+                                 "Packet[DD]: Neighbor %pI4 Negotiation fails.",
+                                 &nbr->router_id);
                        break;
                }
 
@@ -1424,8 +1430,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                if (CHECK_FLAG(oi->ospf->config, OSPF_OPAQUE_CAPABLE)) {
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "Neighbor[%s] is %sOpaque-capable.",
-                                       inet_ntoa(nbr->router_id),
+                                       "Neighbor[%pI4] is %sOpaque-capable.",
+                                       &nbr->router_id,
                                        CHECK_FLAG(nbr->options, OSPF_OPTION_O)
                                                ? ""
                                                : "NOT ");
@@ -1435,8 +1441,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                                              &nbr->address.u.prefix4)) {
                                flog_warn(
                                        EC_OSPF_PACKET,
-                                       "DR-neighbor[%s] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.",
-                                       inet_ntoa(nbr->router_id));
+                                       "DR-neighbor[%pI4] is NOT opaque-capable; Opaque-LSAs cannot be reliably advertised in this network.",
+                                       &nbr->router_id);
                                /* This situation is undesirable, but not a real
                                 * error. */
                        }
@@ -1452,15 +1458,15 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                        if (IS_SET_DD_MS(nbr->dd_flags))
                                /* Master: discard duplicated DD packet. */
                                zlog_info(
-                                       "Packet[DD] (Master): Neighbor %s packet duplicated.",
-                                       inet_ntoa(nbr->router_id));
+                                       "Packet[DD] (Master): Neighbor %pI4 packet duplicated.",
+                                       &nbr->router_id);
                        else
                        /* Slave: cause to retransmit the last Database
                           Description. */
                        {
                                zlog_info(
-                                       "Packet[DD] [Slave]: Neighbor %s packet duplicated.",
-                                       inet_ntoa(nbr->router_id));
+                                       "Packet[DD] [Slave]: Neighbor %pI4 packet duplicated.",
+                                       &nbr->router_id);
                                ospf_db_desc_resend(nbr);
                        }
                        break;
@@ -1471,8 +1477,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                if (IS_SET_DD_MS(dd->flags)
                    != IS_SET_DD_MS(nbr->last_recv.flags)) {
                        flog_warn(EC_OSPF_PACKET,
-                                 "Packet[DD]: Neighbor %s MS-bit mismatch.",
-                                 inet_ntoa(nbr->router_id));
+                                 "Packet[DD]: Neighbor %pI4 MS-bit mismatch.",
+                                 &nbr->router_id);
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
                        if (IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
@@ -1483,8 +1489,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
 
                /* Check initialize bit is set. */
                if (IS_SET_DD_I(dd->flags)) {
-                       zlog_info("Packet[DD]: Neighbor %s I-bit set.",
-                                 inet_ntoa(nbr->router_id));
+                       zlog_info("Packet[DD]: Neighbor %pI4 I-bit set.",
+                                 &nbr->router_id);
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
                        break;
                }
@@ -1492,8 +1498,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                /* Check DD Options. */
                if (dd->options != nbr->options) {
                        flog_warn(EC_OSPF_PACKET,
-                                 "Packet[DD]: Neighbor %s options mismatch.",
-                                 inet_ntoa(nbr->router_id));
+                                 "Packet[DD]: Neighbor %pI4 options mismatch.",
+                                 &nbr->router_id);
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
                        break;
                }
@@ -1505,8 +1511,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                        && ntohl(dd->dd_seqnum) != nbr->dd_seqnum + 1)) {
                        flog_warn(
                                EC_OSPF_PACKET,
-                               "Packet[DD]: Neighbor %s sequence number mismatch.",
-                               inet_ntoa(nbr->router_id));
+                               "Packet[DD]: Neighbor %pI4 sequence number mismatch.",
+                               &nbr->router_id);
                        OSPF_NSM_EVENT_SCHEDULE(nbr, NSM_SeqNumberMismatch);
                        break;
                }
@@ -1520,8 +1526,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                        if (IS_SET_DD_MS(nbr->dd_flags)) {
                                /* Master should discard duplicate DD packet. */
                                zlog_info(
-                                       "Packet[DD]: Neighbor %s duplicated, packet discarded.",
-                                       inet_ntoa(nbr->router_id));
+                                       "Packet[DD]: Neighbor %pI4 duplicated, packet discarded.",
+                                       &nbr->router_id);
                                break;
                        } else {
                                if (monotime_since(&nbr->last_send_ts, NULL)
@@ -1554,8 +1560,8 @@ static void ospf_db_desc(struct ip *iph, struct ospf_header *ospfh,
                break;
        default:
                flog_warn(EC_OSPF_PACKET,
-                         "Packet[DD]: Neighbor %s NSM illegal status %u.",
-                         inet_ntoa(nbr->router_id), nbr->state);
+                         "Packet[DD]: Neighbor %pI4 NSM illegal status %u.",
+                         &nbr->router_id, nbr->state);
                break;
        }
 }
@@ -1581,8 +1587,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
        nbr = ospf_nbr_lookup(oi, iph, ospfh);
        if (nbr == NULL) {
                flog_warn(EC_OSPF_PACKET,
-                         "Link State Request: Unknown Neighbor %s.",
-                         inet_ntoa(ospfh->router_id));
+                         "Link State Request: Unknown Neighbor %pI4",
+                         &ospfh->router_id);
                return;
        }
 
@@ -1594,8 +1600,8 @@ static void ospf_ls_req(struct ip *iph, struct ospf_header *ospfh,
            && nbr->state != NSM_Full) {
                flog_warn(
                        EC_OSPF_PACKET,
-                       "Link State Request received from %s: Neighbor state is %s, packet discarded.",
-                       inet_ntoa(ospfh->router_id),
+                       "Link State Request received from %pI4: Neighbor state is %s, packet discarded.",
+                       &ospfh->router_id,
                        lookup_msg(ospf_nsm_state_msg, nbr->state, NULL));
                return;
        }
@@ -1702,10 +1708,10 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
                         * other */
                        flog_warn(
                                EC_OSPF_PACKET,
-                               "Link State Update: LSA checksum error %x/%x, ID=%s from: nbr %s, router ID %s, adv router %s",
-                               sum, lsah->checksum, inet_ntoa(lsah->id),
-                               inet_ntoa(nbr->src), inet_ntoa(nbr->router_id),
-                               inet_ntoa(lsah->adv_router));
+                               "Link State Update: LSA checksum error %x/%x, ID=%pI4 from: nbr %pI4, router ID %pI4, adv router %pI4",
+                               sum, lsah->checksum, &lsah->id,
+                               &nbr->src, &nbr->router_id,
+                               &lsah->adv_router);
                        continue;
                }
 
@@ -1737,8 +1743,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
                                 * only.
                                 */
                                flog_warn(EC_OSPF_PACKET,
-                                         "LSA[Type%d:%s]: O-bit abuse?",
-                                         lsah->type, inet_ntoa(lsah->id));
+                                         "LSA[Type%d:%pI4]: O-bit abuse?",
+                                         lsah->type, &lsah->id);
                                continue;
                        }
 #endif /* STRICT_OBIT_USAGE_CHECK */
@@ -1750,15 +1756,15 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
                                       != OSPF_AREA_DEFAULT) {
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "LSA[Type%d:%s]: We are a stub, don't take this LSA.",
+                                               "LSA[Type%d:%pI4]: We are a stub, don't take this LSA.",
                                                lsah->type,
-                                               inet_ntoa(lsah->id));
+                                               &lsah->id);
                                continue;
                        }
                } else if (IS_OPAQUE_LSA(lsah->type)) {
                        flog_warn(EC_OSPF_PACKET,
-                                 "LSA[Type%d:%s]: Opaque capability mismatch?",
-                                 lsah->type, inet_ntoa(lsah->id));
+                                 "LSA[Type%d:%pI4]: Opaque capability mismatch?",
+                                 lsah->type, &lsah->id);
                        continue;
                }
 
@@ -1786,8 +1792,8 @@ static struct list *ospf_ls_upd_list_lsa(struct ospf_neighbor *nbr,
 
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "LSA[Type%d:%s]: %p new LSA created with Link State Update",
-                               lsa->data->type, inet_ntoa(lsa->data->id),
+                               "LSA[Type%d:%pI4]: %p new LSA created with Link State Update",
+                               lsa->data->type, &lsa->data->id,
                                (void *)lsa);
                listnode_add(lsas, lsa);
        }
@@ -1828,8 +1834,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
        nbr = ospf_nbr_lookup(oi, iph, ospfh);
        if (nbr == NULL) {
                flog_warn(EC_OSPF_PACKET,
-                         "Link State Update: Unknown Neighbor %s on int: %s",
-                         inet_ntoa(ospfh->router_id), IF_NAME(oi));
+                         "Link State Update: Unknown Neighbor %pI4 on int: %s",
+                         &ospfh->router_id, IF_NAME(oi));
                return;
        }
 
@@ -1840,8 +1846,8 @@ static void ospf_ls_upd(struct ospf *ospf, struct ip *iph,
        if (nbr->state < NSM_Exchange) {
                if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
                        zlog_debug(
-                               "Link State Update: Neighbor[%s] state %s is less than Exchange",
-                               inet_ntoa(ospfh->router_id),
+                               "Link State Update: Neighbor[%pI4] state %s is less than Exchange",
+                               &ospfh->router_id,
                                lookup_msg(ospf_nsm_state_msg, nbr->state,
                                           NULL));
                return;
@@ -2231,8 +2237,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
        nbr = ospf_nbr_lookup(oi, iph, ospfh);
        if (nbr == NULL) {
                flog_warn(EC_OSPF_PACKET,
-                         "Link State Acknowledgment: Unknown Neighbor %s.",
-                         inet_ntoa(ospfh->router_id));
+                         "Link State Acknowledgment: Unknown Neighbor %pI4",
+                         &ospfh->router_id);
                return;
        }
 
@@ -2242,8 +2248,8 @@ static void ospf_ls_ack(struct ip *iph, struct ospf_header *ospfh,
        if (nbr->state < NSM_Exchange) {
                if (IS_DEBUG_OSPF(nsm, NSM_EVENTS))
                        zlog_debug(
-                               "Link State Acknowledgment: Neighbor[%s] state %s is less than Exchange",
-                               inet_ntoa(ospfh->router_id),
+                               "Link State Acknowledgment: Neighbor[%pI4] state %s is less than Exchange",
+                               &ospfh->router_id,
                                lookup_msg(ospf_nsm_state_msg, nbr->state,
                                           NULL));
                return;
@@ -2475,9 +2481,9 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
                        if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
                                flog_warn(
                                        EC_OSPF_PACKET,
-                                       "interface %s: Null auth OK, but checksum error, Router-ID %s",
+                                       "interface %s: Null auth OK, but checksum error, Router-ID %pI4",
                                        IF_NAME(oi),
-                                       inet_ntoa(ospfh->router_id));
+                                       &ospfh->router_id);
                        return 0;
                }
                return 1;
@@ -2505,9 +2511,9 @@ static int ospf_check_auth(struct ospf_interface *oi, struct ospf_header *ospfh)
                        if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, RECV))
                                flog_warn(
                                        EC_OSPF_PACKET,
-                                       "interface %s: Simple auth OK, checksum error, Router-ID %s",
+                                       "interface %s: Simple auth OK, checksum error, Router-ID %pI4",
                                        IF_NAME(oi),
-                                       inet_ntoa(ospfh->router_id));
+                                       &ospfh->router_id);
                        return 0;
                }
                return 1;
@@ -2906,8 +2912,8 @@ static int ospf_verify_header(struct stream *ibuf, struct ospf_interface *oi,
        /* Check Area ID. */
        if (!ospf_check_area_id(oi, ospfh)) {
                flog_warn(EC_OSPF_PACKET,
-                         "interface %s: ospf_read invalid Area ID %s.",
-                         IF_NAME(oi), inet_ntoa(ospfh->area_id));
+                         "interface %s: ospf_read invalid Area ID %pI4",
+                         IF_NAME(oi), &ospfh->area_id);
                return -1;
        }
 
@@ -2915,8 +2921,8 @@ static int ospf_verify_header(struct stream *ibuf, struct ospf_interface *oi,
        if (!ospf_check_network_mask(oi, iph->ip_src)) {
                flog_warn(
                        EC_OSPF_PACKET,
-                       "interface %s: ospf_read network address is not same [%s]",
-                       IF_NAME(oi), inet_ntoa(iph->ip_src));
+                       "interface %s: ospf_read network address is not same [%pI4]",
+                       IF_NAME(oi), &iph->ip_src);
                return -1;
        }
 
@@ -2974,8 +2980,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
                if (ifp == NULL) {
                        if (IS_DEBUG_OSPF_PACKET(0, RECV))
                                zlog_debug(
-                                       "%s: Unable to determine incoming interface from: %s(%s)",
-                                       __func__, inet_ntoa(iph->ip_src),
+                                       "%s: Unable to determine incoming interface from: %pI4(%s)",
+                                       __func__, &iph->ip_src,
                                        ospf_get_name(ospf));
                        return OSPF_READ_CONTINUE;
                }
@@ -2985,8 +2991,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
        if (ospf_if_lookup_by_local_addr(ospf, NULL, iph->ip_src)) {
                if (IS_DEBUG_OSPF_PACKET(0, RECV)) {
                        zlog_debug(
-                               "ospf_read[%s]: Dropping self-originated packet",
-                               inet_ntoa(iph->ip_src));
+                               "ospf_read[%pI4]: Dropping self-originated packet",
+                               &iph->ip_src);
                }
                return OSPF_READ_CONTINUE;
        }
@@ -3064,8 +3070,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
                    == NULL) {
                        if (!ospf->instance && IS_DEBUG_OSPF_EVENT)
                                zlog_debug(
-                                       "Packet from [%s] received on link %s but no ospf_interface",
-                                       inet_ntoa(iph->ip_src), ifp->name);
+                                       "Packet from [%pI4] received on link %s but no ospf_interface",
+                                       &iph->ip_src, ifp->name);
                        return OSPF_READ_CONTINUE;
                }
        }
@@ -3077,8 +3083,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
        else if (oi->ifp != ifp) {
                if (IS_DEBUG_OSPF_EVENT)
                        flog_warn(EC_OSPF_PACKET,
-                                 "Packet from [%s] received on wrong link %s",
-                                 inet_ntoa(iph->ip_src), ifp->name);
+                                 "Packet from [%pI4] received on wrong link %s",
+                                 &iph->ip_src, ifp->name);
                return OSPF_READ_CONTINUE;
        } else if (oi->state == ISM_Down) {
                char buf[2][INET_ADDRSTRLEN];
@@ -3112,8 +3118,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
            && (oi->state != ISM_DR && oi->state != ISM_Backup)) {
                flog_warn(
                        EC_OSPF_PACKET,
-                       "Dropping packet for AllDRouters from [%s] via [%s] (ISM: %s)",
-                       inet_ntoa(iph->ip_src), IF_NAME(oi),
+                       "Dropping packet for AllDRouters from [%pI4] via [%s] (ISM: %s)",
+                       &iph->ip_src, IF_NAME(oi),
                        lookup_msg(ospf_ism_state_msg, oi->state, NULL));
                /* Try to fix multicast membership. */
                SET_FLAG(oi->multicast_memberships, MEMBER_DROUTERS);
@@ -3126,8 +3132,8 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
        if (ret < 0) {
                if (IS_DEBUG_OSPF_PACKET(0, RECV))
                        zlog_debug(
-                               "ospf_read[%s]: Header check failed, dropping.",
-                               inet_ntoa(iph->ip_src));
+                               "ospf_read[%pI4]: Header check failed, dropping.",
+                               &iph->ip_src);
                return OSPF_READ_CONTINUE;
        }
 
@@ -3139,11 +3145,11 @@ static enum ospf_read_return_enum ospf_read_helper(struct ospf *ospf)
                        ospf_packet_dump(ibuf);
                }
 
-               zlog_debug("%s received from [%s] via [%s]",
+               zlog_debug("%s received from [%pI4] via [%s]",
                           lookup_msg(ospf_packet_type_str, ospfh->type, NULL),
-                          inet_ntoa(ospfh->router_id), IF_NAME(oi));
-               zlog_debug(" src [%s],", inet_ntoa(iph->ip_src));
-               zlog_debug(" dst [%s]", inet_ntoa(iph->ip_dst));
+                          &ospfh->router_id, IF_NAME(oi));
+               zlog_debug(" src [%pI4],", &iph->ip_src);
+               zlog_debug(" dst [%pI4]", &iph->ip_dst);
 
                if (IS_DEBUG_OSPF_PACKET(ospfh->type - 1, DETAIL))
                        zlog_debug(
@@ -3726,8 +3732,8 @@ int ospf_poll_timer(struct thread *thread)
        nbr_nbma->t_poll = NULL;
 
        if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
-               zlog_debug("NSM[%s:%s]: Timer (Poll timer expire)",
-                          IF_NAME(nbr_nbma->oi), inet_ntoa(nbr_nbma->addr));
+               zlog_debug("NSM[%s:%pI4]: Timer (Poll timer expire)",
+                          IF_NAME(nbr_nbma->oi), &nbr_nbma->addr);
 
        ospf_poll_send(nbr_nbma);
 
@@ -3747,8 +3753,8 @@ int ospf_hello_reply_timer(struct thread *thread)
        nbr->t_hello_reply = NULL;
 
        if (IS_DEBUG_OSPF(nsm, NSM_TIMERS))
-               zlog_debug("NSM[%s:%s]: Timer (hello-reply timer expire)",
-                          IF_NAME(nbr->oi), inet_ntoa(nbr->router_id));
+               zlog_debug("NSM[%s:%pI4]: Timer (hello-reply timer expire)",
+                          IF_NAME(nbr->oi), &nbr->router_id);
 
        ospf_hello_send_sub(nbr->oi, nbr->address.u.prefix4.s_addr);
 
@@ -3865,9 +3871,9 @@ void ospf_db_desc_send(struct ospf_neighbor *nbr)
        monotime(&nbr->last_send_ts);
        if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
                zlog_info(
-                       "%s:Packet[DD]: %s DB Desc send with seqnum:%x , flags:%x",
+                       "%s:Packet[DD]: %pI4 DB Desc send with seqnum:%x , flags:%x",
                        (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME,
-                       inet_ntoa(nbr->router_id), nbr->dd_seqnum,
+                       &nbr->router_id, nbr->dd_seqnum,
                        nbr->dd_flags);
 }
 
@@ -3885,9 +3891,9 @@ void ospf_db_desc_resend(struct ospf_neighbor *nbr)
        OSPF_ISM_WRITE_ON(oi->ospf);
        if (CHECK_FLAG(oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL))
                zlog_info(
-                       "%s:Packet[DD]: %s DB Desc resend with seqnum:%x , flags:%x",
+                       "%s:Packet[DD]: %pI4 DB Desc resend with seqnum:%x , flags:%x",
                        (oi->ospf->name) ? oi->ospf->name : VRF_DEFAULT_NAME,
-                       inet_ntoa(nbr->router_id), nbr->dd_seqnum,
+                       &nbr->router_id, nbr->dd_seqnum,
                        nbr->dd_flags);
 }
 
@@ -3982,10 +3988,10 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update,
 
                if (IS_DEBUG_OSPF_PACKET(0, SEND))
                        zlog_debug(
-                               "ospf_ls_upd_packet_new: oversized LSA id:%s, %d bytes originated by %s, will be fragmented!",
-                               inet_ntoa(lsa->data->id),
+                               "ospf_ls_upd_packet_new: oversized LSA id:%pI4, %d bytes originated by %pI4, will be fragmented!",
+                               &lsa->data->id,
                                ntohs(lsa->data->length),
-                               inet_ntoa(lsa->data->adv_router));
+                               &lsa->data->adv_router);
 
                /*
                 * Allocate just enough to fit this LSA only, to avoid including
@@ -4000,8 +4006,8 @@ static struct ospf_packet *ospf_ls_upd_packet_new(struct list *update,
 
        if (size > OSPF_MAX_PACKET_SIZE) {
                flog_warn(EC_OSPF_LARGE_LSA,
-                         "ospf_ls_upd_packet_new: oversized LSA id:%s too big, %d bytes, packet size %ld, dropping it completely. OSPF routing is broken!",
-                         inet_ntoa(lsa->data->id), ntohs(lsa->data->length),
+                         "ospf_ls_upd_packet_new: oversized LSA id:%pI4 too big, %d bytes, packet size %ld, dropping it completely. OSPF routing is broken!",
+                         &lsa->data->id, ntohs(lsa->data->length),
                          (long int)size);
                list_delete_node(update, ln);
                return NULL;
@@ -4033,8 +4039,8 @@ static void ospf_ls_upd_queue_send(struct ospf_interface *oi,
        uint16_t length = OSPF_HEADER_SIZE;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("listcount = %d, [%s]dst %s", listcount(update),
-                          IF_NAME(oi), inet_ntoa(addr));
+               zlog_debug("listcount = %d, [%s]dst %pI4", listcount(update),
+                          IF_NAME(oi), &addr);
 
        /* Check that we have really something to process */
        if (listcount(update) == 0)
@@ -4262,6 +4268,12 @@ void ospf_ls_ack_send(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
 {
        struct ospf_interface *oi = nbr->oi;
 
+       if (IS_GRACE_LSA(lsa)) {
+               if (IS_DEBUG_OSPF_GR_HELPER)
+                       zlog_debug("%s, Sending GRACE ACK to Restarter.",
+                                  __PRETTY_FUNCTION__);
+       }
+
        if (listcount(oi->ls_ack_direct.ls_ack) == 0)
                oi->ls_ack_direct.dst = nbr->address.u.prefix4;
 
index 5a3e029f2ea9e7f161a7fce9fbb67158918ed63f..72b87edafb42e5e5f0182f19ab25d75bce82828d 100644 (file)
 #define OSPF_LS_UPD_MIN_SIZE      4U
 #define OSPF_LS_ACK_MIN_SIZE      0U
 
-#define OSPF_MSG_HELLO         1  /* OSPF Hello Message. */
-#define OSPF_MSG_DB_DESC       2  /* OSPF Database Descriptoin Message. */
-#define OSPF_MSG_LS_REQ        3  /* OSPF Link State Request Message. */
-#define OSPF_MSG_LS_UPD        4  /* OSPF Link State Update Message. */
-#define OSPF_MSG_LS_ACK        5  /* OSPF Link State Acknoledgement Message. */
+#define OSPF_MSG_HELLO   /* OSPF Hello Message. */
+#define OSPF_MSG_DB_DESC 2 /* OSPF Database Description Message. */
+#define OSPF_MSG_LS_REQ 3  /* OSPF Link State Request Message. */
+#define OSPF_MSG_LS_UPD 4  /* OSPF Link State Update Message. */
+#define OSPF_MSG_LS_ACK 5  /* OSPF Link State Acknowledgement Message. */
 
 #define OSPF_SEND_PACKET_DIRECT         1
 #define OSPF_SEND_PACKET_INDIRECT       2
index fc9c8f6be68929387d2aed30580ed035aedb79e2..3145d16161eabe489c0778a4a34657c7dce492ed 100644 (file)
@@ -544,8 +544,8 @@ static void initialize_params(struct ospf_router_info *ori)
                if (!list_isempty(OspfRI.area_info))
                        list_delete_all_node(OspfRI.area_info);
                for (ALL_LIST_ELEMENTS(top->areas, node, nnode, area)) {
-                       zlog_debug("RI (%s): Add area %s to Router Information",
-                               __func__, inet_ntoa(area->area_id));
+                       zlog_debug("RI (%s): Add area %pI4 to Router Information",
+                               __func__, &area->area_id);
                        new = XCALLOC(MTYPE_OSPF_ROUTER_INFO,
                                sizeof(struct ospf_ri_area_info));
                        new->area = area;
@@ -795,8 +795,8 @@ static struct ospf_lsa *ospf_router_info_lsa_new(struct ospf_area *area)
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                zlog_debug(
-                       "LSA[Type%d:%s]: Create an Opaque-LSA/ROUTER INFORMATION instance",
-                       lsa_type, inet_ntoa(lsa_id));
+                       "LSA[Type%d:%pI4]: Create an Opaque-LSA/ROUTER INFORMATION instance",
+                       lsa_type, &lsa_id);
 
        top = ospf_lookup_by_vrf_id(VRF_DEFAULT);
 
@@ -874,8 +874,8 @@ static int ospf_router_info_lsa_originate_as(void *arg)
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                zlog_debug(
-                       "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION",
-                       new->data->type, inet_ntoa(new->data->id));
+                       "LSA[Type%d:%pI4]: Originate Opaque-LSA/ROUTER INFORMATION",
+                       new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -943,8 +943,8 @@ static int ospf_router_info_lsa_originate_area(void *arg)
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                zlog_debug(
-                       "LSA[Type%d:%s]: Originate Opaque-LSA/ROUTER INFORMATION",
-                       new->data->type, inet_ntoa(new->data->id));
+                       "LSA[Type%d:%pI4]: Originate Opaque-LSA/ROUTER INFORMATION",
+                       new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1094,8 +1094,8 @@ static struct ospf_lsa *ospf_router_info_lsa_refresh(struct ospf_lsa *lsa)
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                zlog_debug(
-                       "LSA[Type%d:%s]: Refresh Opaque-LSA/ROUTER INFORMATION",
-                       new->data->type, inet_ntoa(new->data->id));
+                       "LSA[Type%d:%pI4]: Refresh Opaque-LSA/ROUTER INFORMATION",
+                       new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1247,11 +1247,11 @@ static uint16_t show_vty_pce_subtlv_address(struct vty *vty,
 
        if (ntohs(top->address.type) == PCE_ADDRESS_TYPE_IPV4) {
                if (vty != NULL)
-                       vty_out(vty, "  PCE Address: %s\n",
-                               inet_ntoa(top->address.value));
+                       vty_out(vty, "  PCE Address: %pI4\n",
+                               &top->address.value);
                else
-                       zlog_debug("    PCE Address: %s",
-                                  inet_ntoa(top->address.value));
+                       zlog_debug("    PCE Address: %pI4",
+                                  &top->address.value);
        } else {
                /* TODO: Add support to IPv6 with inet_ntop() */
                if (vty != NULL)
@@ -1288,9 +1288,9 @@ static uint16_t show_vty_pce_subtlv_domain(struct vty *vty,
        if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
                tmp.s_addr = top->value;
                if (vty != NULL)
-                       vty_out(vty, "  PCE domain Area: %s\n", inet_ntoa(tmp));
+                       vty_out(vty, "  PCE domain Area: %pI4\n", &tmp);
                else
-                       zlog_debug("    PCE domain Area: %s", inet_ntoa(tmp));
+                       zlog_debug("    PCE domain Area: %pI4", &tmp);
        } else {
                if (vty != NULL)
                        vty_out(vty, "  PCE domain AS: %d\n",
@@ -1312,10 +1312,10 @@ static uint16_t show_vty_pce_subtlv_neighbor(struct vty *vty,
        if (ntohs(top->type) == PCE_DOMAIN_TYPE_AREA) {
                tmp.s_addr = top->value;
                if (vty != NULL)
-                       vty_out(vty, "  PCE neighbor Area: %s\n",
-                               inet_ntoa(tmp));
+                       vty_out(vty, "  PCE neighbor Area: %pI4\n",
+                               &tmp);
                else
-                       zlog_debug("    PCE neighbor Area: %s", inet_ntoa(tmp));
+                       zlog_debug("    PCE neighbor Area: %pI4", &tmp);
        } else {
                if (vty != NULL)
                        vty_out(vty, "  PCE neighbor AS: %d\n",
@@ -1543,8 +1543,8 @@ static void ospf_router_info_config_write_router(struct vty *vty)
        if (OspfRI.pce_info.enabled) {
 
                if (pce->pce_address.header.type != 0)
-                       vty_out(vty, "  pce address %s\n",
-                               inet_ntoa(pce->pce_address.address.value));
+                       vty_out(vty, "  pce address %pI4\n",
+                               &pce->pce_address.address.value);
 
                if (pce->pce_cap_flag.header.type != 0)
                        vty_out(vty, "  pce flag 0x%x\n",
@@ -1554,8 +1554,8 @@ static void ospf_router_info_config_write_router(struct vty *vty)
                        if (domain->header.type != 0) {
                                if (domain->type == PCE_DOMAIN_TYPE_AREA) {
                                        tmp.s_addr = domain->value;
-                                       vty_out(vty, "  pce domain area %s\n",
-                                               inet_ntoa(tmp));
+                                       vty_out(vty, "  pce domain area %pI4\n",
+                                               &tmp);
                                } else {
                                        vty_out(vty, "  pce domain as %d\n",
                                                ntohl(domain->value));
@@ -1567,8 +1567,9 @@ static void ospf_router_info_config_write_router(struct vty *vty)
                        if (neighbor->header.type != 0) {
                                if (neighbor->type == PCE_DOMAIN_TYPE_AREA) {
                                        tmp.s_addr = neighbor->value;
-                                       vty_out(vty, "  pce neighbor area %s\n",
-                                               inet_ntoa(tmp));
+                                       vty_out(vty,
+                                               "  pce neighbor area %pI4\n",
+                                               &tmp);
                                } else {
                                        vty_out(vty, "  pce neighbor as %d\n",
                                                ntohl(neighbor->value));
index 3b049555ba991e726d5c79cda8546f8349ef241c..bcf563a5ba3fff6ba7ddaf699f52b215aae1bf5f 100644 (file)
@@ -307,8 +307,8 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
        lsa = (struct router_lsa *)v->lsa;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_intra_add_router: LS ID: %s",
-                          inet_ntoa(lsa->header.id));
+               zlog_debug("ospf_intra_add_router: LS ID: %pI4",
+                          &lsa->header.id);
 
        if (!OSPF_IS_AREA_BACKBONE(area))
                ospf_vl_up_check(area, lsa->header.id, v);
@@ -364,8 +364,7 @@ void ospf_intra_add_router(struct route_table *rt, struct vertex *v,
        apply_mask_ipv4(&p);
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_intra_add_router: talking about %s/%d",
-                          inet_ntoa(p.prefix), p.prefixlen);
+               zlog_debug("ospf_intra_add_router: talking about %pFX", &p);
 
        rn = route_node_get(rt, (struct prefix *)&p);
 
@@ -467,8 +466,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        apply_mask_ipv4(&p);
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_intra_add_stub(): processing route to %s/%d",
-                          inet_ntoa(p.prefix), p.prefixlen);
+               zlog_debug("ospf_intra_add_stub(): processing route to %pFX",
+                          &p);
 
        /* (1) Calculate the distance D of stub network from the root.  D is
           equal to the distance from the root to the router vertex
@@ -488,8 +487,8 @@ void ospf_intra_add_stub(struct route_table *rt, struct router_lsa_link *link,
        if (parent_is_root && link->link_data.s_addr == 0xffffffff
            && ospf_if_lookup_by_local_addr(area->ospf, NULL, link->link_id)) {
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("%s: ignoring host route %s/32 to self.",
-                                  __func__, inet_ntoa(link->link_id));
+                       zlog_debug("%s: ignoring host route %pI4/32 to self.",
+                                  __func__, &link->link_id);
                return;
        }
 
@@ -653,8 +652,8 @@ void ospf_route_table_dump(struct route_table *rt)
                                           or->cost);
                                for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
                                                          path))
-                                       zlog_debug("  -> %s",
-                                                  inet_ntoa(path->nexthop));
+                                       zlog_debug("  -> %pI4",
+                                                  &path->nexthop);
                        } else
                                zlog_debug("R %-18pI4 %-15pI4 %s %d",
                                           &rn->p.u.prefix4,
@@ -682,11 +681,12 @@ void ospf_route_table_print(struct vty *vty, struct route_table *rt)
                                        or->cost);
                                for (ALL_LIST_ELEMENTS_RO(or->paths, pnode,
                                                          path))
-                                       vty_out(vty, "  -> %s\n",
-                                               path->nexthop.s_addr != 0
-                                                       ? inet_ntoa(
-                                                               path->nexthop)
-                                                       : "directly connected");
+                                       if (path->nexthop.s_addr != 0)
+                                               vty_out(vty, "  -> %pI4\n",
+                                                       &path->nexthop);
+                                       else
+                                               vty_out(vty, "  -> %s\n",
+                                                       "directly connected");
                        } else
                                vty_out(vty, "R %-18pI4 %-15pI4 %s %d\n",
                                        &rn->p.u.prefix4, & or->u.std.area_id,
@@ -896,9 +896,8 @@ void ospf_prune_unreachable_networks(struct route_table *rt)
                        or = rn->info;
                        if (listcount(or->paths) == 0) {
                                if (IS_DEBUG_OSPF_EVENT)
-                                       zlog_debug("Pruning route to %s/%d",
-                                                  inet_ntoa(rn->p.u.prefix4),
-                                                  rn->p.prefixlen);
+                                       zlog_debug("Pruning route to %pFX",
+                                                  &rn->p);
 
                                ospf_route_free(or);
                                rn->info = NULL;
@@ -926,11 +925,11 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs)
                for (ALL_LIST_ELEMENTS(paths, node, nnode, or)) {
                        if (listcount(or->paths) == 0) {
                                if (IS_DEBUG_OSPF_EVENT) {
-                                       zlog_debug("Pruning route to rtr %s",
-                                                  inet_ntoa(rn->p.u.prefix4));
+                                       zlog_debug("Pruning route to rtr %pI4",
+                                                  &rn->p.u.prefix4);
                                        zlog_debug(
-                                               "               via area %s",
-                                               inet_ntoa(or->u.std.area_id));
+                                               "               via area %pI4",
+                                               &or->u.std.area_id);
                                }
 
                                listnode_delete(paths, or);
@@ -940,8 +939,8 @@ void ospf_prune_unreachable_routers(struct route_table *rtrs)
 
                if (listcount(paths) == 0) {
                        if (IS_DEBUG_OSPF_EVENT)
-                               zlog_debug("Pruning router node %s",
-                                          inet_ntoa(rn->p.u.prefix4));
+                               zlog_debug("Pruning router node %pI4",
+                                          &rn->p.u.prefix4);
 
                        list_delete(&paths);
                        rn->info = NULL;
@@ -989,9 +988,7 @@ int ospf_add_discard_route(struct ospf *ospf, struct route_table *rt,
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug(
-                       "ospf_add_discard_route(): adding %s/%d",
-                       inet_ntoa(p->prefix), p->prefixlen);
+               zlog_debug("ospf_add_discard_route(): adding %pFX", p);
 
        new_or = ospf_route_new();
        new_or->type = OSPF_DESTINATION_DISCARD;
@@ -1014,9 +1011,7 @@ void ospf_delete_discard_route(struct ospf *ospf, struct route_table *rt,
        struct ospf_route * or ;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug(
-                       "ospf_delete_discard_route(): deleting %s/%d",
-                       inet_ntoa(p->prefix), p->prefixlen);
+               zlog_debug("ospf_delete_discard_route(): deleting %pFX", p);
 
        rn = route_node_lookup(rt, (struct prefix *)p);
 
index 63191d5cb58ac7619f25b7bb4bb8ca6821815dda..033046da0a3b6e7f28c0f3d39fde431e3ddca690 100644 (file)
@@ -2455,8 +2455,8 @@ static void ospfTrapNbrStateChange(struct ospf_neighbor *on)
 
        ospf_nbr_state_message(on, msgbuf, sizeof(msgbuf));
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_info("%s: trap sent: %s now %s", __func__,
-                         inet_ntoa(on->address.u.prefix4), msgbuf);
+               zlog_info("%s: trap sent: %pI4 now %s", __func__,
+                         &on->address.u.prefix4, msgbuf);
 
        oid_copy_addr(index, &(on->address.u.prefix4), IN_ADDR_SIZE);
        index[IN_ADDR_SIZE] = 0;
@@ -2486,20 +2486,25 @@ static void ospfTrapVirtNbrStateChange(struct ospf_neighbor *on)
 static int ospf_snmp_nsm_change(struct ospf_neighbor *nbr, int next_state,
                                int old_state)
 {
-       /* Terminal state or regression */
-       if ((next_state == NSM_Full) || (next_state == NSM_TwoWay)
-           || (next_state < old_state)) {
-               /* ospfVirtNbrStateChange */
-               if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
-                       ospfTrapVirtNbrStateChange(nbr);
-               /* ospfNbrStateChange trap  */
-               else
-                       /* To/From FULL, only managed by DR */
-                       if (((next_state != NSM_Full)
-                            && (nbr->state != NSM_Full))
-                           || (nbr->oi->state == ISM_DR))
-                       ospfTrapNbrStateChange(nbr);
-       }
+       /* Transition to/from state Full should be handled only by
+        * DR when in Broadcast or Non-Brodcast Multi-Access networks
+        */
+       if ((next_state == NSM_Full || old_state == NSM_Full)
+           && (nbr->oi->state != ISM_DR)
+           && (nbr->oi->type == OSPF_IFTYPE_BROADCAST
+               || nbr->oi->type == OSPF_IFTYPE_NBMA))
+               return 0;
+
+       /* State progression to non-terminal state */
+       if (next_state > old_state && next_state != NSM_Full
+           && next_state != NSM_TwoWay)
+               return 0;
+
+       if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
+               ospfTrapVirtNbrStateChange(nbr);
+       else
+               ospfTrapNbrStateChange(nbr);
+
        return 0;
 }
 
@@ -2508,8 +2513,8 @@ static void ospfTrapIfStateChange(struct ospf_interface *oi)
        oid index[sizeof(oid) * (IN_ADDR_SIZE + 1)];
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_info("%s: trap sent: %s now %s", __func__,
-                         inet_ntoa(oi->address->u.prefix4),
+               zlog_info("%s: trap sent: %pI4 now %s", __func__,
+                         &oi->address->u.prefix4,
                          lookup_msg(ospf_ism_state_msg, oi->state, NULL));
 
        oid_copy_addr(index, &(oi->address->u.prefix4), IN_ADDR_SIZE);
index f5e393a13c0da1b91bff582b06b03b5800cbfbe2..b53719a402bf80a48e9bccd330b0080347ebd2a7 100644 (file)
@@ -200,10 +200,10 @@ static struct vertex *ospf_vertex_new(struct ospf_area *area,
        listnode_add(area->spf_vertex_list, new);
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("%s: Created %s vertex %s", __func__,
+               zlog_debug("%s: Created %s vertex %pI4", __func__,
                           new->type == OSPF_VERTEX_ROUTER ? "Router"
                                                           : "Network",
-                          inet_ntoa(new->lsa->id));
+                          &new->lsa->id);
 
        return new;
 }
@@ -213,9 +213,9 @@ static void ospf_vertex_free(void *data)
        struct vertex *v = data;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("%s: Free %s vertex %s", __func__,
+               zlog_debug("%s: Free %s vertex %pI4", __func__,
                           v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
-                          inet_ntoa(v->lsa->id));
+                          &v->lsa->id);
 
        if (v->children)
                list_delete(&v->children);
@@ -234,9 +234,9 @@ static void ospf_vertex_dump(const char *msg, struct vertex *v,
        if (!IS_DEBUG_OSPF_EVENT)
                return;
 
-       zlog_debug("%s %s vertex %s  distance %u flags %u", msg,
+       zlog_debug("%s %s vertex %pI4  distance %u flags %u", msg,
                   v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
-                  inet_ntoa(v->lsa->id), v->distance, (unsigned int)v->flags);
+                  &v->lsa->id, v->distance, (unsigned int)v->flags);
 
        if (print_parents) {
                struct listnode *node;
@@ -247,8 +247,8 @@ static void ospf_vertex_dump(const char *msg, struct vertex *v,
 
                        if (vp) {
                                zlog_debug(
-                                       "parent %s backlink %d nexthop %s  lsa pos %d",
-                                       inet_ntoa(vp->parent->lsa->id),
+                                       "parent %pI4 backlink %d nexthop %s  lsa pos %d",
+                                       &vp->parent->lsa->id,
                                        vp->backlink,
                                        inet_ntop(AF_INET, &vp->nexthop->router,
                                                  buf1, BUFSIZ),
@@ -826,9 +826,9 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("%s: Next vertex of %s vertex %s", __func__,
+               zlog_debug("%s: Next vertex of %s vertex %pI4", __func__,
                           v->type == OSPF_VERTEX_ROUTER ? "Router" : "Network",
-                          inet_ntoa(v->lsa->id));
+                          &v->lsa->id);
 
        p = ((uint8_t *)v->lsa) + OSPF_LSA_HEADER_SIZE + 4;
        lim = ((uint8_t *)v->lsa) + ntohs(v->lsa->length);
@@ -868,20 +868,20 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
                                if (type == LSA_LINK_TYPE_VIRTUALLINK
                                    && IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "looking up LSA through VL: %s",
-                                               inet_ntoa(l->link_id));
+                                               "looking up LSA through VL: %pI4",
+                                               &l->link_id);
                                w_lsa = ospf_lsa_lookup(area->ospf, area,
                                                        OSPF_ROUTER_LSA,
                                                        l->link_id, l->link_id);
                                if (w_lsa && IS_DEBUG_OSPF_EVENT)
-                                       zlog_debug("found Router LSA %s",
-                                                  inet_ntoa(l->link_id));
+                                       zlog_debug("found Router LSA %pI4",
+                                                  &l->link_id);
                                break;
                        case LSA_LINK_TYPE_TRANSIT:
                                if (IS_DEBUG_OSPF_EVENT)
                                        zlog_debug(
-                                               "Looking up Network LSA, ID: %s",
-                                               inet_ntoa(l->link_id));
+                                               "Looking up Network LSA, ID: %pI4",
+                                               &l->link_id);
                                w_lsa = ospf_lsa_lookup_by_id(
                                        area, OSPF_NETWORK_LSA, l->link_id);
                                if (w_lsa && IS_DEBUG_OSPF_EVENT)
@@ -904,8 +904,8 @@ static void ospf_spf_next(struct vertex *v, struct ospf_area *area,
                        w_lsa = ospf_lsa_lookup_by_id(area, OSPF_ROUTER_LSA,
                                                      *r);
                        if (w_lsa && IS_DEBUG_OSPF_EVENT)
-                               zlog_debug("found Router LSA %s",
-                                          inet_ntoa(w_lsa->data->id));
+                               zlog_debug("found Router LSA %pI4",
+                                          &w_lsa->data->id);
 
                        /* step (d) below */
                        distance = v->distance;
@@ -1003,20 +1003,21 @@ static void ospf_spf_dump(struct vertex *v, int i)
 
        if (v->type == OSPF_VERTEX_ROUTER) {
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("SPF Result: %d [R] %s", i,
-                                  inet_ntoa(v->lsa->id));
+                       zlog_debug("SPF Result: %d [R] %pI4", i,
+                                  &v->lsa->id);
        } else {
                struct network_lsa *lsa = (struct network_lsa *)v->lsa;
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("SPF Result: %d [N] %s/%d", i,
-                                  inet_ntoa(v->lsa->id),
+                       zlog_debug("SPF Result: %d [N] %pI4/%d", i,
+                                  &v->lsa->id,
                                   ip_masklen(lsa->mask));
        }
 
        if (IS_DEBUG_OSPF_EVENT)
                for (ALL_LIST_ELEMENTS_RO(v->parents, nnode, parent)) {
-                       zlog_debug(" nexthop %p %s %d", (void *)parent->nexthop,
-                                  inet_ntoa(parent->nexthop->router),
+                       zlog_debug(" nexthop %p %pI4 %d",
+                                  (void *)parent->nexthop,
+                                  &parent->nexthop->router,
                                   parent->nexthop->lsa_pos);
                }
 
@@ -1033,17 +1034,17 @@ void ospf_spf_print(struct vty *vty, struct vertex *v, int i)
        struct vertex_parent *parent;
 
        if (v->type == OSPF_VERTEX_ROUTER) {
-               vty_out(vty, "SPF Result: depth %d [R] %s\n", i,
-                       inet_ntoa(v->lsa->id));
+               vty_out(vty, "SPF Result: depth %d [R] %pI4\n", i,
+                       &v->lsa->id);
        } else {
                struct network_lsa *lsa = (struct network_lsa *)v->lsa;
-               vty_out(vty, "SPF Result: depth %d [N] %s/%d\n", i,
-                       inet_ntoa(v->lsa->id), ip_masklen(lsa->mask));
+               vty_out(vty, "SPF Result: depth %d [N] %pI4/%d\n", i,
+                       &v->lsa->id, ip_masklen(lsa->mask));
        }
 
        for (ALL_LIST_ELEMENTS_RO(v->parents, nnode, parent)) {
-               vty_out(vty, " nexthop %s lsa pos %d\n",
-                       inet_ntoa(parent->nexthop->router),
+               vty_out(vty, " nexthop %pI4 lsa pos %d\n",
+                       &parent->nexthop->router,
                        parent->nexthop->lsa_pos);
        }
 
@@ -1061,8 +1062,8 @@ static void ospf_spf_process_stubs(struct ospf_area *area, struct vertex *v,
        struct vertex *child;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("ospf_process_stub():processing stubs for area %s",
-                          inet_ntoa(area->area_id));
+               zlog_debug("ospf_process_stub():processing stubs for area %pI4",
+                          &area->area_id);
 
        if (v->type == OSPF_VERTEX_ROUTER) {
                uint8_t *p;
@@ -1073,8 +1074,8 @@ static void ospf_spf_process_stubs(struct ospf_area *area, struct vertex *v,
 
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_process_stubs():processing router LSA, id: %s",
-                               inet_ntoa(v->lsa->id));
+                               "ospf_process_stubs():processing router LSA, id: %pI4",
+                               &v->lsa->id);
 
                router_lsa = (struct router_lsa *)v->lsa;
 
@@ -1211,8 +1212,8 @@ ospf_rtrs_print (struct route_table *rtrs)
               else
                 {
                   if (IS_DEBUG_OSPF_EVENT)
-                    zlog_debug ("   via %s, %s\r",
-                               inet_ntoa (path->nexthop),
+                    zlog_debug ("   via %pI4, %s\r",
+                               &path->nexthop,
                                ifindex2ifname (path->ifindex), VRF_DEFAULT);
                 }
             }
@@ -1233,8 +1234,8 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa,
 
        if (IS_DEBUG_OSPF_EVENT) {
                zlog_debug("ospf_spf_calculate: Start");
-               zlog_debug("ospf_spf_calculate: running Dijkstra for area %s",
-                          inet_ntoa(area->area_id));
+               zlog_debug("ospf_spf_calculate: running Dijkstra for area %pI4",
+                          &area->area_id);
        }
 
        /*
@@ -1245,8 +1246,8 @@ void ospf_spf_calculate(struct ospf_area *area, struct ospf_lsa *root_lsa,
        if (!root_lsa) {
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "ospf_spf_calculate: Skip area %s's calculation due to empty root LSA",
-                               inet_ntoa(area->area_id));
+                               "ospf_spf_calculate: Skip area %pI4's calculation due to empty root LSA",
+                               &area->area_id);
                return;
        }
 
@@ -1444,20 +1445,19 @@ static int ospf_spf_calculate_schedule_worker(struct thread *thread)
        rbuf[0] = '\0';
        if (spf_reason_flags) {
                if (spf_reason_flags & SPF_FLAG_ROUTER_LSA_INSTALL)
-                       strncat(rbuf, "R, ", sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "R, ", sizeof(rbuf));
                if (spf_reason_flags & SPF_FLAG_NETWORK_LSA_INSTALL)
-                       strncat(rbuf, "N, ", sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "N, ", sizeof(rbuf));
                if (spf_reason_flags & SPF_FLAG_SUMMARY_LSA_INSTALL)
-                       strncat(rbuf, "S, ", sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "S, ", sizeof(rbuf));
                if (spf_reason_flags & SPF_FLAG_ASBR_SUMMARY_LSA_INSTALL)
-                       strncat(rbuf, "AS, ", sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "AS, ", sizeof(rbuf));
                if (spf_reason_flags & SPF_FLAG_ABR_STATUS_CHANGE)
-                       strncat(rbuf, "ABR, ", sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "ABR, ", sizeof(rbuf));
                if (spf_reason_flags & SPF_FLAG_ASBR_STATUS_CHANGE)
-                       strncat(rbuf, "ASBR, ",
-                               sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "ASBR, ", sizeof(rbuf));
                if (spf_reason_flags & SPF_FLAG_MAXAGE)
-                       strncat(rbuf, "M, ", sizeof(rbuf) - strlen(rbuf) - 1);
+                       strlcat(rbuf, "M, ", sizeof(rbuf));
 
                size_t rbuflen = strlen(rbuf);
                if (rbuflen >= 2)
index eb882c5d0e57df2ad4f32d77c092c970238824c0..e2218957d2c8093bcd5bbde6f11597a782e03c68 100644 (file)
@@ -516,10 +516,13 @@ static int ospf_sr_start(struct ospf *ospf)
 static void ospf_sr_stop(void)
 {
 
+       if (OspfSR.status == SR_OFF)
+               return;
+
        osr_debug("SR (%s): Stop Segment Routing", __func__);
 
        /* Disable any re-attempt to connect to Label Manager */
-       THREAD_TIMER_OFF(OspfSR.t_start_lm);
+       THREAD_OFF(OspfSR.t_start_lm);
 
        /* Release SRGB & SRLB if active. */
        if (OspfSR.srgb.reserved)
@@ -1046,6 +1049,7 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl,
        struct listnode *node;
        struct sr_link *lk;
        bool found = false;
+       bool config = true;
 
        /* Sanity check */
        if ((srn == NULL) || (srl == NULL))
@@ -1053,11 +1057,11 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl,
 
        osr_debug("  |-  Process Extended Link Adj/Lan-SID");
 
-       /* Skip Local Adj/Lan_Adj SID coming from neighbors */
+       /* Detect if Adj/Lan_Adj SID must be configured */
        if (!CHECK_FLAG(lsa_flags, OSPF_LSA_SELF)
            && (CHECK_FLAG(srl->flags[0], EXT_SUBTLV_LINK_ADJ_SID_LFLG)
                || CHECK_FLAG(srl->flags[1], EXT_SUBTLV_LINK_ADJ_SID_LFLG)))
-               return;
+               config = false;
 
        /* Search for existing Segment Link */
        for (ALL_LIST_ELEMENTS_RO(srn->ext_link, node, lk))
@@ -1077,28 +1081,31 @@ static void update_ext_link_sid(struct sr_node *srn, struct sr_link *srl,
                IPV4_ADDR_COPY(&srl->adv_router, &srn->adv_router);
                listnode_add(srn->ext_link, srl);
                /* Try to set MPLS table */
-               if (compute_link_nhlfe(srl)) {
+               if (config && compute_link_nhlfe(srl)) {
                        add_adj_sid(srl->nhlfe[0]);
                        add_adj_sid(srl->nhlfe[1]);
                }
        } else {
+               /* Update SR-Link if they are different */
                if (sr_link_cmp(lk, srl)) {
-                       if (compute_link_nhlfe(srl)) {
-                               update_adj_sid(lk->nhlfe[0], srl->nhlfe[0]);
-                               update_adj_sid(lk->nhlfe[1], srl->nhlfe[1]);
-                               /* Replace Segment List */
-                               listnode_delete(srn->ext_link, lk);
-                               XFREE(MTYPE_OSPF_SR_PARAMS, lk);
-                               srl->srn = srn;
-                               IPV4_ADDR_COPY(&srl->adv_router,
-                                              &srn->adv_router);
-                               listnode_add(srn->ext_link, srl);
-                       } else {
-                               /* New NHLFE was not found.
-                                * Just free the SR Link
-                                */
-                               XFREE(MTYPE_OSPF_SR_PARAMS, srl);
+                       /* Try to set MPLS table */
+                       if (config) {
+                               if (compute_link_nhlfe(srl)) {
+                                       update_adj_sid(lk->nhlfe[0],
+                                                      srl->nhlfe[0]);
+                                       update_adj_sid(lk->nhlfe[1],
+                                                      srl->nhlfe[1]);
+                               } else {
+                                       del_adj_sid(lk->nhlfe[0]);
+                                       del_adj_sid(lk->nhlfe[1]);
+                               }
                        }
+                       /* Replace SR-Link in SR-Node Adjacency List */
+                       listnode_delete(srn->ext_link, lk);
+                       XFREE(MTYPE_OSPF_SR_PARAMS, lk);
+                       srl->srn = srn;
+                       IPV4_ADDR_COPY(&srl->adv_router, &srn->adv_router);
+                       listnode_add(srn->ext_link, srl);
                } else {
                        /*
                         * This is just an LSA refresh.
@@ -1879,7 +1886,8 @@ void ospf_sr_update_task(struct ospf *ospf)
 
        struct timeval start_time, stop_time;
 
-       if (ospf == NULL)
+       /* Check ospf and SR status */
+       if ((ospf == NULL) || (OspfSR.status != SR_UP))
                return;
 
        monotime(&start_time);
@@ -1943,10 +1951,8 @@ void ospf_sr_config_write_router(struct vty *vty)
                        for (ALL_LIST_ELEMENTS_RO(OspfSR.self->ext_prefix, node,
                                                  srp)) {
                                vty_out(vty,
-                                       " segment-routing prefix %s/%u "
-                                       "index %u",
-                                       inet_ntoa(srp->prefv4.prefix),
-                                       srp->prefv4.prefixlen, srp->sid);
+                                       " segment-routing prefix %pFX index %u",
+                                       &srp->prefv4, srp->sid);
                                if (CHECK_FLAG(srp->flags,
                                               EXT_SUBTLV_PREFIX_SID_EFLG))
                                        vty_out(vty, " explicit-null\n");
@@ -2445,8 +2451,8 @@ DEFUN (sr_prefix_sid,
        new->instance = ospf_ext_schedule_prefix_index(
                ifp, new->sid, &new->prefv4, new->flags);
        if (new->instance == 0) {
-               vty_out(vty, "Unable to set index %u for prefix %s/%u\n", index,
-                       inet_ntoa(p.u.prefix4), p.prefixlen);
+               vty_out(vty, "Unable to set index %u for prefix %pFX\n",
+                       index, &p);
                return CMD_WARNING;
        }
 
@@ -2568,6 +2574,7 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json,
        char pref[19];
        char sid[22];
        char op[32];
+       char buf[PREFIX_STRLEN];
        int indent = 0;
 
        snprintfrr(pref, 19, "%pFX", (struct prefix *)&srp->prefv4);
@@ -2594,15 +2601,18 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json,
                                            srp->nhlfe.label_out);
                        json_object_string_add(json_obj, "interface",
                                               itf ? itf->name : "-");
-                       json_object_string_add(json_obj, "nexthop",
-                                              inet_ntoa(srp->nhlfe.nexthop));
+                       json_object_string_add(
+                               json_obj, "nexthop",
+                               inet_ntop(AF_INET, &srp->nhlfe.nexthop,
+                                         buf, sizeof(buf)));
                        json_object_array_add(json_route, json_obj);
                } else {
                        sbuf_push(sbuf, 0, "%20s  %9s  %15s\n",
                                  sr_op2str(op, 32, srp->label_in,
                                            srp->nhlfe.label_out),
                                  itf ? itf->name : "-",
-                                 inet_ntoa(srp->nhlfe.nexthop));
+                                 inet_ntop(AF_INET, &srp->nhlfe.nexthop,
+                                           buf, sizeof(buf)));
                }
                return;
        }
@@ -2629,15 +2639,18 @@ static void show_sr_prefix(struct sbuf *sbuf, struct json_object *json,
                                            path->srni.label_out);
                        json_object_string_add(json_obj, "interface",
                                               itf ? itf->name : "-");
-                       json_object_string_add(json_obj, "nexthop",
-                                              inet_ntoa(path->nexthop));
+                       json_object_string_add(
+                               json_obj, "nexthop",
+                               inet_ntop(AF_INET, &path->nexthop,
+                                         buf, sizeof(buf)));
                        json_object_array_add(json_route, json_obj);
                } else {
                        sbuf_push(sbuf, indent, "%20s  %9s  %15s\n",
                                  sr_op2str(op, 32, srp->label_in,
                                            path->srni.label_out),
                                  itf ? itf->name : "-",
-                                 inet_ntoa(path->nexthop));
+                                 inet_ntop(AF_INET, &path->nexthop, buf,
+                                           sizeof(buf)));
                        /* Offset to align information for ECMP */
                        indent = 43;
                }
@@ -2656,6 +2669,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
        char pref[19];
        char sid[22];
        char op[32];
+       char buf[PREFIX_STRLEN];
        uint32_t upper;
        json_object *json_node = NULL, *json_algo, *json_obj;
        json_object *json_prefix = NULL, *json_link = NULL;
@@ -2669,7 +2683,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
        if (json) {
                json_node = json_object_new_object();
                json_object_string_add(json_node, "routerID",
-                                      inet_ntoa(srn->adv_router));
+                                      inet_ntop(AF_INET, &srn->adv_router,
+                                                buf, sizeof(buf)));
                json_object_int_add(json_node, "srgbSize",
                                    srn->srgb.range_size);
                json_object_int_add(json_node, "srgbLabel",
@@ -2696,7 +2711,7 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
                if (srn->msd != 0)
                        json_object_int_add(json_node, "nodeMsd", srn->msd);
        } else {
-               sbuf_push(&sbuf, 0, "SR-Node: %s", inet_ntoa(srn->adv_router));
+               sbuf_push(&sbuf, 0, "SR-Node: %pI4", &srn->adv_router);
                upper = srn->srgb.lower_bound + srn->srgb.range_size - 1;
                sbuf_push(&sbuf, 0, "\tSRGB: [%u/%u]",
                          srn->srgb.lower_bound, upper);
@@ -2760,7 +2775,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
                                               itf ? itf->name : "-");
                        json_object_string_add(
                                json_obj, "nexthop",
-                               inet_ntoa(srl->nhlfe[0].nexthop));
+                               inet_ntop(AF_INET, &srl->nhlfe[0].nexthop,
+                                         buf, sizeof(buf)));
                        json_object_array_add(json_link, json_obj);
                        /* Backup Link */
                        json_obj = json_object_new_object();
@@ -2775,7 +2791,8 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
                                               itf ? itf->name : "-");
                        json_object_string_add(
                                json_obj, "nexthop",
-                               inet_ntoa(srl->nhlfe[1].nexthop));
+                               inet_ntop(AF_INET, &srl->nhlfe[1].nexthop,
+                                         buf, sizeof(buf)));
                        json_object_array_add(json_link, json_obj);
                } else {
                        sbuf_push(&sbuf, 0, "%18s  %21s  %20s  %9s  %15s\n",
@@ -2783,14 +2800,16 @@ static void show_sr_node(struct vty *vty, struct json_object *json,
                                  sr_op2str(op, 32, srl->nhlfe[0].label_in,
                                            srl->nhlfe[0].label_out),
                                  itf ? itf->name : "-",
-                                 inet_ntoa(srl->nhlfe[0].nexthop));
+                                 inet_ntop(AF_INET, &srl->nhlfe[0].nexthop,
+                                           buf, sizeof(buf)));
                        snprintf(sid, 22, "SR Adj. (lbl %u)", srl->sid[1]);
                        sbuf_push(&sbuf, 0, "%18s  %21s  %20s  %9s  %15s\n",
                                  pref, sid,
                                  sr_op2str(op, 32, srl->nhlfe[1].label_in,
                                            srl->nhlfe[1].label_out),
                                  itf ? itf->name : "-",
-                                 inet_ntoa(srl->nhlfe[1].nexthop));
+                                 inet_ntop(AF_INET, &srl->nhlfe[1].nexthop,
+                                         buf, sizeof(buf)));
                }
        }
        if (json)
@@ -2833,6 +2852,7 @@ DEFUN (show_ip_opsf_srdb,
        int idx = 0;
        struct in_addr rid;
        struct sr_node *srn;
+       char buf[PREFIX_STRLEN];
        bool uj = use_json(argc, argv);
        json_object *json = NULL, *json_node_array = NULL;
 
@@ -2844,13 +2864,15 @@ DEFUN (show_ip_opsf_srdb,
        if (uj) {
                json = json_object_new_object();
                json_node_array = json_object_new_array();
-               json_object_string_add(json, "srdbID",
-                                      inet_ntoa(OspfSR.self->adv_router));
+               json_object_string_add(
+                       json, "srdbID",
+                       inet_ntop(AF_INET, &OspfSR.self->adv_router,
+                                 buf, sizeof(buf)));
                json_object_object_add(json, "srNodes", json_node_array);
        } else {
                vty_out(vty,
-                       "\n\t\tOSPF Segment Routing database for ID %s\n\n",
-                       inet_ntoa(OspfSR.self->adv_router));
+                       "\n\t\tOSPF Segment Routing database for ID %pI4\n\n",
+                       &OspfSR.self->adv_router);
        }
 
        if (argv_find(argv, argc, "self-originate", &idx)) {
index c54d2dcc3c90d1991806b071d797d340c21400b7..222675944d4dcf88907216c84b76a16d3b077399 100644 (file)
@@ -269,7 +269,7 @@ struct sr_node {
 
        /* List of Prefix & Link advertise by this node */
        struct list *ext_prefix; /* For Node SID */
-       struct list *ext_link;   /* For Adj and LAN SID */
+       struct list *ext_link;   /* For Adjacency SID */
 
        /* Pointer to FRR SR-Node or NULL if it is not a neighbor */
        struct sr_node *neighbor;
index 1009c7577e04af8e2c020bcfe3086b122d1ea848..e3c554c530b7fb76fa3c42a21dd2f44c532a83e3 100644 (file)
@@ -1043,8 +1043,8 @@ static void ospf_mpls_te_nsm_change(struct ospf_neighbor *nbr, int old_state)
 
        if (IS_DEBUG_OSPF_TE)
                zlog_debug(
-                       "MPLS-TE (%s): Add Link-ID %s for interface %s ",
-                       __func__, inet_ntoa(lp->link_id.value), oi->ifp->name);
+                       "MPLS-TE (%s): Add Link-ID %pI4 for interface %s ",
+                       __func__, &lp->link_id.value, oi->ifp->name);
 
        /* Try to Schedule LSA */
        if (OspfMplsTE.enabled) {
@@ -1187,8 +1187,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_new(struct ospf *ospf,
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE))
                zlog_debug(
-                       "LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance",
-                       lsa_type, inet_ntoa(lsa_id));
+                       "LSA[Type%d:%pI4]: Create an Opaque-LSA/MPLS-TE instance",
+                       lsa_type, &lsa_id);
 
        /* Set opaque-LSA body fields. */
        ospf_mpls_te_lsa_body_set(s, lp);
@@ -1243,11 +1243,9 @@ static int ospf_mpls_te_lsa_originate1(struct ospf_area *area,
        ospf_flood_through_area(area, NULL /*nbr*/, new);
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               char area_id[INET_ADDRSTRLEN];
-               strlcpy(area_id, inet_ntoa(area->area_id), sizeof(area_id));
                zlog_debug(
-                       "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)",
-                       new->data->type, inet_ntoa(new->data->id), area_id,
+                       "LSA[Type%d:%pI4]: Originate Opaque-LSA/MPLS-TE: Area(%pI4), Link(%s)",
+                       new->data->type, &new->data->id, &area->area_id,
                        lp->ifp->name);
                ospf_lsa_header_dump(new->data);
        }
@@ -1302,8 +1300,8 @@ static int ospf_mpls_te_lsa_originate_area(void *arg)
                /* Ok, let's try to originate an LSA for this area and Link. */
                if (IS_DEBUG_OSPF_TE)
                        zlog_debug(
-                               "MPLS-TE(ospf_mpls_te_lsa_originate_area) Let's finally reoriginate the LSA %d through the Area %s for Link %s",
-                               lp->instance, inet_ntoa(area->area_id),
+                               "MPLS-TE(ospf_mpls_te_lsa_originate_area) Let's finally reoriginate the LSA %d through the Area %pI4 for Link %s",
+                               lp->instance, &area->area_id,
                                lp->ifp ? lp->ifp->name : "?");
                if (ospf_mpls_te_lsa_originate1(area, lp) != 0)
                        return rc;
@@ -1347,8 +1345,8 @@ static int ospf_mpls_te_lsa_originate2(struct ospf *top,
 
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
                zlog_debug(
-                       "LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE Inter-AS",
-                       new->data->type, inet_ntoa(new->data->id));
+                       "LSA[Type%d:%pI4]: Originate Opaque-LSA/MPLS-TE Inter-AS",
+                       new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1490,8 +1488,8 @@ static struct ospf_lsa *ospf_mpls_te_lsa_refresh(struct ospf_lsa *lsa)
 
        /* Debug logging. */
        if (IS_DEBUG_OSPF(lsa, LSA_GENERATE)) {
-               zlog_debug("LSA[Type%d:%s]: Refresh Opaque-LSA/MPLS-TE",
-                          new->data->type, inet_ntoa(new->data->id));
+               zlog_debug("LSA[Type%d:%pI4]: Refresh Opaque-LSA/MPLS-TE",
+                          new->data->type, &new->data->id);
                ospf_lsa_header_dump(new->data);
        }
 
@@ -1593,9 +1591,9 @@ static uint16_t show_vty_router_addr(struct vty *vty, struct tlv_header *tlvh)
        struct te_tlv_router_addr *top = (struct te_tlv_router_addr *)tlvh;
 
        if (vty != NULL)
-               vty_out(vty, "  Router-Address: %s\n", inet_ntoa(top->value));
+               vty_out(vty, "  Router-Address: %pI4\n", &top->value);
        else
-               zlog_debug("    Router-Address: %s", inet_ntoa(top->value));
+               zlog_debug("    Router-Address: %pI4", &top->value);
 
        return TLV_SIZE(tlvh);
 }
@@ -1648,9 +1646,9 @@ static uint16_t show_vty_link_subtlv_link_id(struct vty *vty,
 
        top = (struct te_link_subtlv_link_id *)tlvh;
        if (vty != NULL)
-               vty_out(vty, "  Link-ID: %s\n", inet_ntoa(top->value));
+               vty_out(vty, "  Link-ID: %pI4\n", &top->value);
        else
-               zlog_debug("    Link-ID: %s", inet_ntoa(top->value));
+               zlog_debug("    Link-ID: %pI4", &top->value);
 
        return TLV_SIZE(tlvh);
 }
@@ -1671,11 +1669,9 @@ static uint16_t show_vty_link_subtlv_lclif_ipaddr(struct vty *vty,
 
        for (i = 0; i < n; i++) {
                if (vty != NULL)
-                       vty_out(vty, "    #%d: %s\n", i,
-                               inet_ntoa(top->value[i]));
+                       vty_out(vty, "    #%d: %pI4\n", i, &top->value[i]);
                else
-                       zlog_debug("      #%d: %s", i,
-                                  inet_ntoa(top->value[i]));
+                       zlog_debug("      #%d: %pI4", i, &top->value[i]);
        }
        return TLV_SIZE(tlvh);
 }
@@ -1695,11 +1691,9 @@ static uint16_t show_vty_link_subtlv_rmtif_ipaddr(struct vty *vty,
 
        for (i = 0; i < n; i++) {
                if (vty != NULL)
-                       vty_out(vty, "    #%d: %s\n", i,
-                               inet_ntoa(top->value[i]));
+                       vty_out(vty, "    #%d: %pI4\n", i, &top->value[i]);
                else
-                       zlog_debug("      #%d: %s", i,
-                                  inet_ntoa(top->value[i]));
+                       zlog_debug("      #%d: %pI4", i, &top->value[i]);
        }
        return TLV_SIZE(tlvh);
 }
@@ -1811,15 +1805,15 @@ static uint16_t show_vty_link_subtlv_lrrid(struct vty *vty,
        top = (struct te_link_subtlv_lrrid *)tlvh;
 
        if (vty != NULL) {
-               vty_out(vty, "  Local  TE Router ID: %s\n",
-                       inet_ntoa(top->local));
-               vty_out(vty, "  Remote TE Router ID: %s\n",
-                       inet_ntoa(top->remote));
+               vty_out(vty, "  Local  TE Router ID: %pI4\n",
+                       &top->local);
+               vty_out(vty, "  Remote TE Router ID: %pI4\n",
+                       &top->remote);
        } else {
-               zlog_debug("    Local  TE Router ID: %s",
-                          inet_ntoa(top->local));
-               zlog_debug("    Remote TE Router ID: %s",
-                          inet_ntoa(top->remote));
+               zlog_debug("    Local  TE Router ID: %pI4",
+                          &top->local);
+               zlog_debug("    Remote TE Router ID: %pI4",
+                          &top->remote);
        }
 
        return TLV_SIZE(tlvh);
@@ -1855,11 +1849,11 @@ static uint16_t show_vty_link_subtlv_rip(struct vty *vty,
        top = (struct te_link_subtlv_rip *)tlvh;
 
        if (vty != NULL)
-               vty_out(vty, "  Inter-AS TE Remote ASBR IP address: %s\n",
-                       inet_ntoa(top->value));
+               vty_out(vty, "  Inter-AS TE Remote ASBR IP address: %pI4\n",
+                       &top->value);
        else
-               zlog_debug("    Inter-AS TE Remote ASBR IP address: %s",
-                          inet_ntoa(top->value));
+               zlog_debug("    Inter-AS TE Remote ASBR IP address: %pI4",
+                          &top->value);
 
        return TLV_SIZE(tlvh);
 }
@@ -2160,15 +2154,15 @@ static void ospf_mpls_te_config_write_router(struct vty *vty)
 
        if (OspfMplsTE.enabled) {
                vty_out(vty, " mpls-te on\n");
-               vty_out(vty, " mpls-te router-address %s\n",
-                       inet_ntoa(OspfMplsTE.router_addr.value));
+               vty_out(vty, " mpls-te router-address %pI4\n",
+                       &OspfMplsTE.router_addr.value);
        }
 
        if (OspfMplsTE.inter_as == AS)
                vty_out(vty, "  mpls-te inter-as as\n");
        if (OspfMplsTE.inter_as == Area)
-               vty_out(vty, "  mpls-te inter-as area %s \n",
-                       inet_ntoa(OspfMplsTE.interas_areaid));
+               vty_out(vty, "  mpls-te inter-as area %pI4 \n",
+                       &OspfMplsTE.interas_areaid);
 
        return;
 }
index 8099b0160cf386a4983df465f5446fbf36caf9b8..28ee4db3a15f55fdd63f749f5fe6a476a976a661 100644 (file)
@@ -22,6 +22,7 @@
 #include <zebra.h>
 #include <string.h>
 
+#include "printfrr.h"
 #include "monotime.h"
 #include "memory.h"
 #include "thread.h"
@@ -34,6 +35,7 @@
 #include "zclient.h"
 #include <lib/json.h>
 #include "defaults.h"
+#include "lib/printfrr.h"
 
 #include "ospfd/ospfd.h"
 #include "ospfd/ospf_asbr.h"
@@ -54,6 +56,7 @@
 #include "ospfd/ospf_bfd.h"
 #include "ospfd/ospf_ldp_sync.h"
 
+
 FRR_CFG_DEFAULT_BOOL(OSPF_LOG_ADJACENCY_CHANGES,
        { .val_bool = true, .match_profile = "datacenter", },
        { .val_bool = false },
@@ -213,9 +216,6 @@ DEFUN_NOSH (router_ospf,
        struct ospf *ospf = NULL;
        int ret = CMD_SUCCESS;
        unsigned short instance = 0;
-       struct vrf *vrf = NULL;
-       struct route_node *rn;
-       struct interface *ifp;
 
        ospf = ospf_cmd_lookup_ospf(vty, argv, argc, 1, &instance);
        if (!ospf)
@@ -227,46 +227,12 @@ DEFUN_NOSH (router_ospf,
                VTY_PUSH_CONTEXT_NULL(OSPF_NODE);
                ret = CMD_NOT_MY_INSTANCE;
        } else {
-               if (ospf->vrf_id != VRF_UNKNOWN)
-                       ospf->oi_running = 1;
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
                                "Config command 'router ospf %d' received, vrf %s id %u oi_running %u",
                                instance, ospf->name ? ospf->name : "NIL",
                                ospf->vrf_id, ospf->oi_running);
                VTY_PUSH_CONTEXT(OSPF_NODE, ospf);
-
-               /* Activate 'ip ospf area x' configured interfaces for given
-                * vrf. Activate area on vrf x aware interfaces.
-                * vrf_enable callback calls router_id_update which
-                * internally will call ospf_if_update to trigger
-                * network_run_state
-                */
-               vrf = vrf_lookup_by_id(ospf->vrf_id);
-
-               FOR_ALL_INTERFACES (vrf, ifp) {
-                       struct ospf_if_params *params;
-
-                       params = IF_DEF_PARAMS(ifp);
-                       if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
-                               for (rn = route_top(ospf->networks); rn;
-                                    rn = route_next(rn)) {
-                                       if (rn->info != NULL) {
-                                               vty_out(vty,
-                                                       "Interface %s has area config but please remove all network commands first.\n",
-                                                       ifp->name);
-                                               return ret;
-                                       }
-                               }
-                               if (!ospf_interface_area_is_already_set(ospf,
-                                                                       ifp)) {
-                                       ospf_interface_area_set(ospf, ifp);
-                                       ospf->if_ospf_cli_count++;
-                               }
-                       }
-               }
-
-               ospf_router_id_update(ospf);
        }
 
        return ret;
@@ -921,7 +887,7 @@ ospf_find_vl_data(struct ospf *ospf, struct ospf_vl_config_data *vl_config)
 
        if (area->external_routing != OSPF_AREA_DEFAULT) {
                if (vl_config->area_id_fmt == OSPF_AREA_ID_FMT_DOTTEDQUAD)
-                       vty_out(vty, "Area %s is %s\n", inet_ntoa(area_id),
+                       vty_out(vty, "Area %pI4 is %s\n", &area_id,
                                area->external_routing == OSPF_AREA_NSSA
                                        ? "nssa"
                                        : "stub");
@@ -1445,6 +1411,8 @@ DEFUN (ospf_area_stub,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
+       /* Flush the external LSAs from the specified area */
+       ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
        ospf_area_no_summary_unset(ospf, area_id);
 
        return CMD_SUCCESS;
@@ -1567,6 +1535,8 @@ static int ospf_area_nssa_cmd_handler(struct vty *vty, int argc,
                        ospf_area_no_summary_unset(ospf, area_id);
        }
 
+       /* Flush the external LSA for the specified area */
+       ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_EXTERNAL_LSA);
        ospf_schedule_abr_task(ospf);
 
        return CMD_SUCCESS;
@@ -1672,6 +1642,8 @@ DEFUN (no_ospf_area_nssa,
        VTY_GET_OSPF_AREA_ID_NO_BB("NSSA", area_id, format,
                                   argv[idx_ipv4_number]->arg);
 
+       /* Flush the NSSA LSA for the specified area */
+       ospf_flush_lsa_from_area(ospf, area_id, OSPF_AS_NSSA_LSA);
        ospf_area_nssa_unset(ospf, area_id, argc);
 
        ospf_schedule_abr_task(ospf);
@@ -1717,8 +1689,8 @@ DEFUN (ospf_area_default_cost,
        p.prefixlen = 0;
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s",
-                       inet_ntoa(area->area_id));
+                       "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4",
+                       &area->area_id);
        ospf_abr_announce_network_to_area(&p, area->default_cost, area);
 
        return CMD_SUCCESS;
@@ -1760,8 +1732,8 @@ DEFUN (no_ospf_area_default_cost,
        p.prefixlen = 0;
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %s",
-                       inet_ntoa(area->area_id));
+                       "ospf_abr_announce_stub_defaults(): announcing 0.0.0.0/0 to area %pI4",
+                       &area->area_id);
        ospf_abr_announce_network_to_area(&p, area->default_cost, area);
 
 
@@ -2643,13 +2615,14 @@ static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area,
                              json_object *json_areas, bool use_json)
 {
        json_object *json_area = NULL;
+       char buf[PREFIX_STRLEN];
 
        if (use_json)
                json_area = json_object_new_object();
 
        /* Show Area ID. */
        if (!use_json)
-               vty_out(vty, " Area ID: %s", inet_ntoa(area->area_id));
+               vty_out(vty, " Area ID: %pI4", &area->area_id);
 
        /* Show Area type/mode. */
        if (OSPF_IS_AREA_BACKBONE(area)) {
@@ -2936,7 +2909,9 @@ static void show_ip_ospf_area(struct vty *vty, struct ospf_area *area,
        }
 
        if (use_json)
-               json_object_object_add(json_areas, inet_ntoa(area->area_id),
+               json_object_object_add(json_areas,
+                                      inet_ntop(AF_INET, &area->area_id,
+                                                buf, sizeof(buf)),
                                       json_area);
        else
                vty_out(vty, "\n");
@@ -2949,6 +2924,7 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
        struct ospf_area *area;
        struct timeval result;
        char timebuf[OSPF_TIME_DUMP_SIZE];
+       char buf[PREFIX_STRLEN];
        json_object *json_vrf = NULL;
        json_object *json_areas = NULL;
 
@@ -2974,10 +2950,11 @@ static int show_ip_ospf_common(struct vty *vty, struct ospf *ospf,
        /* Show Router ID. */
        if (json) {
                json_object_string_add(json_vrf, "routerId",
-                                      inet_ntoa(ospf->router_id));
+                                      inet_ntop(AF_INET, &ospf->router_id,
+                                                buf, sizeof(buf)));
        } else {
-               vty_out(vty, " OSPF Routing Process, Router ID: %s\n",
-                       inet_ntoa(ospf->router_id));
+               vty_out(vty, " OSPF Routing Process, Router ID: %pI4\n",
+                       &ospf->router_id);
        }
 
        /* Graceful shutdown */
@@ -3389,6 +3366,7 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
        int is_up;
        struct ospf_neighbor *nbr;
        struct route_node *rn;
+       char buf[PREFIX_STRLEN];
        uint32_t bandwidth = ifp->bandwidth ? ifp->bandwidth : ifp->speed;
 
        /* Is interface up? */
@@ -3460,14 +3438,15 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
                        if (use_json) {
                                json_object_string_add(
                                        json_interface_sub, "ipAddress",
-                                       inet_ntoa(oi->address->u.prefix4));
+                                       inet_ntop(AF_INET,
+                                                 &oi->address->u.prefix4,
+                                                 buf, sizeof(buf)));
                                json_object_int_add(json_interface_sub,
                                                    "ipAddressPrefixlen",
                                                    oi->address->prefixlen);
                        } else
-                               vty_out(vty, "  Internet Address %s/%d,",
-                                       inet_ntoa(oi->address->u.prefix4),
-                                       oi->address->prefixlen);
+                               vty_out(vty, "  Internet Address %pFX,",
+                                       oi->address);
 
                        /* For Vlinks, showing the peer address is
                         * probably more informative than the local
@@ -3494,15 +3473,17 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
                                        json_object_string_add(
                                                json_interface_sub,
                                                "vlinkPeer",
-                                               inet_ntoa(dest));
+                                               inet_ntop(AF_INET, &dest,
+                                                         buf, sizeof(buf)));
                                else
                                        json_object_string_add(
                                                json_interface_sub,
                                                "localIfUsed",
-                                               inet_ntoa(dest));
+                                               inet_ntop(AF_INET, &dest,
+                                                         buf, sizeof(buf)));
                        } else
-                               vty_out(vty, " %s %s,", dstr,
-                                       inet_ntoa(dest));
+                               vty_out(vty, " %s %pI4,", dstr,
+                                       &dest);
                }
                if (use_json) {
                        json_object_string_add(json_interface_sub, "area",
@@ -3511,8 +3492,10 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
                                json_object_boolean_true_add(
                                        json_interface_sub,
                                        "mtuMismatchDetect");
-                       json_object_string_add(json_interface_sub, "routerId",
-                                              inet_ntoa(ospf->router_id));
+                       json_object_string_add(
+                               json_interface_sub, "routerId",
+                               inet_ntop(AF_INET, &ospf->router_id,
+                                         buf, sizeof(buf)));
                        json_object_string_add(json_interface_sub,
                                               "networkType",
                                               ospf_network_type_str[oi->type]);
@@ -3535,8 +3518,8 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
                                                              : "enabled");
 
                        vty_out(vty,
-                               "  Router ID %s, Network Type %s, Cost: %d\n",
-                               inet_ntoa(ospf->router_id),
+                               "  Router ID %pI4, Network Type %s, Cost: %d\n",
+                               &ospf->router_id,
                                ospf_network_type_str[oi->type],
                                oi->output_cost);
 
@@ -3562,19 +3545,22 @@ static void show_ip_ospf_interface_sub(struct vty *vty, struct ospf *ospf,
                                if (use_json) {
                                        json_object_string_add(
                                                json_interface_sub, "bdrId",
-                                               inet_ntoa(nbr->router_id));
+                                               inet_ntop(AF_INET,
+                                                         &nbr->router_id,
+                                                         buf, sizeof(buf)));
                                        json_object_string_add(
                                                json_interface_sub,
                                                "bdrAddress",
-                                               inet_ntoa(nbr->address.u
-                                                                 .prefix4));
+                                               inet_ntop(AF_INET,
+                                                         &nbr->address.u
+                                                         .prefix4,
+                                                         buf, sizeof(buf)));
                                } else {
                                        vty_out(vty,
-                                               "  Backup Designated Router (ID) %s,",
-                                               inet_ntoa(nbr->router_id));
-                                       vty_out(vty, " Interface Address %s\n",
-                                               inet_ntoa(nbr->address.u
-                                                                 .prefix4));
+                                               "  Backup Designated Router (ID) %pI4,",
+                                               &nbr->router_id);
+                                       vty_out(vty, " Interface Address %pI4\n",
+                                               &nbr->address.u.prefix4);
                                }
                        }
                }
@@ -4174,6 +4160,7 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
        struct route_node *rn;
        struct ospf_neighbor *nbr, *prev_nbr = NULL;
        char msgbuf[16];
+       char buf[PREFIX_STRLEN];
        char timebuf[OSPF_TIME_DUMP_SIZE];
        json_object *json_neighbor = NULL, *json_neigh_array = NULL;
 
@@ -4200,9 +4187,8 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
                                        strlcpy(neigh_str, "neighbor",
                                                sizeof(neigh_str));
                                else
-                                       strlcpy(neigh_str,
-                                               inet_ntoa(nbr->router_id),
-                                               sizeof(neigh_str));
+                                       inet_ntop(AF_INET, &nbr->router_id,
+                                                 neigh_str, sizeof(neigh_str));
 
                                json_object_object_get_ex(json, neigh_str,
                                                          &json_neigh_array);
@@ -4234,8 +4220,10 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
                                json_object_int_add(json_neighbor,
                                                    "deadTimeMsecs",
                                                    time_store);
-                               json_object_string_add(json_neighbor, "address",
-                                                      inet_ntoa(nbr->src));
+                               json_object_string_add(
+                                       json_neighbor, "address",
+                                       inet_ntop(AF_INET, &nbr->src,
+                                                 buf, sizeof(buf)));
                                json_object_string_add(json_neighbor,
                                                       "ifaceName",
                                                       IF_NAME(oi));
@@ -4259,15 +4247,15 @@ static void show_ip_ospf_neighbor_sub(struct vty *vty,
                                        vty_out(vty, "%-15s %3d %-15s ", "-",
                                                nbr->priority, msgbuf);
                                else
-                                       vty_out(vty, "%-15s %3d %-15s ",
-                                               inet_ntoa(nbr->router_id),
+                                       vty_out(vty, "%-15pI4 %3d %-15s ",
+                                               &nbr->router_id,
                                                nbr->priority, msgbuf);
 
                                vty_out(vty, "%9s ",
                                        ospf_timer_dump(nbr->t_inactivity,
                                                        timebuf,
                                                        sizeof(timebuf)));
-                               vty_out(vty, "%-15s ", inet_ntoa(nbr->src));
+                               vty_out(vty, "%-15pI4 ", &nbr->src);
                                vty_out(vty, "%-32s %5ld %5ld %5d\n",
                                        IF_NAME(oi),
                                        ospf_ls_retransmit_count(nbr),
@@ -4470,6 +4458,7 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
 {
        struct listnode *node;
        struct ospf_interface *oi;
+       char buf[PREFIX_STRLEN];
        json_object *json_vrf = NULL;
        json_object *json_neighbor_sub = NULL;
 
@@ -4525,15 +4514,17 @@ static int show_ip_ospf_neighbor_all_common(struct vty *vty, struct ospf *ospf,
                                                "nbrNbmaDbSummaryCounter", 0);
                                        json_object_object_add(
                                                json_vrf,
-                                               inet_ntoa(nbr_nbma->addr),
+                                               inet_ntop(AF_INET,
+                                                         &nbr_nbma->addr, buf,
+                                                         sizeof(buf)),
                                                json_neighbor_sub);
                                } else {
                                        vty_out(vty, "%-15s %3d %-15s %9s ",
                                                "-", nbr_nbma->priority, "Down",
                                                "-");
                                        vty_out(vty,
-                                               "%-32s %-20s %5d %5d %5d\n",
-                                               inet_ntoa(nbr_nbma->addr),
+                                               "%-32pI4 %-20s %5d %5d %5d\n",
+                                               &nbr_nbma->addr,
                                                IF_NAME(oi), 0, 0, 0);
                                }
                        }
@@ -4815,6 +4806,7 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
                                             bool use_json, json_object *json)
 {
        char timebuf[OSPF_TIME_DUMP_SIZE];
+       char buf[PREFIX_STRLEN];
        json_object *json_sub = NULL;
 
        if (use_json)
@@ -4825,10 +4817,11 @@ static void show_ip_ospf_nbr_nbma_detail_sub(struct vty *vty,
        /* Show interface address. */
        if (use_json)
                json_object_string_add(json_sub, "ifaceAddress",
-                                      inet_ntoa(nbr_nbma->addr));
+                                      inet_ntop(AF_INET, &nbr_nbma->addr,
+                                                buf, sizeof(buf)));
        else
-               vty_out(vty, " interface address %s\n",
-                       inet_ntoa(nbr_nbma->addr));
+               vty_out(vty, " interface address %pI4\n",
+                       &nbr_nbma->addr);
 
        /* Show Area ID. */
        if (use_json) {
@@ -4898,6 +4891,7 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
        char timebuf[OSPF_TIME_DUMP_SIZE];
        json_object *json_neigh = NULL, *json_neigh_array = NULL;
        char neigh_str[INET_ADDRSTRLEN] = {0};
+       char buf[PREFIX_STRLEN];
 
        if (use_json) {
                if (prev_nbr &&
@@ -4909,8 +4903,8 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
                    && nbr->router_id.s_addr == INADDR_ANY)
                        strlcpy(neigh_str, "noNbrId", sizeof(neigh_str));
                else
-                       strlcpy(neigh_str, inet_ntoa(nbr->router_id),
-                               sizeof(neigh_str));
+                       inet_ntop(AF_INET, &nbr->router_id,
+                                 neigh_str, sizeof(neigh_str));
 
                json_object_object_get_ex(json, neigh_str, &json_neigh_array);
 
@@ -4928,17 +4922,19 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
                    && nbr->router_id.s_addr == INADDR_ANY)
                        vty_out(vty, " Neighbor %s,", "-");
                else
-                       vty_out(vty, " Neighbor %s,",
-                               inet_ntoa(nbr->router_id));
+                       vty_out(vty, " Neighbor %pI4,",
+                               &nbr->router_id);
        }
 
        /* Show interface address. */
        if (use_json)
                json_object_string_add(json_neigh, "ifaceAddress",
-                                      inet_ntoa(nbr->address.u.prefix4));
+                                      inet_ntop(AF_INET,
+                                                &nbr->address.u.prefix4,
+                                                buf, sizeof(buf)));
        else
-               vty_out(vty, " interface address %s\n",
-                       inet_ntoa(nbr->address.u.prefix4));
+               vty_out(vty, " interface address %pI4\n",
+                       &nbr->address.u.prefix4);
 
        /* Show Area ID. */
        if (use_json) {
@@ -5013,16 +5009,18 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
        /* Show Designated Rotuer ID. */
        if (use_json)
                json_object_string_add(json_neigh, "routerDesignatedId",
-                                      inet_ntoa(nbr->d_router));
+                                      inet_ntop(AF_INET, &nbr->d_router,
+                                                buf, sizeof(buf)));
        else
-               vty_out(vty, "    DR is %s,", inet_ntoa(nbr->d_router));
+               vty_out(vty, "    DR is %pI4,", &nbr->d_router);
 
        /* Show Backup Designated Rotuer ID. */
        if (use_json)
                json_object_string_add(json_neigh, "routerDesignatedBackupId",
-                                      inet_ntoa(nbr->bd_router));
+                                      inet_ntop(AF_INET, &nbr->bd_router,
+                                                buf, sizeof(buf)));
        else
-               vty_out(vty, " BDR is %s\n", inet_ntoa(nbr->bd_router));
+               vty_out(vty, " BDR is %pI4\n", &nbr->bd_router);
 
        /* Show options. */
        if (use_json) {
@@ -5121,6 +5119,68 @@ static void show_ip_ospf_neighbor_detail_sub(struct vty *vty,
                        "    Thread Link State Update Retransmission %s\n\n",
                        nbr->t_ls_upd != NULL ? "on" : "off");
 
+       if (!use_json) {
+               vty_out(vty, "    Graceful restart Helper info:\n");
+
+               if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) {
+                       vty_out(vty,
+                               "      Graceful Restart HELPER Status : Inprogress.\n");
+
+                       vty_out(vty,
+                               "      Graceful Restart grace period time: %d (seconds).\n",
+                               nbr->gr_helper_info.recvd_grace_period);
+                       vty_out(vty, "      Graceful Restart reason: %s.\n",
+                               ospf_restart_reason2str(
+                                       nbr->gr_helper_info.gr_restart_reason));
+               } else {
+                       vty_out(vty,
+                               "      Graceful Restart HELPER Status : None\n");
+               }
+
+               if (nbr->gr_helper_info.rejected_reason
+                   != OSPF_HELPER_REJECTED_NONE)
+                       vty_out(vty, "      Helper rejected reason: %s.\n",
+                               ospf_rejected_reason2str(
+                                       nbr->gr_helper_info.rejected_reason));
+
+               if (nbr->gr_helper_info.helper_exit_reason
+                   != OSPF_GR_HELPER_EXIT_NONE)
+                       vty_out(vty, "      Last helper exit reason: %s.\n\n",
+                               ospf_exit_reason2str(
+                                       nbr->gr_helper_info.helper_exit_reason));
+               else
+                       vty_out(vty, "\n");
+       } else {
+               json_object_string_add(json_neigh, "grHelperStatus",
+                                      OSPF_GR_IS_ACTIVE_HELPER(nbr) ?
+                                                       "Inprogress"
+                                                       : "None");
+               if (OSPF_GR_IS_ACTIVE_HELPER(nbr)) {
+                       json_object_int_add(
+                               json_neigh, "graceInterval",
+                               nbr->gr_helper_info.recvd_grace_period);
+                       json_object_string_add(
+                               json_neigh, "grRestartReason",
+                               ospf_restart_reason2str(
+                                       nbr->gr_helper_info.gr_restart_reason));
+               }
+
+               if (nbr->gr_helper_info.rejected_reason
+                   != OSPF_HELPER_REJECTED_NONE)
+                       json_object_string_add(
+                               json_neigh, "helperRejectReason",
+                               ospf_rejected_reason2str(
+                                       nbr->gr_helper_info.rejected_reason));
+
+               if (nbr->gr_helper_info.helper_exit_reason
+                   != OSPF_GR_HELPER_EXIT_NONE)
+                       json_object_string_add(
+                               json_neigh, "helperExitReason",
+                               ospf_exit_reason2str(
+                                       nbr->gr_helper_info
+                                                .helper_exit_reason));
+       }
+
        ospf_bfd_show_info(vty, nbr->bfd_info, json_neigh, use_json, 0);
 
        if (use_json)
@@ -5716,27 +5776,62 @@ DEFUN (show_ip_ospf_instance_neighbor_int_detail,
 }
 
 /* Show functions */
-static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self)
+static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self,
+                           json_object *json_lsa)
 {
        struct router_lsa *rl;
        struct summary_lsa *sl;
        struct as_external_lsa *asel;
        struct prefix_ipv4 p;
+       char buf[PREFIX2STR_BUFFER];
 
        if (lsa != NULL)
                /* If self option is set, check LSA self flag. */
                if (self == 0 || IS_LSA_SELF(lsa)) {
-                       /* LSA common part show. */
-                       vty_out(vty, "%-15s ", inet_ntoa(lsa->data->id));
-                       vty_out(vty, "%-15s %4d 0x%08lx 0x%04x",
-                               inet_ntoa(lsa->data->adv_router), LS_AGE(lsa),
-                               (unsigned long)ntohl(lsa->data->ls_seqnum),
-                               ntohs(lsa->data->checksum));
+
+                       if (!json_lsa) {
+                               /* LSA common part show. */
+                               vty_out(vty, "%-15pI4",
+                                       &lsa->data->id);
+                               vty_out(vty, "%-15s %4d 0x%08lx 0x%04x",
+                                       inet_ntoa(lsa->data->adv_router),
+                                       LS_AGE(lsa),
+                                       (unsigned long)ntohl(
+                                               lsa->data->ls_seqnum),
+                                       ntohs(lsa->data->checksum));
+                       } else {
+                               char seqnum[10];
+                               char checksum[10];
+
+                               snprintf(seqnum, sizeof(seqnum), "%x",
+                                        ntohl(lsa->data->ls_seqnum));
+                               snprintf(checksum, sizeof(checksum), "%x",
+                                        ntohs(lsa->data->checksum));
+                               json_object_string_add(
+                                       json_lsa, "lsId",
+                                       inet_ntoa(lsa->data->id));
+                               json_object_string_add(
+                                       json_lsa, "advertisedRouter",
+                                       inet_ntoa(lsa->data->adv_router));
+                               json_object_int_add(json_lsa, "lsaAge",
+                                                   LS_AGE(lsa));
+                               json_object_string_add(
+                                       json_lsa, "sequenceNumber", seqnum);
+                               json_object_string_add(json_lsa, "checksum",
+                                                      checksum);
+                       }
+
                        /* LSA specific part show. */
                        switch (lsa->data->type) {
                        case OSPF_ROUTER_LSA:
                                rl = (struct router_lsa *)lsa->data;
-                               vty_out(vty, " %-d", ntohs(rl->links));
+
+                               if (!json_lsa)
+                                       vty_out(vty, " %-d", ntohs(rl->links));
+                               else
+                                       json_object_int_add(json_lsa,
+                                                           "numOfRouterLinks",
+                                                           ntohs(rl->links));
                                break;
                        case OSPF_SUMMARY_LSA:
                                sl = (struct summary_lsa *)lsa->data;
@@ -5746,8 +5841,14 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self)
                                p.prefixlen = ip_masklen(sl->mask);
                                apply_mask_ipv4(&p);
 
-                               vty_out(vty, " %s/%d", inet_ntoa(p.prefix),
-                                       p.prefixlen);
+                               if (!json_lsa)
+                                       vty_out(vty, " %pFX", &p);
+                               else {
+                                       prefix2str(&p, buf, sizeof(buf));
+                                       json_object_string_add(json_lsa,
+                                                              "summaryAddress",
+                                                              buf);
+                               }
                                break;
                        case OSPF_AS_EXTERNAL_LSA:
                        case OSPF_AS_NSSA_LSA:
@@ -5758,13 +5859,30 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self)
                                p.prefixlen = ip_masklen(asel->mask);
                                apply_mask_ipv4(&p);
 
-                               vty_out(vty, " %s %s/%d [0x%lx]",
-                                       IS_EXTERNAL_METRIC(asel->e[0].tos)
-                                               ? "E2"
-                                               : "E1",
-                                       inet_ntoa(p.prefix), p.prefixlen,
-                                       (unsigned long)ntohl(
-                                               asel->e[0].route_tag));
+                               if (!json_lsa)
+                                       vty_out(vty, " %s %pFX [0x%lx]",
+                                               IS_EXTERNAL_METRIC(
+                                                       asel->e[0].tos)
+                                                       ? "E2"
+                                                       : "E1",
+                                               &p,
+                                               (unsigned long)ntohl(
+                                                       asel->e[0].route_tag));
+                               else {
+                                       prefix2str(&p, buf, sizeof(buf));
+                                       json_object_string_add(
+                                               json_lsa, "metricType",
+                                               IS_EXTERNAL_METRIC(
+                                                       asel->e[0].tos)
+                                                       ? "E2"
+                                                       : "E1");
+                                       json_object_string_add(json_lsa,
+                                                              "route", buf);
+                                       json_object_int_add(
+                                               json_lsa, "tag",
+                                               (unsigned long)ntohl(
+                                                       asel->e[0].route_tag));
+                               }
                                break;
                        case OSPF_NETWORK_LSA:
                        case OSPF_ASBR_SUMMARY_LSA:
@@ -5774,7 +5892,9 @@ static int show_lsa_summary(struct vty *vty, struct ospf_lsa *lsa, int self)
                        default:
                                break;
                        }
-                       vty_out(vty, "\n");
+
+                       if (!json_lsa)
+                               vty_out(vty, "\n");
                }
 
        return 0;
@@ -5795,6 +5915,21 @@ static const char *const show_database_desc[] = {
        "AS-external Opaque-LSA",
 };
 
+static const char * const show_database_desc_json[] = {
+       "unknown",
+       "routerLinkStates",
+       "networkLinkStates",
+       "summaryLinkStates",
+       "asbrSummaryLinkStates",
+       "asExternalLinkStates",
+       "groupMembershipLsa",
+       "nssaExternalLinkStates",
+       "type8Lsa",
+       "linkLocalOpaqueLsa",
+       "areaLocalOpaqueLsa",
+       "asExternalOpaqueLsa",
+};
+
 static const char *const show_database_header[] = {
        "",
        "Link ID         ADV Router      Age  Seq#       CkSum  Link count",
@@ -5810,41 +5945,97 @@ static const char *const show_database_header[] = {
        "Opaque-Type/Id  ADV Router      Age  Seq#       CkSum",
 };
 
-static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa)
+static void show_ip_ospf_database_header(struct vty *vty, struct ospf_lsa *lsa,
+                                        json_object *json)
 {
        struct router_lsa *rlsa = (struct router_lsa *)lsa->data;
 
-       vty_out(vty, "  LS age: %d\n", LS_AGE(lsa));
-       vty_out(vty, "  Options: 0x%-2x : %s\n", lsa->data->options,
-               ospf_options_dump(lsa->data->options));
-       vty_out(vty, "  LS Flags: 0x%-2x %s\n", lsa->flags,
-               ((lsa->flags & OSPF_LSA_LOCAL_XLT) ? "(Translated from Type-7)"
-                                                  : ""));
-
-       if (lsa->data->type == OSPF_ROUTER_LSA) {
-               vty_out(vty, "  Flags: 0x%x", rlsa->flags);
-
-               if (rlsa->flags)
-                       vty_out(vty, " :%s%s%s%s",
-                               IS_ROUTER_LSA_BORDER(rlsa) ? " ABR" : "",
-                               IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR" : "",
-                               IS_ROUTER_LSA_VIRTUAL(rlsa) ? " VL-endpoint"
-                                                           : "",
-                               IS_ROUTER_LSA_SHORTCUT(rlsa) ? " Shortcut"
-                                                            : "");
+       if (!json) {
+               vty_out(vty, "  LS age: %d\n", LS_AGE(lsa));
+               vty_out(vty, "  Options: 0x%-2x : %s\n", lsa->data->options,
+                       ospf_options_dump(lsa->data->options));
+               vty_out(vty, "  LS Flags: 0x%-2x %s\n", lsa->flags,
+                       ((lsa->flags & OSPF_LSA_LOCAL_XLT)
+                                ? "(Translated from Type-7)"
+                                : ""));
+
+               if (lsa->data->type == OSPF_ROUTER_LSA) {
+                       vty_out(vty, "  Flags: 0x%x", rlsa->flags);
+
+                       if (rlsa->flags)
+                               vty_out(vty, " :%s%s%s%s",
+                                       IS_ROUTER_LSA_BORDER(rlsa) ? " ABR"
+                                                                  : "",
+                                       IS_ROUTER_LSA_EXTERNAL(rlsa) ? " ASBR"
+                                                                    : "",
+                                       IS_ROUTER_LSA_VIRTUAL(rlsa)
+                                               ? " VL-endpoint"
+                                               : "",
+                                       IS_ROUTER_LSA_SHORTCUT(rlsa)
+                                               ? " Shortcut"
+                                               : "");
 
-               vty_out(vty, "\n");
+                       vty_out(vty, "\n");
+               }
+               vty_out(vty, "  LS Type: %s\n",
+                       lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL));
+               vty_out(vty, "  Link State ID: %pI4 %s\n",
+                       &lsa->data->id,
+                       lookup_msg(ospf_link_state_id_type_msg, lsa->data->type,
+                                  NULL));
+               vty_out(vty, "  Advertising Router: %pI4\n",
+                       &lsa->data->adv_router);
+               vty_out(vty, "  LS Seq Number: %08lx\n",
+                       (unsigned long)ntohl(lsa->data->ls_seqnum));
+               vty_out(vty, "  Checksum: 0x%04x\n",
+                       ntohs(lsa->data->checksum));
+               vty_out(vty, "  Length: %d\n\n", ntohs(lsa->data->length));
+       } else {
+               char seqnum[10];
+               char checksum[10];
+
+               snprintf(seqnum, 10, "%x", ntohl(lsa->data->ls_seqnum));
+               snprintf(checksum, 10, "%x", ntohs(lsa->data->checksum));
+
+               json_object_int_add(json, "lsaAge", LS_AGE(lsa));
+               json_object_string_add(json, "options",
+                                      ospf_options_dump(lsa->data->options));
+               json_object_int_add(json, "lsaFlags", lsa->flags);
+
+               if (lsa->flags & OSPF_LSA_LOCAL_XLT)
+                       json_object_boolean_true_add(json,
+                                                    "translatedFromType7");
+
+               if (lsa->data->type == OSPF_ROUTER_LSA) {
+                       json_object_int_add(json, "flags", rlsa->flags);
+
+                       if (rlsa->flags) {
+                               if (IS_ROUTER_LSA_BORDER(rlsa))
+                                       json_object_boolean_true_add(json,
+                                                                    "abr");
+                               if (IS_ROUTER_LSA_EXTERNAL(rlsa))
+                                       json_object_boolean_true_add(json,
+                                                                    "asbr");
+                               if (IS_ROUTER_LSA_VIRTUAL(rlsa))
+                                       json_object_boolean_true_add(
+                                               json, "vlEndpoint");
+                               if (IS_ROUTER_LSA_SHORTCUT(rlsa))
+                                       json_object_boolean_true_add(
+                                               json, "shortcut");
+                       }
+               }
+
+               json_object_string_add(
+                       json, "lsaType",
+                       lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL));
+               json_object_string_add(json, "linkStateId",
+                                      inet_ntoa(lsa->data->id));
+               json_object_string_add(json, "advertisingRouter",
+                                      inet_ntoa(lsa->data->adv_router));
+               json_object_string_add(json, "lsaSeqNumber", seqnum);
+               json_object_string_add(json, "checksum", checksum);
+               json_object_int_add(json, "length", ntohs(lsa->data->length));
        }
-       vty_out(vty, "  LS Type: %s\n",
-               lookup_msg(ospf_lsa_type_msg, lsa->data->type, NULL));
-       vty_out(vty, "  Link State ID: %s %s\n", inet_ntoa(lsa->data->id),
-               lookup_msg(ospf_link_state_id_type_msg, lsa->data->type, NULL));
-       vty_out(vty, "  Advertising Router: %s\n",
-               inet_ntoa(lsa->data->adv_router));
-       vty_out(vty, "  LS Seq Number: %08lx\n",
-               (unsigned long)ntohl(lsa->data->ls_seqnum));
-       vty_out(vty, "  Checksum: 0x%04x\n", ntohs(lsa->data->checksum));
-       vty_out(vty, "  Length: %d\n\n", ntohs(lsa->data->length));
 }
 
 static const char *const link_type_desc[] = {
@@ -5865,128 +6056,240 @@ static const char *const link_data_desc[] = {
        "Network Mask", "Router Interface address",
 };
 
+static const char *const link_id_desc_json[] = {
+       "null",           "neighborRouterId", "designatedRouterAddress",
+       "networkAddress", "neighborRouterId",
+};
+
+static const char *const link_data_desc_json[] = {
+       "null", "routerInterfaceAddress", "routerInterfaceAddress",
+       "networkMask", "routerInterfaceAddress",
+};
+
 /* Show router-LSA each Link information. */
 static void show_ip_ospf_database_router_links(struct vty *vty,
-                                              struct router_lsa *rl)
+                                              struct router_lsa *rl,
+                                              json_object *json)
 {
        int len, type;
-       unsigned int i;
+       unsigned short i;
+       json_object *json_links = NULL;
+       json_object *json_link = NULL;
+       int metric = 0;
+
+       if (json)
+               json_links = json_object_new_object();
 
        len = ntohs(rl->header.length) - 4;
        for (i = 0; i < ntohs(rl->links) && len > 0; len -= 12, i++) {
                type = rl->link[i].type;
 
-               vty_out(vty, "    Link connected to: %s\n",
-                       link_type_desc[type]);
-               vty_out(vty, "     (Link ID) %s: %s\n", link_id_desc[type],
-                       inet_ntoa(rl->link[i].link_id));
-               vty_out(vty, "     (Link Data) %s: %s\n", link_data_desc[type],
-                       inet_ntoa(rl->link[i].link_data));
-               vty_out(vty, "      Number of TOS metrics: 0\n");
-               vty_out(vty, "       TOS 0 Metric: %d\n",
-                       ntohs(rl->link[i].metric));
-               vty_out(vty, "\n");
+               if (json) {
+                       char link[16];
+
+                       snprintf(link, sizeof(link), "link%u", i);
+                       json_link = json_object_new_object();
+                       json_object_string_add(json_link, "linkType",
+                                              link_type_desc[type]);
+                       json_object_string_add(json_link,
+                                              link_id_desc_json[type],
+                                              inet_ntoa(rl->link[i].link_id));
+                       json_object_string_add(
+                               json_link, link_data_desc_json[type],
+                               inet_ntoa(rl->link[i].link_data));
+                       json_object_int_add(json_link, "numOfTosMetrics",
+                                           metric);
+                       json_object_int_add(json_link, "tos0Metric",
+                                           ntohs(rl->link[i].metric));
+                       json_object_object_add(json_links, link, json_link);
+               } else {
+                       vty_out(vty, "    Link connected to: %s\n",
+                               link_type_desc[type]);
+                       vty_out(vty, "     (Link ID) %s: %pI4\n",
+                               link_id_desc[type],
+                               &rl->link[i].link_id);
+                       vty_out(vty, "     (Link Data) %s: %pI4\n",
+                               link_data_desc[type],
+                               &rl->link[i].link_data);
+                       vty_out(vty, "      Number of TOS metrics: 0\n");
+                       vty_out(vty, "       TOS 0 Metric: %d\n",
+                               ntohs(rl->link[i].metric));
+                       vty_out(vty, "\n");
+               }
        }
+       if (json)
+               json_object_object_add(json, "routerLinks", json_links);
 }
 
 /* Show router-LSA detail information. */
-static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_router_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                 json_object *json)
 {
        if (lsa != NULL) {
                struct router_lsa *rl = (struct router_lsa *)lsa->data;
 
-               show_ip_ospf_database_header(vty, lsa);
+               show_ip_ospf_database_header(vty, lsa, json);
 
-               vty_out(vty, "   Number of Links: %d\n\n", ntohs(rl->links));
+               if (!json)
+                       vty_out(vty, "   Number of Links: %d\n\n",
+                               ntohs(rl->links));
+               else
+                       json_object_int_add(json, "numOfLinks",
+                                           ntohs(rl->links));
 
-               show_ip_ospf_database_router_links(vty, rl);
-               vty_out(vty, "\n");
+               show_ip_ospf_database_router_links(vty, rl, json);
+
+               if (!json)
+                       vty_out(vty, "\n");
        }
 
        return 0;
 }
 
 /* Show network-LSA detail information. */
-static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_network_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                  json_object *json)
 {
        int length, i;
+       json_object *json_attached_rt = NULL;
+       json_object *json_router = NULL;
+
+       if (json)
+               json_attached_rt = json_object_new_object();
 
        if (lsa != NULL) {
                struct network_lsa *nl = (struct network_lsa *)lsa->data;
 
-               show_ip_ospf_database_header(vty, lsa);
+               show_ip_ospf_database_header(vty, lsa, json);
 
-               vty_out(vty, "  Network Mask: /%d\n", ip_masklen(nl->mask));
+               if (!json)
+                       vty_out(vty, "  Network Mask: /%d\n",
+                               ip_masklen(nl->mask));
+               else
+                       json_object_int_add(json, "networkMask",
+                                           ip_masklen(nl->mask));
 
                length = ntohs(lsa->data->length) - OSPF_LSA_HEADER_SIZE - 4;
 
                for (i = 0; length > 0; i++, length -= 4)
-                       vty_out(vty, "        Attached Router: %s\n",
-                               inet_ntoa(nl->routers[i]));
-
-               vty_out(vty, "\n");
+                       if (!json) {
+                               vty_out(vty, "        Attached Router: %pI4\n",
+                                       &nl->routers[i]);
+                               vty_out(vty, "\n");
+                       } else {
+                               json_router = json_object_new_object();
+                               json_object_string_add(
+                                       json_router, "attachedRouterId",
+                                       inet_ntoa(nl->routers[i]));
+                               json_object_object_add(
+                                       json_attached_rt,
+                                       inet_ntoa(nl->routers[i]), json_router);
+                       }
        }
 
+       if (json)
+               json_object_object_add(json, "attchedRouters",
+                                      json_attached_rt);
+
        return 0;
 }
 
 /* Show summary-LSA detail information. */
-static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_summary_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                  json_object *json)
 {
        if (lsa != NULL) {
                struct summary_lsa *sl = (struct summary_lsa *)lsa->data;
 
-               show_ip_ospf_database_header(vty, lsa);
+               show_ip_ospf_database_header(vty, lsa, json);
 
-               vty_out(vty, "  Network Mask: /%d\n", ip_masklen(sl->mask));
-               vty_out(vty, "        TOS: 0  Metric: %d\n",
-                       GET_METRIC(sl->metric));
-               vty_out(vty, "\n");
+               if (!json) {
+                       vty_out(vty, "  Network Mask: /%d\n",
+                               ip_masklen(sl->mask));
+                       vty_out(vty, "        TOS: 0  Metric: %d\n",
+                               GET_METRIC(sl->metric));
+                       vty_out(vty, "\n");
+               } else {
+                       json_object_int_add(json, "networkMask",
+                                           ip_masklen(sl->mask));
+                       json_object_int_add(json, "tos0Metric",
+                                           GET_METRIC(sl->metric));
+               }
        }
 
        return 0;
 }
 
 /* Show summary-ASBR-LSA detail information. */
-static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_summary_asbr_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                       json_object *json)
 {
        if (lsa != NULL) {
                struct summary_lsa *sl = (struct summary_lsa *)lsa->data;
 
-               show_ip_ospf_database_header(vty, lsa);
+               show_ip_ospf_database_header(vty, lsa, json);
 
-               vty_out(vty, "  Network Mask: /%d\n", ip_masklen(sl->mask));
-               vty_out(vty, "        TOS: 0  Metric: %d\n",
-                       GET_METRIC(sl->metric));
-               vty_out(vty, "\n");
+               if (!json) {
+                       vty_out(vty, "  Network Mask: /%d\n",
+                               ip_masklen(sl->mask));
+                       vty_out(vty, "        TOS: 0  Metric: %d\n",
+                               GET_METRIC(sl->metric));
+                       vty_out(vty, "\n");
+               } else {
+                       json_object_int_add(json, "networkMask",
+                                           ip_masklen(sl->mask));
+                       json_object_int_add(json, "tos0Metric",
+                                           GET_METRIC(sl->metric));
+               }
        }
 
        return 0;
 }
 
 /* Show AS-external-LSA detail information. */
-static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_as_external_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                      json_object *json)
 {
+       int tos = 0;
+
        if (lsa != NULL) {
                struct as_external_lsa *al =
                        (struct as_external_lsa *)lsa->data;
 
-               show_ip_ospf_database_header(vty, lsa);
-
-               vty_out(vty, "  Network Mask: /%d\n", ip_masklen(al->mask));
-               vty_out(vty, "        Metric Type: %s\n",
-                       IS_EXTERNAL_METRIC(al->e[0].tos)
-                               ? "2 (Larger than any link state path)"
-                               : "1");
-               vty_out(vty, "        TOS: 0\n");
-               vty_out(vty, "        Metric: %d\n",
-                       GET_METRIC(al->e[0].metric));
-               vty_out(vty, "        Forward Address: %s\n",
-                       inet_ntoa(al->e[0].fwd_addr));
-
-               vty_out(vty,
-                       "        External Route Tag: %" ROUTE_TAG_PRI "\n\n",
-                       (route_tag_t)ntohl(al->e[0].route_tag));
+               show_ip_ospf_database_header(vty, lsa, json);
+
+               if (!json) {
+                       vty_out(vty, "  Network Mask: /%d\n",
+                               ip_masklen(al->mask));
+                       vty_out(vty, "        Metric Type: %s\n",
+                               IS_EXTERNAL_METRIC(al->e[0].tos)
+                                       ? "2 (Larger than any link state path)"
+                                       : "1");
+                       vty_out(vty, "        TOS: 0\n");
+                       vty_out(vty, "        Metric: %d\n",
+                               GET_METRIC(al->e[0].metric));
+                       vty_out(vty, "        Forward Address: %pI4\n",
+                               &al->e[0].fwd_addr);
+                       vty_out(vty,
+                               "        External Route Tag: %" ROUTE_TAG_PRI "\n\n",
+                               (route_tag_t)ntohl(al->e[0].route_tag));
+               } else {
+                       json_object_int_add(json, "networkMask",
+                                           ip_masklen(al->mask));
+                       json_object_string_add(
+                               json, "metricType",
+                               IS_EXTERNAL_METRIC(al->e[0].tos)
+                                       ? "E2 (Larger than any link state path)"
+                                       : "E1");
+                       json_object_int_add(json, "tos", tos);
+                       json_object_int_add(json, "metric",
+                                           GET_METRIC(al->e[0].metric));
+                       json_object_string_add(json, "forwardAddress",
+                                              inet_ntoa(al->e[0].fwd_addr));
+                       json_object_int_add(
+                               json, "externalRouteTag",
+                               (route_tag_t)ntohl(al->e[0].route_tag));
+               }
        }
 
        return 0;
@@ -6007,8 +6310,8 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
   zlog_debug( "        TOS: 0%s", "\n");
   zlog_debug( "        Metric: %d%s",
             GET_METRIC (al->e[0].metric), "\n");
-  zlog_debug( "        Forward Address: %s%s",
-            inet_ntoa (al->e[0].fwd_addr), "\n");
+  zlog_debug( "        Forward Address: %pI4%s",
+            &al->e[0].fwd_addr, "\n");
 
   zlog_debug( "        External Route Tag: %"ROUTE_TAG_PRI"%s%s",
             (route_tag_t)ntohl (al->e[0].route_tag), "\n", "\n");
@@ -6017,50 +6320,74 @@ show_as_external_lsa_stdvty (struct ospf_lsa *lsa)
 }
 #endif
 /* Show AS-NSSA-LSA detail information. */
-static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_as_nssa_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                  json_object *json)
 {
+       int tos = 0;
+
        if (lsa != NULL) {
                struct as_external_lsa *al =
                        (struct as_external_lsa *)lsa->data;
 
-               show_ip_ospf_database_header(vty, lsa);
-
-               vty_out(vty, "  Network Mask: /%d\n", ip_masklen(al->mask));
-               vty_out(vty, "        Metric Type: %s\n",
-                       IS_EXTERNAL_METRIC(al->e[0].tos)
-                               ? "2 (Larger than any link state path)"
-                               : "1");
-               vty_out(vty, "        TOS: 0\n");
-               vty_out(vty, "        Metric: %d\n",
-                       GET_METRIC(al->e[0].metric));
-               vty_out(vty, "        NSSA: Forward Address: %s\n",
-                       inet_ntoa(al->e[0].fwd_addr));
-
-               vty_out(vty,
-                       "        External Route Tag: %" ROUTE_TAG_PRI "\n\n",
-                       (route_tag_t)ntohl(al->e[0].route_tag));
+               show_ip_ospf_database_header(vty, lsa, json);
+
+               if (!json) {
+                       vty_out(vty, "  Network Mask: /%d\n",
+                               ip_masklen(al->mask));
+                       vty_out(vty, "        Metric Type: %s\n",
+                               IS_EXTERNAL_METRIC(al->e[0].tos)
+                                       ? "2 (Larger than any link state path)"
+                                       : "1");
+                       vty_out(vty, "        TOS: 0\n");
+                       vty_out(vty, "        Metric: %d\n",
+                               GET_METRIC(al->e[0].metric));
+                       vty_out(vty, "        NSSA: Forward Address: %pI4\n",
+                               &al->e[0].fwd_addr);
+                       vty_out(vty,
+                               "        External Route Tag: %" ROUTE_TAG_PRI
+                               "\n\n",
+                               (route_tag_t)ntohl(al->e[0].route_tag));
+               } else {
+                       json_object_int_add(json, "networkMask",
+                                           ip_masklen(al->mask));
+                       json_object_string_add(
+                               json, "metricType",
+                               IS_EXTERNAL_METRIC(al->e[0].tos)
+                                       ? "E2 (Larger than any link state path)"
+                                       : "E1");
+                       json_object_int_add(json, "tos", tos);
+                       json_object_int_add(json, "metric",
+                                           GET_METRIC(al->e[0].metric));
+                       json_object_string_add(json, "nssaForwardAddress",
+                                              inet_ntoa(al->e[0].fwd_addr));
+                       json_object_int_add(
+                               json, "externalRouteTag",
+                               (route_tag_t)ntohl(al->e[0].route_tag));
+               }
        }
 
        return 0;
 }
 
-static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa)
+static int show_func_dummy(struct vty *vty, struct ospf_lsa *lsa,
+                          json_object *json)
 {
        return 0;
 }
 
-static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa)
+static int show_opaque_lsa_detail(struct vty *vty, struct ospf_lsa *lsa,
+                                 json_object *json)
 {
        if (lsa != NULL) {
-               show_ip_ospf_database_header(vty, lsa);
-               show_opaque_info_detail(vty, lsa);
-
-               vty_out(vty, "\n");
+               show_ip_ospf_database_header(vty, lsa, json);
+               show_opaque_info_detail(vty, lsa, json);
+               if (!json)
+                       vty_out(vty, "\n");
        }
        return 0;
 }
 
-int (*const show_function[])(struct vty *, struct ospf_lsa *) = {
+int (*show_function[])(struct vty *, struct ospf_lsa *, json_object *) = {
        NULL,
        show_router_lsa_detail,
        show_network_lsa_detail,
@@ -6093,11 +6420,13 @@ static void show_lsa_prefix_set(struct vty *vty, struct prefix_ls *lp,
 }
 
 static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt,
-                                struct in_addr *id, struct in_addr *adv_router)
+                                struct in_addr *id, struct in_addr *adv_router,
+                                json_object *json)
 {
        struct prefix_ls lp;
        struct route_node *rn, *start;
        struct ospf_lsa *lsa;
+       json_object *json_lsa = NULL;
 
        show_lsa_prefix_set(vty, &lp, id, adv_router);
        start = route_node_get(rt, (struct prefix *)&lp);
@@ -6105,9 +6434,14 @@ static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt,
                route_lock_node(start);
                for (rn = start; rn; rn = route_next_until(rn, start))
                        if ((lsa = rn->info)) {
+                               if (json) {
+                                       json_lsa = json_object_new_object();
+                                       json_object_array_add(json, json_lsa);
+                               }
+
                                if (show_function[lsa->data->type] != NULL)
-                                       show_function[lsa->data->type](vty,
-                                                                      lsa);
+                                       show_function[lsa->data->type](
+                                               vty, lsa, json_lsa);
                        }
                route_unlock_node(start);
        }
@@ -6116,25 +6450,62 @@ static void show_lsa_detail_proc(struct vty *vty, struct route_table *rt,
 /* Show detail LSA information
    -- if id is NULL then show all LSAs. */
 static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type,
-                           struct in_addr *id, struct in_addr *adv_router)
+                           struct in_addr *id, struct in_addr *adv_router,
+                           json_object *json)
 {
        struct listnode *node;
        struct ospf_area *area;
+       json_object *json_lsa_type = NULL;
+       json_object *json_areas = NULL;
+       json_object *json_lsa_array = NULL;
+
+       if (json)
+               json_lsa_type = json_object_new_object();
 
        switch (type) {
        case OSPF_AS_EXTERNAL_LSA:
        case OSPF_OPAQUE_AS_LSA:
-               vty_out(vty, "                %s \n\n",
-                       show_database_desc[type]);
-               show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router);
+               if (!json)
+                       vty_out(vty, "                %s \n\n",
+                               show_database_desc[type]);
+               else
+                       json_lsa_array = json_object_new_array();
+
+               show_lsa_detail_proc(vty, AS_LSDB(ospf, type), id, adv_router,
+                                    json_lsa_array);
+               if (json)
+                       json_object_object_add(json,
+                                              show_database_desc_json[type],
+                                              json_lsa_array);
+
                break;
        default:
+               if (json)
+                       json_areas = json_object_new_object();
+
                for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
-                       vty_out(vty, "\n                %s (Area %s)\n\n",
-                               show_database_desc[type],
-                               ospf_area_desc_string(area));
+                       if (!json) {
+                               vty_out(vty,
+                                       "\n                %s (Area %s)\n\n",
+                                       show_database_desc[type],
+                                       ospf_area_desc_string(area));
+                       } else {
+                               json_lsa_array = json_object_new_array();
+                               json_object_object_add(json_areas,
+                                                      inet_ntoa(area->area_id),
+                                                      json_lsa_array);
+                       }
+
                        show_lsa_detail_proc(vty, AREA_LSDB(area, type), id,
-                                            adv_router);
+                                            adv_router, json_lsa_array);
+               }
+
+               if (json) {
+                       json_object_object_add(json_lsa_type, "areas",
+                                              json_areas);
+                       json_object_object_add(json,
+                                              show_database_desc_json[type],
+                                              json_lsa_type);
                }
                break;
        }
@@ -6142,60 +6513,104 @@ static void show_lsa_detail(struct vty *vty, struct ospf *ospf, int type,
 
 static void show_lsa_detail_adv_router_proc(struct vty *vty,
                                            struct route_table *rt,
-                                           struct in_addr *adv_router)
+                                           struct in_addr *adv_router,
+                                           json_object *json)
 {
        struct route_node *rn;
        struct ospf_lsa *lsa;
 
        for (rn = route_top(rt); rn; rn = route_next(rn))
-               if ((lsa = rn->info))
+               if ((lsa = rn->info)) {
+                       json_object *json_lsa = NULL;
+
                        if (IPV4_ADDR_SAME(adv_router,
                                           &lsa->data->adv_router)) {
                                if (CHECK_FLAG(lsa->flags, OSPF_LSA_LOCAL_XLT))
                                        continue;
+                               if (json)
+                                       json_lsa = json_object_new_object();
+
                                if (show_function[lsa->data->type] != NULL)
-                                       show_function[lsa->data->type](vty,
-                                                                      lsa);
+                                       show_function[lsa->data->type](
+                                               vty, lsa, json_lsa);
+                               if (json)
+                                       json_object_object_add(
+                                               json, inet_ntoa(lsa->data->id),
+                                               json_lsa);
                        }
+               }
 }
 
 /* Show detail LSA information. */
 static void show_lsa_detail_adv_router(struct vty *vty, struct ospf *ospf,
-                                      int type, struct in_addr *adv_router)
+                                      int type, struct in_addr *adv_router,
+                                      json_object *json)
 {
        struct listnode *node;
        struct ospf_area *area;
+       json_object *json_lstype = NULL;
+       json_object *json_area = NULL;
+
+       if (json)
+               json_lstype = json_object_new_object();
 
        switch (type) {
        case OSPF_AS_EXTERNAL_LSA:
        case OSPF_OPAQUE_AS_LSA:
-               vty_out(vty, "                %s \n\n",
-                       show_database_desc[type]);
+               if (!json)
+                       vty_out(vty, "                %s \n\n",
+                               show_database_desc[type]);
+
                show_lsa_detail_adv_router_proc(vty, AS_LSDB(ospf, type),
-                                               adv_router);
+                                               adv_router, json_lstype);
                break;
        default:
+
                for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
-                       vty_out(vty, "\n                %s (Area %s)\n\n",
-                               show_database_desc[type],
-                               ospf_area_desc_string(area));
-                       show_lsa_detail_adv_router_proc(
-                               vty, AREA_LSDB(area, type), adv_router);
+                       if (json)
+                               json_area = json_object_new_object();
+                       else
+                               vty_out(vty,
+                                       "\n                %s (Area %s)\n\n",
+                                       show_database_desc[type],
+                                       ospf_area_desc_string(area));
+                       show_lsa_detail_adv_router_proc(vty,
+                                                       AREA_LSDB(area, type),
+                                                       adv_router, json_area);
+
+                       if (json)
+                               json_object_object_add(json_lstype,
+                                                      inet_ntoa(area->area_id),
+                                                      json_area);
                }
                break;
        }
+
+       if (json)
+               json_object_object_add(json, show_database_desc[type],
+                                      json_lstype);
 }
 
 static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf,
-                                         int self)
+                                         int self, json_object *json)
 {
        struct ospf_lsa *lsa;
        struct route_node *rn;
        struct ospf_area *area;
        struct listnode *node;
+       json_object *json_areas = NULL;
+       json_object *json_area = NULL;
+       json_object *json_lsa = NULL;
        int type;
+       json_object *json_lsa_array = NULL;
+
+       if (json)
+               json_areas = json_object_new_object();
 
        for (ALL_LIST_ELEMENTS_RO(ospf->areas, node, area)) {
+               if (json)
+                       json_area = json_object_new_object();
+
                for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) {
                        switch (type) {
                        case OSPF_AS_EXTERNAL_LSA:
@@ -6207,20 +6622,49 @@ static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf,
                        if (ospf_lsdb_count_self(area->lsdb, type) > 0
                            || (!self
                                && ospf_lsdb_count(area->lsdb, type) > 0)) {
-                               vty_out(vty, "                %s (Area %s)\n\n",
-                                       show_database_desc[type],
-                                       ospf_area_desc_string(area));
-                               vty_out(vty, "%s\n",
-                                       show_database_header[type]);
 
-                               LSDB_LOOP (AREA_LSDB(area, type), rn, lsa)
-                                       show_lsa_summary(vty, lsa, self);
+                               if (!json) {
+                                       vty_out(vty,
+                                               "                %s (Area %s)\n\n",
+                                               show_database_desc[type],
+                                               ospf_area_desc_string(area));
+                                       vty_out(vty, "%s\n",
+                                               show_database_header[type]);
+                               } else {
+                                       json_lsa_array =
+                                               json_object_new_array();
+                                       json_object_object_add(
+                                               json_area,
+                                               show_database_desc_json[type],
+                                               json_lsa_array);
+                               }
 
-                               vty_out(vty, "\n");
+                               LSDB_LOOP (AREA_LSDB(area, type), rn, lsa) {
+                                       if (json) {
+                                               json_lsa =
+                                               json_object_new_object();
+                                               json_object_array_add(
+                                                       json_lsa_array,
+                                                       json_lsa);
+                                       }
+
+                                       show_lsa_summary(vty, lsa, self,
+                                                        json_lsa);
+                               }
+
+                               if (!json)
+                                       vty_out(vty, "\n");
                        }
                }
+               if (json)
+                       json_object_object_add(json_areas,
+                                              inet_ntoa(area->area_id),
+                                              json_area);
        }
 
+       if (json)
+               json_object_object_add(json, "areas", json_areas);
+
        for (type = OSPF_MIN_LSA; type < OSPF_MAX_LSA; type++) {
                switch (type) {
                case OSPF_AS_EXTERNAL_LSA:
@@ -6231,39 +6675,82 @@ static void show_ip_ospf_database_summary(struct vty *vty, struct ospf *ospf,
                }
                if (ospf_lsdb_count_self(ospf->lsdb, type)
                    || (!self && ospf_lsdb_count(ospf->lsdb, type))) {
-                       vty_out(vty, "                %s\n\n",
-                               show_database_desc[type]);
-                       vty_out(vty, "%s\n", show_database_header[type]);
+                       if (!json) {
+                               vty_out(vty, "                %s\n\n",
+                                       show_database_desc[type]);
+                               vty_out(vty, "%s\n",
+                                       show_database_header[type]);
+                       } else {
+                               json_lsa_array = json_object_new_array();
+                               json_object_object_add(
+                                       json, show_database_desc_json[type],
+                                       json_lsa_array);
+                       }
 
-                       LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa)
-                               show_lsa_summary(vty, lsa, self);
+                       LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa) {
+                               if (json) {
+                                       json_lsa = json_object_new_object();
+                                       json_object_array_add(json_lsa_array,
+                                                             json_lsa);
+                               }
 
-                       vty_out(vty, "\n");
+                               show_lsa_summary(vty, lsa, self, json_lsa);
+                       }
+
+                       if (!json)
+                               vty_out(vty, "\n");
                }
        }
 
-       vty_out(vty, "\n");
+       if (!json)
+               vty_out(vty, "\n");
 }
 
-static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf)
+static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf,
+                                        json_object *json)
 {
        struct route_node *rn;
+       json_object *json_maxage = NULL;
 
-       vty_out(vty, "\n                MaxAge Link States:\n\n");
+       if (!json)
+               vty_out(vty, "\n                MaxAge Link States:\n\n");
+       else
+               json_maxage = json_object_new_object();
 
        for (rn = route_top(ospf->maxage_lsa); rn; rn = route_next(rn)) {
                struct ospf_lsa *lsa;
+               json_object *json_lsa = NULL;
 
                if ((lsa = rn->info) != NULL) {
-                       vty_out(vty, "Link type: %d\n", lsa->data->type);
-                       vty_out(vty, "Link State ID: %s\n",
-                               inet_ntoa(lsa->data->id));
-                       vty_out(vty, "Advertising Router: %s\n",
-                               inet_ntoa(lsa->data->adv_router));
-                       vty_out(vty, "LSA lock count: %d\n", lsa->lock);
-                       vty_out(vty, "\n");
+                       if (!json) {
+                               vty_out(vty, "Link type: %d\n",
+                                       lsa->data->type);
+                               vty_out(vty, "Link State ID: %s\n",
+                                       inet_ntoa(lsa->data->id));
+                               vty_out(vty, "Advertising Router: %pI4\n",
+                                       &lsa->data->adv_router);
+                               vty_out(vty, "LSA lock count: %d\n", lsa->lock);
+                               vty_out(vty, "\n");
+                       } else {
+                               json_lsa = json_object_new_object();
+                               json_object_int_add(json_lsa, "linkType",
+                                                   lsa->data->type);
+                               json_object_string_add(
+                                       json_lsa, "linkStateId",
+                                       inet_ntoa(lsa->data->id));
+                               json_object_string_add(
+                                       json_lsa, "advertisingRouter",
+                                       inet_ntoa(lsa->data->adv_router));
+                               json_object_int_add(json_lsa, "lsaLockCount",
+                                                   lsa->lock);
+                               json_object_object_add(json_maxage,
+                                                      inet_ntoa(lsa->data->id),
+                                                      json_lsa);
+                       }
                }
        }
+       if (json)
+               json_object_object_add(json, "maxAgeLinkStates", json_maxage);
 }
 
 #define OSPF_LSA_TYPE_NSSA_DESC      "NSSA external link state\n"
@@ -6286,28 +6773,58 @@ static void show_ip_ospf_database_maxage(struct vty *vty, struct ospf *ospf)
 static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
                                        int arg_base, int argc,
                                        struct cmd_token **argv,
-                                       uint8_t use_vrf)
+                                       uint8_t use_vrf, json_object *json,
+                                       bool uj)
 {
        int idx_type = 4;
        int type, ret;
        struct in_addr id, adv_router;
+       json_object *json_vrf = NULL;
 
-       if (ospf->instance)
-               vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance);
-
-       ospf_show_vrf_name(ospf, vty, NULL, use_vrf);
-
-       vty_out(vty, "\n       OSPF Router with ID (%s)\n\n",
-               inet_ntoa(ospf->router_id));
+       if (uj) {
+               if (use_vrf)
+                       json_vrf = json_object_new_object();
+               else
+                       json_vrf = json;
+       }
 
-       /* Show all LSA. */
-       if (argc == arg_base + 4) {
-               show_ip_ospf_database_summary(vty, ospf, 0);
-               return CMD_SUCCESS;
+       if (ospf->instance) {
+               if (uj)
+                       json_object_int_add(json_vrf, "ospfInstance",
+                                           ospf->instance);
+               else
+                       vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
        }
 
-       /* Set database type to show. */
-       if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
+       ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
+
+       /* Show Router ID. */
+       if (uj) {
+               json_object_string_add(json_vrf, "routerId",
+                                      inet_ntoa(ospf->router_id));
+       } else {
+               vty_out(vty, "\n       OSPF Router with ID (%pI4)\n\n",
+                       &ospf->router_id);
+       }
+
+       /* Show all LSA. */
+       if ((argc == arg_base + 4) || (uj && (argc == arg_base + 5))) {
+               show_ip_ospf_database_summary(vty, ospf, 0, json_vrf);
+               if (json) {
+                       if (use_vrf) {
+                               if (ospf->vrf_id == VRF_DEFAULT)
+                                       json_object_object_add(json, "default",
+                                                              json_vrf);
+                               else
+                                       json_object_object_add(json, ospf->name,
+                                                              json_vrf);
+                       }
+               }
+               return CMD_SUCCESS;
+       }
+
+       /* Set database type to show. */
+       if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
                type = OSPF_ROUTER_LSA;
        else if (strncmp(argv[arg_base + idx_type]->text, "ne", 2) == 0)
                type = OSPF_NETWORK_LSA;
@@ -6320,10 +6837,30 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
        else if (strncmp(argv[arg_base + idx_type]->text, "e", 1) == 0)
                type = OSPF_AS_EXTERNAL_LSA;
        else if (strncmp(argv[arg_base + idx_type]->text, "se", 2) == 0) {
-               show_ip_ospf_database_summary(vty, ospf, 1);
+               show_ip_ospf_database_summary(vty, ospf, 1, json_vrf);
+               if (json) {
+                       if (use_vrf) {
+                               if (ospf->vrf_id == VRF_DEFAULT)
+                                       json_object_object_add(json, "default",
+                                                              json_vrf);
+                               else
+                                       json_object_object_add(json, ospf->name,
+                                                              json_vrf);
+                       }
+               }
                return CMD_SUCCESS;
        } else if (strncmp(argv[arg_base + idx_type]->text, "m", 1) == 0) {
-               show_ip_ospf_database_maxage(vty, ospf);
+               show_ip_ospf_database_maxage(vty, ospf, json_vrf);
+               if (json) {
+                       if (use_vrf) {
+                               if (ospf->vrf_id == VRF_DEFAULT)
+                                       json_object_object_add(json, "default",
+                                                              json_vrf);
+                               else
+                                       json_object_object_add(json, ospf->name,
+                                                              json_vrf);
+                       }
+               }
                return CMD_SUCCESS;
        } else if (strncmp(argv[arg_base + idx_type]->text, "opaque-l", 8) == 0)
                type = OSPF_OPAQUE_LINK_LSA;
@@ -6335,18 +6872,19 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
                return CMD_WARNING;
 
        /* `show ip ospf database LSA'. */
-       if (argc == arg_base + 5)
-               show_lsa_detail(vty, ospf, type, NULL, NULL);
+       if ((argc == arg_base + 5) || (uj && (argc == arg_base + 6)))
+               show_lsa_detail(vty, ospf, type, NULL, NULL, json_vrf);
        else if (argc >= arg_base + 6) {
                ret = inet_aton(argv[arg_base + 5]->arg, &id);
                if (!ret)
                        return CMD_WARNING;
 
                /* `show ip ospf database LSA ID'. */
-               if (argc == arg_base + 6)
-                       show_lsa_detail(vty, ospf, type, &id, NULL);
+               if ((argc == arg_base + 6) || (uj && (argc == arg_base + 7)))
+                       show_lsa_detail(vty, ospf, type, &id, NULL, json_vrf);
                /* `show ip ospf database LSA ID adv-router ADV_ROUTER'. */
-               else if (argc == arg_base + 7) {
+               else if ((argc == arg_base + 7)
+                        || (uj && (argc == arg_base + 8))) {
                        if (strncmp(argv[arg_base + 6]->text, "s", 1) == 0)
                                adv_router = ospf->router_id;
                        else {
@@ -6355,7 +6893,19 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
                                if (!ret)
                                        return CMD_WARNING;
                        }
-                       show_lsa_detail(vty, ospf, type, &id, &adv_router);
+                       show_lsa_detail(vty, ospf, type, &id, &adv_router,
+                                       json_vrf);
+               }
+       }
+
+       if (json) {
+               if (use_vrf) {
+                       if (ospf->vrf_id == VRF_DEFAULT)
+                               json_object_object_add(json, "default",
+                                                      json_vrf);
+                       else
+                               json_object_object_add(json, ospf->name,
+                                                      json_vrf);
                }
        }
 
@@ -6364,7 +6914,7 @@ static int show_ip_ospf_database_common(struct vty *vty, struct ospf *ospf,
 
 DEFUN (show_ip_ospf_database_max,
        show_ip_ospf_database_max_cmd,
-       "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
+       "show ip ospf [vrf <NAME|all>] database <max-age|self-originate> [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
@@ -6372,7 +6922,8 @@ DEFUN (show_ip_ospf_database_max,
        "All VRFs\n"
        "Database summary\n"
        "LSAs in MaxAge list\n"
-       "Self-originated link states\n")
+       "Self-originated link states\n"
+       JSON_STR)
 {
        struct ospf *ospf = NULL;
        struct listnode *node = NULL;
@@ -6382,6 +6933,11 @@ DEFUN (show_ip_ospf_database_max,
        int inst = 0;
        int idx_vrf = 0;
        uint8_t use_vrf = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
+
+       if (uj)
+               json = json_object_new_object();
 
        OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
 
@@ -6397,7 +6953,7 @@ DEFUN (show_ip_ospf_database_max,
                                ospf_output = true;
                                ret = show_ip_ospf_database_common(
                                        vty, ospf, idx_vrf ? 2 : 0, argc, argv,
-                                       use_vrf);
+                                       use_vrf, json, uj);
                        }
 
                        if (!ospf_output)
@@ -6409,8 +6965,8 @@ DEFUN (show_ip_ospf_database_max,
                                return CMD_SUCCESS;
                        }
                        ret = (show_ip_ospf_database_common(
-                               vty, ospf, idx_vrf ? 2 : 0, argc, argv,
-                               use_vrf));
+                               vty, ospf, idx_vrf ? 2 : 0, argc, argv, use_vrf,
+                               json, uj));
                }
        } else {
                /* Display default ospf (instance 0) info */
@@ -6421,7 +6977,12 @@ DEFUN (show_ip_ospf_database_max,
                }
 
                ret = show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
-                                                  use_vrf);
+                                                  use_vrf, json, uj);
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n", json_object_to_json_string(json));
+               json_object_free(json);
        }
 
        return ret;
@@ -6429,7 +6990,7 @@ DEFUN (show_ip_ospf_database_max,
 
 DEFUN (show_ip_ospf_instance_database,
        show_ip_ospf_instance_database_cmd,
-       "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]]",
+       "show ip ospf [{(1-65535)|vrf NAME}] database [<asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> [A.B.C.D [<self-originate|adv-router A.B.C.D>]]] [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
@@ -6440,7 +7001,8 @@ DEFUN (show_ip_ospf_instance_database,
        "Link State ID (as an IP address)\n"
        "Self-originated link states\n"
        "Advertising Router link states\n"
-       "Advertising Router (as an IP address)\n")
+       "Advertising Router (as an IP address)\n"
+       JSON_STR)
 {
        struct ospf *ospf;
        unsigned short instance = 0;
@@ -6451,6 +7013,11 @@ DEFUN (show_ip_ospf_instance_database,
        int inst = 0;
        int idx = 0;
        uint8_t use_vrf = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
+
+       if (uj)
+               json = json_object_new_object();
 
        if (argv_find(argv, argc, "(1-65535)", &idx)) {
                instance = strtoul(argv[idx]->arg, NULL, 10);
@@ -6460,8 +7027,8 @@ DEFUN (show_ip_ospf_instance_database,
                if (!ospf->oi_running)
                        return CMD_SUCCESS;
 
-               return (show_ip_ospf_database_common(vty, ospf, idx ? 1 : 0,
-                                                    argc, argv, use_vrf));
+               return (show_ip_ospf_database_common(
+                       vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj));
        } else if (argv_find(argv, argc, "vrf", &idx)) {
                vrf_name = argv[++idx]->arg;
                all_vrf = strmatch(vrf_name, "all");
@@ -6475,7 +7042,7 @@ DEFUN (show_ip_ospf_instance_database,
                                        continue;
                                ret = (show_ip_ospf_database_common(
                                        vty, ospf, idx ? 2 : 0, argc, argv,
-                                       use_vrf));
+                                       use_vrf, json, uj));
                        }
                } else {
                        ospf = ospf_lookup_by_inst_name(inst, vrf_name);
@@ -6485,7 +7052,8 @@ DEFUN (show_ip_ospf_instance_database,
                        }
 
                        ret = (show_ip_ospf_database_common(
-                               vty, ospf, idx ? 2 : 0, argc, argv, use_vrf));
+                               vty, ospf, idx ? 2 : 0, argc, argv, use_vrf,
+                               json, uj));
                }
        } else {
                /* Display default ospf (instance 0) info */
@@ -6496,7 +7064,12 @@ DEFUN (show_ip_ospf_instance_database,
                }
 
                ret = (show_ip_ospf_database_common(vty, ospf, 0, argc, argv,
-                                                   use_vrf));
+                                                   use_vrf, json, uj));
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n", json_object_to_json_string(json));
+               json_object_free(json);
        }
 
        return ret;
@@ -6504,18 +7077,24 @@ DEFUN (show_ip_ospf_instance_database,
 
 DEFUN (show_ip_ospf_instance_database_max,
        show_ip_ospf_instance_database_max_cmd,
-       "show ip ospf (1-65535) database <max-age|self-originate>",
+       "show ip ospf (1-65535) database <max-age|self-originate> [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
        "Instance ID\n"
        "Database summary\n"
        "LSAs in MaxAge list\n"
-       "Self-originated link states\n")
+       "Self-originated link states\n"
+       JSON_STR)
 {
        int idx_number = 3;
        struct ospf *ospf;
        unsigned short instance = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
+
+       if (uj)
+               json = json_object_new_object();
 
        instance = strtoul(argv[idx_number]->arg, NULL, 10);
 
@@ -6528,7 +7107,16 @@ DEFUN (show_ip_ospf_instance_database_max,
                return CMD_SUCCESS;
        }
 
-       return show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0);
+       show_ip_ospf_database_common(vty, ospf, 1, argc, argv, 0, json, uj);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
+
+       return CMD_SUCCESS;
 }
 
 
@@ -6536,19 +7124,40 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
                                                        struct ospf *ospf,
                                                        int arg_base, int argc,
                                                        struct cmd_token **argv,
-                                                       uint8_t use_vrf)
+                                                       uint8_t use_vrf,
+                                                       json_object *json,
+                                                       bool uj)
 {
        int idx_type = 4;
        int type, ret;
        struct in_addr adv_router;
+       json_object *json_vrf = NULL;
 
-       if (ospf->instance)
-               vty_out(vty, "\nOSPF Instance: %d\n", ospf->instance);
+       if (uj) {
+               if (use_vrf)
+                       json_vrf = json_object_new_object();
+               else
+                       json_vrf = json;
+       }
 
-       ospf_show_vrf_name(ospf, vty, NULL, use_vrf);
+       if (ospf->instance) {
+               if (uj)
+                       json_object_int_add(json, "ospfInstance",
+                                           ospf->instance);
+               else
+                       vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
+       }
+
+       ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
 
-       vty_out(vty, "\n       OSPF Router with ID (%s)\n\n",
-               inet_ntoa(ospf->router_id));
+       /* Show Router ID. */
+       if (uj) {
+               json_object_string_add(json_vrf, "routerId",
+                                      inet_ntoa(ospf->router_id));
+       } else {
+               vty_out(vty, "\n       OSPF Router with ID (%pI4)\n\n",
+                       &ospf->router_id);
+       }
 
        /* Set database type to show. */
        if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
@@ -6581,14 +7190,25 @@ static int show_ip_ospf_database_type_adv_router_common(struct vty *vty,
                        return CMD_WARNING;
        }
 
-       show_lsa_detail_adv_router(vty, ospf, type, &adv_router);
+       show_lsa_detail_adv_router(vty, ospf, type, &adv_router, json_vrf);
+
+       if (json) {
+               if (use_vrf) {
+                       if (ospf->vrf_id == VRF_DEFAULT)
+                               json_object_object_add(json, "default",
+                                                      json_vrf);
+                       else
+                               json_object_object_add(json, ospf->name,
+                                                      json_vrf);
+               }
+       }
 
        return CMD_SUCCESS;
 }
 
 DEFUN (show_ip_ospf_instance_database_type_adv_router,
        show_ip_ospf_instance_database_type_adv_router_cmd,
-       "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate>",
+       "show ip ospf [{(1-65535)|vrf NAME}] database <asbr-summary|external|network|router|summary|nssa-external|opaque-link|opaque-area|opaque-as> <adv-router A.B.C.D|self-originate> [json]",
        SHOW_STR
        IP_STR
        "OSPF information\n"
@@ -6598,7 +7218,8 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
        OSPF_LSA_TYPES_DESC
        "Advertising Router link states\n"
        "Advertising Router (as an IP address)\n"
-       "Self-originated link states\n")
+       "Self-originated link states\n"
+       JSON_STR)
 {
        struct ospf *ospf = NULL;
        unsigned short instance = 0;
@@ -6609,6 +7230,11 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
        int inst = 0;
        int idx = 0, idx_vrf = 0;
        uint8_t use_vrf = 0;
+       bool uj = use_json(argc, argv);
+       json_object *json = NULL;
+
+       if (uj)
+               json = json_object_new_object();
 
        if (argv_find(argv, argc, "(1-65535)", &idx)) {
                instance = strtoul(argv[idx]->arg, NULL, 10);
@@ -6621,7 +7247,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
                }
 
                return (show_ip_ospf_database_type_adv_router_common(
-                       vty, ospf, idx ? 1 : 0, argc, argv, use_vrf));
+                       vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj));
        }
 
        OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
@@ -6638,7 +7264,7 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
                                ospf_output = true;
                                ret = show_ip_ospf_database_type_adv_router_common(
                                        vty, ospf, idx ? 1 : 0, argc, argv,
-                                       use_vrf);
+                                       use_vrf, json, uj);
                        }
                        if (!ospf_output)
                                vty_out(vty, "%% OSPF instance not found\n");
@@ -6650,7 +7276,8 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
                        }
 
                        ret = show_ip_ospf_database_type_adv_router_common(
-                               vty, ospf, idx ? 1 : 0, argc, argv, use_vrf);
+                               vty, ospf, idx ? 1 : 0, argc, argv, use_vrf,
+                               json, uj);
                }
        } else {
                /* Display default ospf (instance 0) info */
@@ -6661,8 +7288,14 @@ DEFUN (show_ip_ospf_instance_database_type_adv_router,
                }
 
                ret = show_ip_ospf_database_type_adv_router_common(
-                       vty, ospf, idx ? 1 : 0, argc, argv, use_vrf);
+                       vty, ospf, idx ? 1 : 0, argc, argv, use_vrf, json, uj);
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n", json_object_to_json_string(json));
+               json_object_free(json);
        }
+
        return ret;
        /*return (show_ip_ospf_database_type_adv_router_common(
                vty, ospf, idx ? 1 : 0, argc, argv));*/
@@ -8057,6 +8690,7 @@ DEFUN (ip_ospf_area,
        struct ospf *ospf = NULL;
        unsigned short instance = 0;
        char *areaid;
+       uint32_t count = 0;
 
        if (argv_find(argv, argc, "(1-65535)", &idx))
                instance = strtol(argv[idx]->arg, NULL, 10);
@@ -8070,13 +8704,39 @@ DEFUN (ip_ospf_area,
                ospf = ospf_lookup_instance(instance);
 
        if (instance && ospf == NULL) {
+               /*
+                * At this point we know we have received
+                * an instance and there is no ospf instance
+                * associated with it.  This means we are
+                * in a situation where we have an
+                * ospf command that is setup for a different
+                * process(instance).  We need to safely
+                * remove the command from ourselves and
+                * allow the other instance(process) handle
+                * the configuration command.
+                */
+               count = 0;
+
                params = IF_DEF_PARAMS(ifp);
                if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
                        UNSET_IF_PARAM(params, if_area);
-                       ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
-                       ospf_interface_area_unset(ospf, ifp);
-                       ospf->if_ospf_cli_count--;
+                       count++;
+               }
+
+               for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
+                       if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
+                               UNSET_IF_PARAM(params, if_area);
+                               count++;
+                       }
+
+               if (count > 0) {
+                       ospf = ospf_lookup_by_vrf_id(ifp->vrf_id);
+                       if (ospf) {
+                               ospf_interface_area_unset(ospf, ifp);
+                               ospf->if_ospf_cli_count -= count;
+                       }
                }
+
                return CMD_NOT_MY_INSTANCE;
        }
 
@@ -8090,6 +8750,16 @@ DEFUN (ip_ospf_area,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
+       if (ospf) {
+               for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
+                       if (rn->info != NULL) {
+                               vty_out(vty,
+                                       "Please remove all network commands first.\n");
+                               return CMD_WARNING_CONFIG_FAILED;
+                       }
+               }
+       }
+
        params = IF_DEF_PARAMS(ifp);
        if (OSPF_IF_PARAM_CONFIGURED(params, if_area)
            && !IPV4_ADDR_SAME(&params->if_area, &area_id)) {
@@ -8109,22 +8779,12 @@ DEFUN (ip_ospf_area,
                params = ospf_get_if_params((ifp), (addr));
                if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) {
                        vty_out(vty,
-                               "Must remove previous area/address config before changing ospf area");
+                               "Must remove previous area/address config before changing ospf area\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
                ospf_if_update_params((ifp), (addr));
        }
 
-       if (ospf) {
-               for (rn = route_top(ospf->networks); rn; rn = route_next(rn)) {
-                       if (rn->info != NULL) {
-                               vty_out(vty,
-                                       "Please remove all network commands first.\n");
-                               return CMD_WARNING_CONFIG_FAILED;
-                       }
-               }
-       }
-
        /* enable ospf on this interface with area_id */
        if (params) {
                SET_IF_PARAM(params, if_area);
@@ -8167,7 +8827,7 @@ DEFUN (no_ip_ospf_area,
        else
                ospf = ospf_lookup_instance(instance);
 
-       if (ospf == NULL)
+       if (instance && ospf == NULL)
                return CMD_NOT_MY_INSTANCE;
 
        argv_find(argv, argc, "area", &idx);
@@ -8197,8 +8857,11 @@ DEFUN (no_ip_ospf_area,
                ospf_if_update_params((ifp), (addr));
        }
 
-       ospf_interface_area_unset(ospf, ifp);
-       ospf->if_ospf_cli_count--;
+       if (ospf) {
+               ospf_interface_area_unset(ospf, ifp);
+               ospf->if_ospf_cli_count--;
+       }
+
        return CMD_SUCCESS;
 }
 
@@ -8988,100 +9651,774 @@ DEFUN (no_ospf_proactive_arp,
        return CMD_SUCCESS;
 }
 
-static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
+/* Graceful Restart HELPER Commands */
+DEFPY(ospf_gr_helper_enable, ospf_gr_helper_enable_cmd,
+      "graceful-restart helper-only [A.B.C.D]",
+      "OSPF Graceful Restart\n"
+      "Enable Helper support\n"
+      "Advertising router id\n")
 {
-       struct listnode *ln;
-       struct ospf_area *area;
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       struct in_addr addr;
+       int ret;
 
-       if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED)
-               vty_out(vty, " max-metric router-lsa on-startup %u\n",
-                       ospf->stub_router_startup_time);
-       if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
-               vty_out(vty, " max-metric router-lsa on-shutdown %u\n",
-                       ospf->stub_router_shutdown_time);
-       for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
-               if (CHECK_FLAG(area->stub_router_state,
-                              OSPF_AREA_ADMIN_STUB_ROUTED)) {
-                       vty_out(vty, " max-metric router-lsa administrative\n");
-                       break;
+       if (argc == 3) {
+               ret = inet_aton(argv[2]->arg, &addr);
+               if (!ret) {
+                       vty_out(vty,
+                               "Please specify the valid routerid address.\n");
+                       return CMD_WARNING_CONFIG_FAILED;
                }
+
+               ospf_gr_helper_support_set_per_routerid(ospf, &addr, OSPF_GR_TRUE);
+               return CMD_SUCCESS;
        }
-       return;
+
+       ospf_gr_helper_support_set(ospf, OSPF_GR_TRUE);
+
+       return CMD_SUCCESS;
 }
 
-static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
-                                      struct route_table *rt,
-                                      json_object *json)
+DEFPY(no_ospf_gr_helper_enable,
+      no_ospf_gr_helper_enable_cmd,
+      "no graceful-restart helper-only [A.B.C.D]",
+      NO_STR
+      "OSPF Graceful Restart\n"
+      "Disable Helper support\n"
+      "Advertising router id\n")
 {
-       struct route_node *rn;
-       struct ospf_route * or ;
-       struct listnode *pnode, *pnnode;
-       struct ospf_path *path;
-       json_object *json_route = NULL, *json_nexthop_array = NULL,
-                   *json_nexthop = NULL;
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       struct in_addr addr;
+       int ret;
 
-       if (!json)
-               vty_out(vty,
-                       "============ OSPF network routing table ============\n");
+       if (argc == 4) {
+               ret = inet_aton(argv[3]->arg, &addr);
+               if (!ret) {
+                       vty_out(vty,
+                               "Please specify the valid routerid address.\n");
+                       return CMD_WARNING_CONFIG_FAILED;
+               }
 
-       for (rn = route_top(rt); rn; rn = route_next(rn)) {
-               if ((or = rn->info) == NULL)
-                       continue;
-               char buf1[PREFIX2STR_BUFFER];
+               ospf_gr_helper_support_set_per_routerid(ospf, &addr,
+                                                       OSPF_GR_FALSE);
+               return CMD_SUCCESS;
+       }
 
-               memset(buf1, 0, sizeof(buf1));
-               prefix2str(&rn->p, buf1, sizeof(buf1));
+       ospf_gr_helper_support_set(ospf, OSPF_GR_FALSE);
+       return CMD_SUCCESS;
+}
 
-               json_route = json_object_new_object();
-               if (json) {
-                       json_object_object_add(json, buf1, json_route);
-                       json_object_to_json_string_ext(
-                               json, JSON_C_TO_STRING_NOSLASHESCAPE);
-               }
+DEFPY(ospf_gr_helper_enable_lsacheck,
+      ospf_gr_helper_enable_lsacheck_cmd,
+      "graceful-restart helper strict-lsa-checking",
+      "OSPF Graceful Restart\n"
+      "OSPF GR Helper\n"
+      "Enable strict LSA check\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
 
-               switch (or->path_type) {
-               case OSPF_PATH_INTER_AREA:
-                       if (or->type == OSPF_DESTINATION_NETWORK) {
-                               if (json) {
-                                       json_object_string_add(json_route,
-                                                              "routeType",
-                                                              "N IA");
-                                       json_object_int_add(json_route, "cost",
-                                                           or->cost);
-                                       json_object_string_add(
-                                               json_route, "area",
-                                               inet_ntoa(or->u.std.area_id));
-                               } else {
-                                       vty_out(vty,
-                                               "N IA %-18s    [%d] area: %s\n",
-                                               buf1, or->cost,
-                                               inet_ntoa(or->u.std.area_id));
-                               }
-                       } else if (or->type == OSPF_DESTINATION_DISCARD) {
-                               if (json) {
-                                       json_object_string_add(json_route,
-                                                              "routeType",
-                                                              "D IA");
-                               } else {
-                                       vty_out(vty,
-                                               "D IA %-18s    Discard entry\n",
-                                               buf1);
-                               }
-                       }
-                       break;
-               case OSPF_PATH_INTRA_AREA:
-                       if (json) {
-                               json_object_string_add(json_route, "routeType",
-                                                      "N");
-                               json_object_int_add(json_route, "cost",
-                                                   or->cost);
-                               json_object_string_add(
-                                       json_route, "area",
-                                       inet_ntoa(or->u.std.area_id));
-                       } else {
-                               vty_out(vty, "N    %-18s    [%d] area: %s\n",
-                                       buf1, or->cost,
-                                       inet_ntoa(or->u.std.area_id));
+       ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_TRUE);
+       return CMD_SUCCESS;
+}
+
+DEFPY(no_ospf_gr_helper_enable_lsacheck,
+      no_ospf_gr_helper_enable_lsacheck_cmd,
+      "no graceful-restart helper strict-lsa-checking",
+      NO_STR
+      "OSPF Graceful Restart\n"
+      "OSPF GR Helper\n"
+      "Disable strict LSA check\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+
+       ospf_gr_helper_lsa_check_set(ospf, OSPF_GR_FALSE);
+       return CMD_SUCCESS;
+}
+
+DEFPY(ospf_gr_helper_supported_grace_time,
+      ospf_gr_helper_supported_grace_time_cmd,
+      "graceful-restart helper supported-grace-time (10-1800)$interval",
+      "OSPF Graceful Restart\n"
+      "OSPF GR Helper\n"
+      "Supported grace timer\n"
+      "Grace interval(in seconds)\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+
+       ospf_gr_helper_supported_gracetime_set(ospf, interval);
+       return CMD_SUCCESS;
+}
+
+DEFPY(no_ospf_gr_helper_supported_grace_time,
+      no_ospf_gr_helper_supported_grace_time_cmd,
+      "no graceful-restart helper supported-grace-time (10-1800)$interval",
+      NO_STR
+      "OSPF Graceful Restart\n"
+      "OSPF GR Helper\n"
+      "Supported grace timer\n"
+      "Grace interval(in seconds)\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+
+       ospf_gr_helper_supported_gracetime_set(ospf, OSPF_MAX_GRACE_INTERVAL);
+       return CMD_SUCCESS;
+}
+
+DEFPY(ospf_gr_helper_planned_only,
+      ospf_gr_helper_planned_only_cmd,
+      "graceful-restart helper planned-only",
+      "OSPF Graceful Restart\n"
+      "OSPF GR Helper\n"
+      "Supported only planned restart\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+
+       ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_TRUE);
+
+       return CMD_SUCCESS;
+}
+
+/* External Route Aggregation */
+DEFUN (ospf_external_route_aggregation,
+       ospf_external_route_aggregation_cmd,
+       "summary-address A.B.C.D/M [tag (1-4294967295)]",
+       "External summary address\n"
+       "Summary address prefix (a.b.c.d/m) \n"
+       "Router tag \n"
+       "Router tag value\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       struct prefix_ipv4 p;
+       int idx = 1;
+       route_tag_t tag = 0;
+       int ret = OSPF_SUCCESS;
+
+       str2prefix_ipv4(argv[idx]->arg, &p);
+
+       if (is_prefix_default(&p)) {
+               vty_out(vty,
+                       "Default address shouldn't be configured as summary address.\n");
+               return CMD_SUCCESS;
+       }
+
+       /* Apply mask for given prefix. */
+       apply_mask((struct prefix *)&p);
+
+       if (!is_valid_summary_addr(&p)) {
+               vty_out(vty, "Not a valid summary address.\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (argc > 2)
+               tag = strtoul(argv[idx + 2]->arg, NULL, 10);
+
+       ret = ospf_asbr_external_aggregator_set(ospf, &p, tag);
+       if (ret == OSPF_INVALID)
+               vty_out(vty, "Inavlid configuration!!\n");
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf_external_route_aggregation,
+       no_ospf_external_route_aggregation_cmd,
+       "no summary-address A.B.C.D/M [tag (1-4294967295)]",
+       NO_STR
+       "External summary address\n"
+       "Summary address prefix (a.b.c.d/m)\n"
+       "Router tag\n"
+       "Router tag value\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       struct prefix_ipv4 p;
+       int idx = 2;
+       route_tag_t tag = 0;
+       int ret = OSPF_SUCCESS;
+
+       str2prefix_ipv4(argv[idx]->arg, &p);
+
+       if (is_prefix_default(&p)) {
+               vty_out(vty,
+                       "Default address shouldn't be configured as summary address.\n");
+               return CMD_SUCCESS;
+       }
+
+       /* Apply mask for given prefix. */
+       apply_mask((struct prefix *)&p);
+
+       if (!is_valid_summary_addr(&p)) {
+               vty_out(vty, "Not a valid summary address.\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       if (argc > 3)
+               tag = strtoul(argv[idx + 2]->arg, NULL, 10);
+
+       ret = ospf_asbr_external_aggregator_unset(ospf, &p, tag);
+       if (ret == OSPF_INVALID)
+               vty_out(vty, "Inavlid configuration!!\n");
+
+       return CMD_SUCCESS;
+}
+
+DEFPY(no_ospf_gr_helper_planned_only,
+      no_ospf_gr_helper_planned_only_cmd,
+      "no graceful-restart helper planned-only",
+      NO_STR
+      "OSPF Graceful Restart\n"
+      "OSPF GR Helper\n"
+      "Supported only for planned restart\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+
+       ospf_gr_helper_set_supported_planned_only_restart(ospf, OSPF_GR_FALSE);
+
+       return CMD_SUCCESS;
+}
+
+static int ospf_print_vty_helper_dis_rtr_walkcb(struct hash_bucket *backet,
+                                               void *arg)
+{
+       struct advRtr *rtr = backet->data;
+       struct vty *vty = (struct vty *)arg;
+       static unsigned int count;
+
+       vty_out(vty, "%-6pI4,", &rtr->advRtrAddr);
+       count++;
+
+       if (count % 5 == 0)
+               vty_out(vty, "\n");
+
+       return HASHWALK_CONTINUE;
+}
+
+static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
+                                      uint8_t use_vrf, json_object *json,
+                                      bool uj, bool detail)
+{
+       struct listnode *node;
+       struct ospf_interface *oi;
+       char buf[PREFIX_STRLEN];
+       json_object *json_vrf = NULL;
+
+       if (uj) {
+               if (use_vrf)
+                       json_vrf = json_object_new_object();
+               else
+                       json_vrf = json;
+       }
+
+       if (ospf->instance) {
+               if (uj)
+                       json_object_int_add(json, "ospfInstance",
+                                           ospf->instance);
+               else
+                       vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
+       }
+
+       ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
+
+       if (uj) {
+               if (use_vrf) {
+                       if (ospf->vrf_id == VRF_DEFAULT)
+                               json_object_object_add(json, "default",
+                                                      json_vrf);
+                       else
+                               json_object_object_add(json, ospf->name,
+                                                      json_vrf);
+               }
+       } else
+               vty_out(vty, "\n");
+
+       /* Show Router ID. */
+       if (uj) {
+               json_object_string_add(json_vrf, "routerId",
+                                      inet_ntop(AF_INET, &ospf->router_id,
+                                                buf, sizeof(buf)));
+       } else {
+               vty_out(vty, "\n       OSPF Router with ID (%pI4)\n\n",
+                       &ospf->router_id);
+       }
+
+       if (!uj) {
+
+               if (ospf->is_helper_supported)
+                       vty_out(vty,
+                               " Graceful restart helper support enabled.\n");
+               else
+                       vty_out(vty,
+                               " Graceful restart helper support disabled.\n");
+
+               if (ospf->strict_lsa_check)
+                       vty_out(vty, " Strict LSA check is enabled.\n");
+               else
+                       vty_out(vty, " Strict LSA check is disabled.\n");
+
+               if (ospf->only_planned_restart)
+                       vty_out(vty,
+                               " Helper supported for planned restarts only.\n");
+               else
+                       vty_out(vty,
+                               " Helper supported for Planned and Unplanned Restarts.\n");
+
+               vty_out(vty,
+                       " Supported Graceful restart interval: %d(in seconds).\n",
+                       ospf->supported_grace_time);
+
+               if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
+                       vty_out(vty, " Enable Router list:\n");
+                       vty_out(vty, "   ");
+                       hash_walk(ospf->enable_rtr_list,
+                                 ospf_print_vty_helper_dis_rtr_walkcb, vty);
+                       vty_out(vty, "\n\n");
+               }
+
+               if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE) {
+                       vty_out(vty, " Last Helper exit Reason :%s\n",
+                               ospf_exit_reason2str(ospf->last_exit_reason));
+               }
+
+               if (ospf->active_restarter_cnt)
+                       vty_out(vty,
+                               " Number of Active neighbours in graceful restart: %d\n",
+                               ospf->active_restarter_cnt);
+               else
+                       vty_out(vty, "\n");
+
+       } else {
+               json_object_string_add(
+                       json_vrf, "helperSupport",
+                       (ospf->is_helper_supported) ? "Enabled" : "Disabled");
+               json_object_string_add(json_vrf, "strictLsaCheck",
+                                      (ospf->strict_lsa_check) ? "Enabled"
+                                                               : "Disabled");
+               json_object_string_add(
+                       json_vrf, "restartSupoort",
+                       (ospf->only_planned_restart)
+                               ? "Planned Restart only"
+                               : "Planned and Unplanned Restarts");
+
+               json_object_int_add(json_vrf, "supportedGracePeriod",
+                                   ospf->supported_grace_time);
+
+               if (ospf->last_exit_reason != OSPF_GR_HELPER_EXIT_NONE)
+                       json_object_string_add(
+                               json_vrf, "LastExitReason",
+                               ospf_exit_reason2str(ospf->last_exit_reason));
+
+               if (ospf->active_restarter_cnt)
+                       json_object_int_add(json_vrf, "activeRestarterCnt",
+                                           ospf->active_restarter_cnt);
+       }
+
+
+       if (detail) {
+               int cnt = 1;
+               json_object *json_neighbors = NULL;
+
+               for (ALL_LIST_ELEMENTS_RO(ospf->oiflist, node, oi)) {
+                       struct route_node *rn;
+                       struct ospf_neighbor *nbr;
+                       json_object *json_neigh;
+
+                       if (ospf_interface_neighbor_count(oi) == 0)
+                               continue;
+
+                       if (uj) {
+                               json_object_object_get_ex(json_vrf, "Neighbors",
+                                                         &json_neighbors);
+                               if (!json_neighbors) {
+                                       json_neighbors =
+                                               json_object_new_object();
+                                       json_object_object_add(json_vrf,
+                                                              "Neighbors",
+                                                              json_neighbors);
+                               }
+                       }
+
+                       for (rn = route_top(oi->nbrs); rn;
+                            rn = route_next(rn)) {
+
+                               if (!rn->info)
+                                       continue;
+
+                               nbr = rn->info;
+
+                               if (!OSPF_GR_IS_ACTIVE_HELPER(nbr))
+                                       continue;
+
+                               if (!uj) {
+                                       vty_out(vty, " Neighbour %d :\n", cnt);
+                                       vty_out(vty, "   Address  : %pI4\n",
+                                               &nbr->address.u.prefix4);
+                                       vty_out(vty, "   Routerid : %pI4\n",
+                                               &nbr->router_id);
+                                       vty_out(vty,
+                                               "   Received Grace period : %d(in seconds).\n",
+                                               nbr->gr_helper_info
+                                                       .recvd_grace_period);
+                                       vty_out(vty,
+                                               "   Actual Grace period : %d(in seconds)\n",
+                                               nbr->gr_helper_info
+                                                       .actual_grace_period);
+                                       vty_out(vty,
+                                               "   Remaining GraceTime:%ld(in seconds).\n",
+                                               thread_timer_remain_second(
+                                                       nbr->gr_helper_info
+                                                       .t_grace_timer));
+                                       vty_out(vty,
+                                               "   Graceful Restart reason: %s.\n\n",
+                                               ospf_restart_reason2str(
+                                                       nbr->gr_helper_info
+                                                       .gr_restart_reason));
+                                       cnt++;
+                               } else {
+                                       json_neigh = json_object_new_object();
+                                       json_object_string_add(
+                                               json_neigh, "srcAddr",
+                                               inet_ntop(AF_INET, &nbr->src,
+                                                         buf, sizeof(buf)));
+
+                                       json_object_string_add(
+                                               json_neigh, "routerid",
+                                               inet_ntop(AF_INET,
+                                                         &nbr->router_id,
+                                                         buf, sizeof(buf)));
+                                       json_object_int_add(
+                                               json_neigh,
+                                               "recvdGraceInterval",
+                                               nbr->gr_helper_info
+                                                       .recvd_grace_period);
+                                       json_object_int_add(
+                                               json_neigh,
+                                               "actualGraceInterval",
+                                               nbr->gr_helper_info
+                                                       .actual_grace_period);
+                                       json_object_int_add(
+                                               json_neigh, "remainGracetime",
+                                               thread_timer_remain_second(
+                                                       nbr->gr_helper_info
+                                                       .t_grace_timer));
+                                       json_object_string_add(
+                                               json_neigh, "restartReason",
+                                               ospf_restart_reason2str(
+                                                       nbr->gr_helper_info
+                                                       .gr_restart_reason));
+                                       json_object_object_add(
+                                               json_neighbors,
+                                               inet_ntop(AF_INET, &nbr->src,
+                                                         buf, sizeof(buf)),
+                                               json_neigh);
+                               }
+                       }
+               }
+       }
+       return CMD_SUCCESS;
+}
+
+DEFUN (ospf_external_route_aggregation_no_adrvertise,
+       ospf_external_route_aggregation_no_adrvertise_cmd,
+       "summary-address A.B.C.D/M no-advertise",
+       "External summary address\n"
+       "Summary address prefix (a.b.c.d/m) \n"
+       "Don't advertise summary route \n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       struct prefix_ipv4 p;
+       int idx = 1;
+       int ret = OSPF_SUCCESS;
+
+       str2prefix_ipv4(argv[idx]->arg, &p);
+
+       if (is_prefix_default(&p)) {
+               vty_out(vty,
+                       "Default address shouldn't be configured as summary address.\n");
+               return CMD_SUCCESS;
+       }
+
+       /* Apply mask for given prefix. */
+       apply_mask((struct prefix *)&p);
+
+       if (!is_valid_summary_addr(&p)) {
+               vty_out(vty, "Not a valid summary address.\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       ret = ospf_asbr_external_rt_no_advertise(ospf, &p);
+       if (ret == OSPF_INVALID)
+               vty_out(vty, "Inavlid configuration!!\n");
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (no_ospf_external_route_aggregation_no_adrvertise,
+       no_ospf_external_route_aggregation_no_adrvertise_cmd,
+       "no summary-address A.B.C.D/M no-advertise",
+       NO_STR
+       "External summary address\n"
+       "Summary address prefix (a.b.c.d/m) \n"
+       "Adverise summary route to the AS \n.")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       struct prefix_ipv4 p;
+       int idx = 2;
+       int ret = OSPF_SUCCESS;
+
+       str2prefix_ipv4(argv[idx]->arg, &p);
+
+       if (is_prefix_default(&p)) {
+               vty_out(vty,
+                       "Default address shouldn't be configured as summary address.\n");
+               return CMD_SUCCESS;
+       }
+
+       /* Apply mask for given prefix. */
+       apply_mask((struct prefix *)&p);
+
+       if (!is_valid_summary_addr(&p)) {
+               vty_out(vty, "Not a valid summary address.\n");
+               return CMD_WARNING_CONFIG_FAILED;
+       }
+
+       ret = ospf_asbr_external_rt_advertise(ospf, &p);
+       if (ret == OSPF_INVALID)
+               vty_out(vty, "Inavlid configuration!!\n");
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (ospf_route_aggregation_timer,
+       ospf_route_aggregation_timer_cmd,
+       "aggregation timer (5-1800)",
+       "External route aggregation\n"
+       "Delay timer (in seconds)\n"
+       "Timer interval(in seconds)\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+       unsigned int interval = 0;
+
+       interval = strtoul(argv[2]->arg, NULL, 10);
+
+       ospf_external_aggregator_timer_set(ospf, interval);
+
+       return CMD_SUCCESS;
+}
+
+DEFPY (show_ip_ospf_gr_helper,
+       show_ip_ospf_gr_helper_cmd,
+       "show ip ospf [vrf <NAME|all>] graceful-restart helper [detail] [json]",
+       SHOW_STR
+       IP_STR
+       "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
+       "OSPF Graceful Restart\n"
+       "Helper details in the router\n"
+       "Detailed informtion\n"
+       JSON_STR)
+{
+       char *vrf_name = NULL;
+       bool all_vrf = false;
+       int ret = CMD_SUCCESS;
+       int idx_vrf = 0;
+       int idx = 0;
+       uint8_t use_vrf = 0;
+       bool uj = use_json(argc, argv);
+       struct ospf *ospf = NULL;
+       json_object *json = NULL;
+       struct listnode *node = NULL;
+       int inst = 0;
+       bool detail = false;
+
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+       if (argv_find(argv, argc, "detail", &idx))
+               detail = true;
+
+       if (uj)
+               json = json_object_new_object();
+
+       /* vrf input is provided */
+       if (vrf_name) {
+               use_vrf = 1;
+
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+
+                               ret = ospf_show_gr_helper_details(
+                                       vty, ospf, use_vrf, json, uj, detail);
+                       }
+
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       }
+
+                       return ret;
+               }
+
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+
+               if (ospf == NULL || !ospf->oi_running) {
+
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
+                       return CMD_SUCCESS;
+               }
+
+       } else {
+               /* Default Vrf */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+
+               if (ospf == NULL || !ospf->oi_running) {
+
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
+                       return CMD_SUCCESS;
+               }
+
+               ospf_show_gr_helper_details(vty, ospf, use_vrf, json, uj,
+                                           detail);
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
+
+       return CMD_SUCCESS;
+}
+/* Graceful Restart HELPER commands end */
+DEFUN (no_ospf_route_aggregation_timer,
+       no_ospf_route_aggregation_timer_cmd,
+       "no aggregation timer",
+       NO_STR
+       "External route aggregation\n"
+       "Delay timer\n")
+{
+       VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
+
+       ospf_external_aggregator_timer_set(ospf, OSPF_EXTL_AGGR_DEFAULT_DELAY);
+
+       return CMD_SUCCESS;
+}
+
+/* External Route Aggregation End */
+
+static void config_write_stub_router(struct vty *vty, struct ospf *ospf)
+{
+       struct listnode *ln;
+       struct ospf_area *area;
+
+       if (ospf->stub_router_startup_time != OSPF_STUB_ROUTER_UNCONFIGURED)
+               vty_out(vty, " max-metric router-lsa on-startup %u\n",
+                       ospf->stub_router_startup_time);
+       if (ospf->stub_router_shutdown_time != OSPF_STUB_ROUTER_UNCONFIGURED)
+               vty_out(vty, " max-metric router-lsa on-shutdown %u\n",
+                       ospf->stub_router_shutdown_time);
+       for (ALL_LIST_ELEMENTS_RO(ospf->areas, ln, area)) {
+               if (CHECK_FLAG(area->stub_router_state,
+                              OSPF_AREA_ADMIN_STUB_ROUTED)) {
+                       vty_out(vty, " max-metric router-lsa administrative\n");
+                       break;
+               }
+       }
+       return;
+}
+
+static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
+                                      struct route_table *rt,
+                                      json_object *json)
+{
+       struct route_node *rn;
+       struct ospf_route * or ;
+       struct listnode *pnode, *pnnode;
+       struct ospf_path *path;
+       char buf[PREFIX_STRLEN];
+       json_object *json_route = NULL, *json_nexthop_array = NULL,
+                   *json_nexthop = NULL;
+
+       if (!json)
+               vty_out(vty,
+                       "============ OSPF network routing table ============\n");
+
+       for (rn = route_top(rt); rn; rn = route_next(rn)) {
+               char buf1[PREFIX2STR_BUFFER];
+
+               if ((or = rn->info) == NULL)
+                       continue;
+
+               prefix2str(&rn->p, buf1, sizeof(buf1));
+
+               json_route = json_object_new_object();
+               if (json) {
+                       json_object_object_add(json, buf1, json_route);
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_NOSLASHESCAPE);
+               }
+
+               switch (or->path_type) {
+               case OSPF_PATH_INTER_AREA:
+                       if (or->type == OSPF_DESTINATION_NETWORK) {
+                               if (json) {
+                                       json_object_string_add(json_route,
+                                                              "routeType",
+                                                              "N IA");
+                                       json_object_int_add(json_route, "cost",
+                                                           or->cost);
+                                       json_object_string_add(
+                                               json_route, "area",
+                                               inet_ntop(AF_INET,
+                                                         &or->u.std.area_id,
+                                                         buf1, sizeof(buf1)));
+                               } else {
+                                       vty_out(vty,
+                                               "N IA %-18s    [%d] area: %pI4\n",
+                                               buf1, or->cost,
+                                               &or->u.std.area_id);
+                               }
+                       } else if (or->type == OSPF_DESTINATION_DISCARD) {
+                               if (json) {
+                                       json_object_string_add(json_route,
+                                                              "routeType",
+                                                              "D IA");
+                               } else {
+                                       vty_out(vty,
+                                               "D IA %-18s    Discard entry\n",
+                                               buf1);
+                               }
+                       }
+                       break;
+               case OSPF_PATH_INTRA_AREA:
+                       if (json) {
+                               json_object_string_add(json_route, "routeType",
+                                                      "N");
+                               json_object_int_add(json_route, "cost",
+                                                   or->cost);
+                               json_object_string_add(
+                                       json_route, "area",
+                                       inet_ntop(AF_INET, &or->u.std.area_id,
+                                                 buf1, sizeof(buf1)));
+                       } else {
+                               vty_out(vty, "N    %-18s    [%d] area: %pI4\n",
+                                       buf1, or->cost,
+                                       &or->u.std.area_id);
                        }
                        break;
                default:
@@ -9130,8 +10467,11 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
                                                        json_object_string_add(
                                                                json_nexthop,
                                                                "ip",
-                                                               inet_ntoa(
-                                                                       path->nexthop));
+                                                               inet_ntop(
+                                                                       AF_INET,
+                                                                       &path->nexthop,
+                                                                       buf,
+                                                                       sizeof(buf)));
                                                        json_object_string_add(
                                                                json_nexthop,
                                                                "via",
@@ -9140,10 +10480,9 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
                                                                        ospf->vrf_id));
                                                } else {
                                                        vty_out(vty,
-                                                               "%24s   via %s, %s\n",
+                                                               "%24s   via %pI4, %s\n",
                                                                "",
-                                                               inet_ntoa(
-                                                                       path->nexthop),
+                                                               &path->nexthop,
                                                                ifindex2ifname(
                                                                        path->ifindex,
                                                                        ospf->vrf_id));
@@ -9168,6 +10507,7 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
        struct listnode *pnode;
        struct listnode *node;
        struct ospf_path *path;
+       char buf[PREFIX_STRLEN];
        json_object *json_route = NULL, *json_nexthop_array = NULL,
                    *json_nexthop = NULL;
 
@@ -9182,12 +10522,14 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
 
                json_route = json_object_new_object();
                if (json) {
-                       json_object_object_add(json, inet_ntoa(rn->p.u.prefix4),
-                                              json_route);
+                       json_object_object_add(
+                               json, inet_ntop(AF_INET, &rn->p.u.prefix4,
+                                               buf, sizeof(buf)),
+                               json_route);
                        json_object_string_add(json_route, "routeType", "R ");
                } else {
-                       vty_out(vty, "R    %-15s    ",
-                               inet_ntoa(rn->p.u.prefix4));
+                       vty_out(vty, "R    %-15pI4    ",
+                               &rn->p.u.prefix4);
                }
 
                for (ALL_LIST_ELEMENTS_RO((struct list *)rn->info, node, or)) {
@@ -9202,7 +10544,8 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
                                                    or->cost);
                                json_object_string_add(
                                        json_route, "area",
-                                       inet_ntoa(or->u.std.area_id));
+                                       inet_ntop(AF_INET, &or->u.std.area_id,
+                                                 buf, sizeof(buf)));
                                if (or->path_type == OSPF_PATH_INTER_AREA)
                                        json_object_boolean_true_add(json_route,
                                                                     "IA");
@@ -9215,11 +10558,11 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
                                                               "routerType",
                                                               "asbr");
                        } else {
-                               vty_out(vty, "%s [%d] area: %s",
+                               vty_out(vty, "%s [%d] area: %pI4",
                                        (or->path_type == OSPF_PATH_INTER_AREA
                                                 ? "IA"
                                                 : "  "),
-                                       or->cost, inet_ntoa(or->u.std.area_id));
+                                       or->cost, &or->u.std.area_id);
                                /* Show flags. */
                                vty_out(vty, "%s%s\n",
                                        (or->u.std.flags & ROUTER_LSA_BORDER
@@ -9269,8 +10612,10 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
                                                        json_object_string_add(
                                                                json_nexthop,
                                                                "ip",
-                                                               inet_ntoa(
-                                                                       path->nexthop));
+                                                               inet_ntop(
+                                                                       AF_INET,
+                                                                       &path->nexthop,
+                                                                       buf, sizeof(buf)));
                                                        json_object_string_add(
                                                                json_nexthop,
                                                                "via",
@@ -9279,10 +10624,9 @@ static void show_ip_ospf_route_router(struct vty *vty, struct ospf *ospf,
                                                                        ospf->vrf_id));
                                                } else {
                                                        vty_out(vty,
-                                                               "%24s   via %s, %s\n",
+                                                               "%24s   via %pI4, %s\n",
                                                                "",
-                                                               inet_ntoa(
-                                                                       path->nexthop),
+                                                               &path->nexthop,
                                                                ifindex2ifname(
                                                                        path->ifindex,
                                                                        ospf->vrf_id));
@@ -9306,6 +10650,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
        struct ospf_route *er;
        struct listnode *pnode, *pnnode;
        struct ospf_path *path;
+       char buf[PREFIX_STRLEN];
        json_object *json_route = NULL, *json_nexthop_array = NULL,
                    *json_nexthop = NULL;
 
@@ -9319,8 +10664,7 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
 
                char buf1[19];
 
-               snprintf(buf1, sizeof(buf1), "%s/%d",
-                        inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen);
+               snprintfrr(buf1, sizeof(buf1), "%pFX", &rn->p);
                json_route = json_object_new_object();
                if (json) {
                        json_object_object_add(json, buf1, json_route);
@@ -9395,8 +10739,11 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
                                        if (json) {
                                                json_object_string_add(
                                                        json_nexthop, "ip",
-                                                       inet_ntoa(
-                                                               path->nexthop));
+                                                       inet_ntop(
+                                                               AF_INET,
+                                                               &path->nexthop,
+                                                               buf,
+                                                               sizeof(buf)));
                                                json_object_string_add(
                                                        json_nexthop, "via",
                                                        ifindex2ifname(
@@ -9404,10 +10751,9 @@ static void show_ip_ospf_route_external(struct vty *vty, struct ospf *ospf,
                                                                ospf->vrf_id));
                                        } else {
                                                vty_out(vty,
-                                                       "%24s   via %s, %s\n",
+                                                       "%24s   via %pI4, %s\n",
                                                        "",
-                                                       inet_ntoa(
-                                                               path->nexthop),
+                                                       &path->nexthop,
                                                        ifindex2ifname(
                                                                path->ifindex,
                                                                ospf->vrf_id));
@@ -9717,6 +11063,7 @@ DEFUN (show_ip_ospf_vrfs,
        struct ospf *ospf = NULL;
        struct listnode *node = NULL;
        int count = 0;
+       char buf[PREFIX_STRLEN];
        static const char header[] = "Name                       Id     RouterId  ";
 
        if (uj) {
@@ -9747,14 +11094,16 @@ DEFUN (show_ip_ospf_vrfs,
 
                if (uj) {
                        json_object_int_add(json_vrf, "vrfId", vrf_id_ui);
-                       json_object_string_add(json_vrf, "routerId",
-                                              inet_ntoa(ospf->router_id));
+                       json_object_string_add(
+                               json_vrf, "routerId",
+                               inet_ntop(AF_INET, &ospf->router_id,
+                                         buf, sizeof(buf)));
 
                        json_object_object_add(json_vrfs, name, json_vrf);
 
                } else {
-                       vty_out(vty, "%-25s  %-5d  %-16s  \n", name,
-                               ospf->vrf_id, inet_ntoa(ospf->router_id));
+                       vty_out(vty, "%-25s  %-5d  %-16pI4  \n", name,
+                               ospf->vrf_id, &ospf->router_id);
                }
        }
 
@@ -9781,6 +11130,264 @@ static const char *const ospf_abr_type_str[] = {
 static const char *const ospf_shortcut_mode_str[] = {
        "default", "enable", "disable"
 };
+static int ospf_vty_external_rt_walkcb(struct hash_bucket *backet,
+                                       void *arg)
+{
+       struct external_info *ei = backet->data;
+       struct vty *vty = (struct vty *)arg;
+       static unsigned int count;
+
+       vty_out(vty, "%-4pI4/%d, ", &ei->p.prefix, ei->p.prefixlen);
+       count++;
+
+       if (count % 5 == 0)
+               vty_out(vty, "\n");
+
+       if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count)
+               count = 0;
+
+       return HASHWALK_CONTINUE;
+}
+
+static int ospf_json_external_rt_walkcb(struct hash_bucket *backet,
+                                       void *arg)
+{
+       struct external_info *ei = backet->data;
+       struct json_object *json = (struct json_object *)arg;
+       char buf[PREFIX2STR_BUFFER];
+       char exnalbuf[20];
+       static unsigned int count;
+
+       prefix2str(&ei->p, buf, sizeof(buf));
+
+       snprintf(exnalbuf, 20, "Exnl Addr-%d", count);
+
+       json_object_string_add(json, exnalbuf, buf);
+
+       count++;
+
+       if (OSPF_EXTERNAL_RT_COUNT(ei->aggr_route) == count)
+               count = 0;
+
+       return HASHWALK_CONTINUE;
+}
+
+static int ospf_show_summary_address(struct vty *vty, struct ospf *ospf,
+                                    uint8_t use_vrf, json_object *json,
+                                    bool uj, bool detail)
+{
+       struct route_node *rn;
+       json_object *json_vrf = NULL;
+       int mtype = 0;
+       int mval = 0;
+       static char header[] =
+               "Summary-address     Metric-type     Metric     Tag         External_Rt_count\n";
+
+       mtype = metric_type(ospf, 0, ospf->instance);
+       mval = metric_value(ospf, 0, ospf->instance);
+
+       if (!uj)
+               vty_out(vty, "%s\n", header);
+
+       if (uj) {
+               if (use_vrf)
+                       json_vrf = json_object_new_object();
+               else
+                       json_vrf = json;
+       }
+
+       if (ospf->instance) {
+               if (uj)
+                       json_object_int_add(json, "ospfInstance",
+                                           ospf->instance);
+               else
+                       vty_out(vty, "\nOSPF Instance: %d\n\n", ospf->instance);
+       }
+
+       ospf_show_vrf_name(ospf, vty, json_vrf, use_vrf);
+
+       if (!uj)
+               vty_out(vty, "aggregation delay interval :%d(in seconds)\n\n",
+                       ospf->aggr_delay_interval);
+       else
+               json_object_int_add(json_vrf, "aggregation delay interval",
+                                   ospf->aggr_delay_interval);
+
+       for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn))
+               if (rn->info) {
+                       struct ospf_external_aggr_rt *aggr = rn->info;
+                       json_object *json_aggr = NULL;
+                       char buf[PREFIX2STR_BUFFER];
+
+                       prefix2str(&aggr->p, buf, sizeof(buf));
+
+                       if (uj) {
+
+                               json_aggr = json_object_new_object();
+
+                               json_object_object_add(json_vrf, buf,
+                                                      json_aggr);
+
+                               json_object_string_add(json_aggr,
+                                                      "Summary address", buf);
+
+                               json_object_string_add(
+                                       json_aggr, "Metric-type",
+                                       (mtype == EXTERNAL_METRIC_TYPE_1)
+                                               ? "E1"
+                                               : "E2");
+
+                               json_object_int_add(json_aggr, "Metric", mval);
+
+                               json_object_int_add(json_aggr, "Tag",
+                                                   aggr->tag);
+
+                               json_object_int_add(
+                                       json_aggr, "External route count",
+                                       OSPF_EXTERNAL_RT_COUNT(aggr));
+
+                               if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) {
+                                       hash_walk(
+                                               aggr->match_extnl_hash,
+                                               ospf_json_external_rt_walkcb,
+                                               json_aggr);
+                               }
+
+                       } else {
+                               vty_out(vty, "%-20s", buf);
+
+                               (mtype == EXTERNAL_METRIC_TYPE_1)
+                                       ? vty_out(vty, "%-16s", "E1")
+                                       : vty_out(vty, "%-16s", "E2");
+                               vty_out(vty, "%-11d", mval);
+
+                               vty_out(vty, "%-12u", aggr->tag);
+
+                               vty_out(vty, "%-5ld\n",
+                                       OSPF_EXTERNAL_RT_COUNT(aggr));
+
+                               if (OSPF_EXTERNAL_RT_COUNT(aggr) && detail) {
+                                       vty_out(vty,
+                                               "Matched External routes:\n");
+                                       hash_walk(
+                                               aggr->match_extnl_hash,
+                                               ospf_vty_external_rt_walkcb,
+                                               vty);
+                                       vty_out(vty, "\n");
+                               }
+
+                               vty_out(vty, "\n");
+                       }
+               }
+
+       if (uj) {
+               if (use_vrf) {
+                       if (ospf->vrf_id == VRF_DEFAULT)
+                               json_object_object_add(json, "default",
+                                                      json_vrf);
+                       else
+                               json_object_object_add(json, ospf->name,
+                                                      json_vrf);
+               }
+       } else
+               vty_out(vty, "\n");
+
+       return CMD_SUCCESS;
+}
+
+DEFUN (show_ip_ospf_external_aggregator,
+       show_ip_ospf_external_aggregator_cmd,
+       "show ip ospf [vrf <NAME|all>] summary-address [detail] [json]",
+       SHOW_STR IP_STR
+       "OSPF information\n"
+       VRF_CMD_HELP_STR
+       "All VRFs\n"
+       "Show external summary addresses\n"
+       "Detailed informtion\n"
+       JSON_STR)
+{
+       char *vrf_name = NULL;
+       bool all_vrf = false;
+       int ret = CMD_SUCCESS;
+       int idx_vrf = 0;
+       int idx = 0;
+       uint8_t use_vrf = 0;
+       bool uj = use_json(argc, argv);
+       struct ospf *ospf = NULL;
+       json_object *json = NULL;
+       struct listnode *node = NULL;
+       int inst = 0;
+       bool detail = false;
+
+       OSPF_FIND_VRF_ARGS(argv, argc, idx_vrf, vrf_name, all_vrf);
+
+       if (argv_find(argv, argc, "detail", &idx))
+               detail = true;
+
+       if (uj)
+               json = json_object_new_object();
+
+       /* vrf input is provided */
+       if (vrf_name) {
+               use_vrf = 1;
+               if (all_vrf) {
+                       for (ALL_LIST_ELEMENTS_RO(om->ospf, node, ospf)) {
+                               if (!ospf->oi_running)
+                                       continue;
+                               ret = ospf_show_summary_address(
+                                       vty, ospf, use_vrf, json, uj, detail);
+                       }
+
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       }
+
+                       return ret;
+               }
+
+               ospf = ospf_lookup_by_inst_name(inst, vrf_name);
+
+               if (ospf == NULL || !ospf->oi_running) {
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
+                       return CMD_SUCCESS;
+               }
+               ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail);
+
+       } else {
+               /* Default Vrf */
+               ospf = ospf_lookup_by_vrf_id(VRF_DEFAULT);
+               if (ospf == NULL || !ospf->oi_running) {
+                       if (uj) {
+                               vty_out(vty, "%s\n",
+                                       json_object_to_json_string_ext(
+                                               json, JSON_C_TO_STRING_PRETTY));
+                               json_object_free(json);
+                       } else
+                               vty_out(vty, "%% OSPF instance not found\n");
+
+                       return CMD_SUCCESS;
+               }
+
+               ospf_show_summary_address(vty, ospf, use_vrf, json, uj, detail);
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n", json_object_to_json_string_ext(
+                                            json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
+       return CMD_SUCCESS;
+}
 
 static const char *const ospf_int_type_str[] = {
        "unknown", /* should never be used. */
@@ -9829,9 +11436,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                                ospf_int_type_str
                                                        [params->type]);
                                        if (params != IF_DEF_PARAMS(ifp) && rn)
-                                               vty_out(vty, " %s",
-                                                       inet_ntoa(
-                                                               rn->p.u.prefix4));
+                                               vty_out(vty, " %pI4",
+                                                       &rn->p.u.prefix4);
                                        vty_out(vty, "\n");
                                }
                        }
@@ -9866,8 +11472,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf authentication%s",
                                        auth_str);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9877,8 +11483,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf authentication-key %s",
                                        params->auth_simple);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9890,9 +11496,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                                " ip ospf message-digest-key %d md5 %s",
                                                ck->key_id, ck->auth_key);
                                        if (params != IF_DEF_PARAMS(ifp) && rn)
-                                               vty_out(vty, " %s",
-                                                       inet_ntoa(
-                                                               rn->p.u.prefix4));
+                                               vty_out(vty, " %pI4",
+                                                       &rn->p.u.prefix4);
                                        vty_out(vty, "\n");
                                }
                        }
@@ -9902,8 +11507,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf cost %u",
                                        params->output_cost_cmd);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9913,8 +11518,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf hello-interval %u",
                                        params->v_hello);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9935,8 +11540,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                        vty_out(vty, "%u", params->v_wait);
 
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9947,8 +11552,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf priority %u",
                                        params->priority);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9960,8 +11565,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf retransmit-interval %u",
                                        params->retransmit_interval);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9972,8 +11577,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                vty_out(vty, " ip ospf transmit-delay %u",
                                        params->transmit_delay);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -9991,8 +11596,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                            params->if_area_id_fmt);
                                vty_out(vty, " area %s", buf);
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -10008,8 +11613,8 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
                                else
                                        vty_out(vty, " ip ospf mtu-ignore");
                                if (params != IF_DEF_PARAMS(ifp) && rn)
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(rn->p.u.prefix4));
+                                       vty_out(vty, " %pI4",
+                                               &rn->p.u.prefix4);
                                vty_out(vty, "\n");
                        }
 
@@ -10073,9 +11678,7 @@ static int config_write_network_area(struct vty *vty, struct ospf *ospf)
                                                 n->area_id.s_addr));
 
                        /* Network print. */
-                       vty_out(vty, " network %s/%d area %s\n",
-                               inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen,
-                               buf);
+                       vty_out(vty, " network %pFX area %s\n", &rn->p, buf);
                }
 
        return 0;
@@ -10146,9 +11749,8 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
                        if (rn1->info) {
                                struct ospf_area_range *range = rn1->info;
 
-                               vty_out(vty, " area %s range %s/%d", buf,
-                                       inet_ntoa(rn1->p.u.prefix4),
-                                       rn1->p.prefixlen);
+                               vty_out(vty, " area %s range %pFX", buf,
+                                       &rn1->p);
 
                                if (range->cost_config
                                    != OSPF_AREA_RANGE_COST_UNSPEC)
@@ -10161,8 +11763,8 @@ static int config_write_ospf_area(struct vty *vty, struct ospf *ospf)
 
                                if (CHECK_FLAG(range->flags,
                                               OSPF_AREA_RANGE_SUBSTITUTE))
-                                       vty_out(vty, " substitute %s/%d",
-                                               inet_ntoa(range->subst_addr),
+                                       vty_out(vty, " substitute %pI4/%d",
+                                               &range->subst_addr,
                                                range->subst_masklen);
 
                                vty_out(vty, "\n");
@@ -10196,7 +11798,7 @@ static int config_write_ospf_nbr_nbma(struct vty *vty, struct ospf *ospf)
        /* Static Neighbor configuration print. */
        for (rn = route_top(ospf->nbr_nbma); rn; rn = route_next(rn))
                if ((nbr_nbma = rn->info)) {
-                       vty_out(vty, " neighbor %s", inet_ntoa(nbr_nbma->addr));
+                       vty_out(vty, " neighbor %pI4", &nbr_nbma->addr);
 
                        if (nbr_nbma->priority
                            != OSPF_NEIGHBOR_PRIORITY_DEFAULT)
@@ -10240,21 +11842,21 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf)
                            || OSPF_IF_PARAM(oi, transmit_delay)
                                       != OSPF_TRANSMIT_DELAY_DEFAULT)
                                vty_out(vty,
-                                       " area %s virtual-link %s hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n",
-                                       buf, inet_ntoa(vl_data->vl_peer),
+                                       " area %s virtual-link %pI4 hello-interval %d retransmit-interval %d transmit-delay %d dead-interval %d\n",
+                                       buf, &vl_data->vl_peer,
                                        OSPF_IF_PARAM(oi, v_hello),
                                        OSPF_IF_PARAM(oi, retransmit_interval),
                                        OSPF_IF_PARAM(oi, transmit_delay),
                                        OSPF_IF_PARAM(oi, v_wait));
                        else
-                               vty_out(vty, " area %s virtual-link %s\n", buf,
-                                       inet_ntoa(vl_data->vl_peer));
+                               vty_out(vty, " area %s virtual-link %pI4\n", buf,
+                                       &vl_data->vl_peer);
                        /* Auth key */
                        if (IF_DEF_PARAMS(vl_data->vl_oi->ifp)->auth_simple[0]
                            != '\0')
                                vty_out(vty,
-                                       " area %s virtual-link %s authentication-key %s\n",
-                                       buf, inet_ntoa(vl_data->vl_peer),
+                                       " area %s virtual-link %pI4 authentication-key %s\n",
+                                       buf, &vl_data->vl_peer,
                                        IF_DEF_PARAMS(vl_data->vl_oi->ifp)
                                                ->auth_simple);
                        /* md5 keys */
@@ -10263,8 +11865,8 @@ static int config_write_virtual_link(struct vty *vty, struct ospf *ospf)
                                             ->auth_crypt,
                                     n2, ck))
                                vty_out(vty,
-                                       " area %s virtual-link %s message-digest-key %d md5 %s\n",
-                                       buf, inet_ntoa(vl_data->vl_peer),
+                                       " area %s virtual-link %pI4 message-digest-key %d md5 %s\n",
+                                       buf, &vl_data->vl_peer,
                                        ck->key_id, ck->auth_key);
                }
        }
@@ -10310,6 +11912,66 @@ static int config_write_ospf_redistribute(struct vty *vty, struct ospf *ospf)
        return 0;
 }
 
+static int ospf_cfg_write_helper_dis_rtr_walkcb(struct hash_bucket *backet,
+                                               void *arg)
+{
+       struct advRtr *rtr = backet->data;
+       struct vty *vty = (struct vty *)arg;
+
+       vty_out(vty, " graceful-restart helper-only %pI4\n",
+               &rtr->advRtrAddr);
+       return HASHWALK_CONTINUE;
+}
+
+static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
+{
+       if (ospf->is_helper_supported)
+               vty_out(vty, " graceful-restart helper-only\n");
+
+       if (!ospf->strict_lsa_check)
+               vty_out(vty,
+                       " no graceful-restart helper strict-lsa-checking\n");
+
+       if (ospf->only_planned_restart)
+               vty_out(vty, " graceful-restart helper planned-only\n");
+
+       if (ospf->supported_grace_time != OSPF_MAX_GRACE_INTERVAL)
+               vty_out(vty,
+                       " graceful-restart helper supported-grace-time %d\n",
+                       ospf->supported_grace_time);
+
+       if (OSPF_HELPER_ENABLE_RTR_COUNT(ospf)) {
+               hash_walk(ospf->enable_rtr_list,
+                         ospf_cfg_write_helper_dis_rtr_walkcb, vty);
+       }
+       return 0;
+}
+
+static int config_write_ospf_external_aggregator(struct vty *vty,
+                                                struct ospf *ospf)
+{
+       struct route_node *rn;
+
+       /* print 'summary-address A.B.C.D/M' */
+       for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn))
+               if (rn->info) {
+                       struct ospf_external_aggr_rt *aggr = rn->info;
+
+                       vty_out(vty, " summary-address %pI4/%d ",
+                               &aggr->p.prefix, aggr->p.prefixlen);
+                       if (aggr->tag)
+                               vty_out(vty, " tag %u ", aggr->tag);
+
+                       if (CHECK_FLAG(aggr->flags,
+                                      OSPF_EXTERNAL_AGGRT_NO_ADVERTISE))
+                               vty_out(vty, " no-advertise");
+
+                       vty_out(vty, "\n");
+               }
+
+       return 0;
+}
+
 static int config_write_ospf_default_metric(struct vty *vty, struct ospf *ospf)
 {
        if (ospf->default_metric != -1)
@@ -10381,9 +12043,8 @@ static int config_write_ospf_distance(struct vty *vty, struct ospf *ospf)
 
        for (rn = route_top(ospf->distance_table); rn; rn = route_next(rn))
                if ((odistance = rn->info) != NULL) {
-                       vty_out(vty, " distance %d %s/%d %s\n",
-                               odistance->distance, inet_ntoa(rn->p.u.prefix4),
-                               rn->p.prefixlen,
+                       vty_out(vty, " distance %d %pFX %s\n",
+                               odistance->distance, &rn->p,
                                odistance->access_list ? odistance->access_list
                                                       : "");
                }
@@ -10416,8 +12077,8 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
 
        /* Router ID print. */
        if (ospf->router_id_static.s_addr != 0)
-               vty_out(vty, " ospf router-id %s\n",
-                       inet_ntoa(ospf->router_id_static));
+               vty_out(vty, " ospf router-id %pI4\n",
+                       &ospf->router_id_static);
 
        /* ABR type print. */
        if (ospf->abr_type != OSPF_ABR_DEFAULT)
@@ -10477,6 +12138,12 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
        /* Redistribute information print. */
        config_write_ospf_redistribute(vty, ospf);
 
+       /* Print gr helper configs */
+       config_write_ospf_gr_helper(vty, ospf);
+
+       /* Print external route aggregation. */
+       config_write_ospf_external_aggregator(vty, ospf);
+
        /* passive-interface print. */
        if (ospf->passive_interface_default == OSPF_IF_PASSIVE)
                vty_out(vty, " passive-interface default\n");
@@ -10511,9 +12178,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *ospf)
                           == ospf->passive_interface_default)
                        continue;
 
-               vty_out(vty, " %spassive-interface %s %s\n",
+               vty_out(vty, " %spassive-interface %s %pI4\n",
                        oi->params->passive_interface ? "" : "no ",
-                       oi->ifp->name, inet_ntoa(oi->address->u.prefix4));
+                       oi->ifp->name, &oi->address->u.prefix4);
        }
 
        /* Network area print. */
@@ -10620,8 +12287,13 @@ void ospf_vty_show_init(void)
 
        /* "show ip ospf vrfs" commands. */
        install_element(VIEW_NODE, &show_ip_ospf_vrfs_cmd);
-}
 
+       /* "show ip ospf gr-helper details" command */
+       install_element(VIEW_NODE, &show_ip_ospf_gr_helper_cmd);
+
+       /* "show ip ospf summary-address" command */
+       install_element(VIEW_NODE, &show_ip_ospf_external_aggregator_cmd);
+}
 
 static int config_write_interface(struct vty *vty);
 /* ospfd's interface node. */
@@ -10735,6 +12407,27 @@ static void ospf_vty_zebra_init(void)
        install_element(OSPF_NODE, &no_ospf_distance_cmd);
        install_element(OSPF_NODE, &no_ospf_distance_ospf_cmd);
        install_element(OSPF_NODE, &ospf_distance_ospf_cmd);
+
+       /*Ospf garcefull restart helper configurations */
+       install_element(OSPF_NODE, &ospf_gr_helper_enable_cmd);
+       install_element(OSPF_NODE, &no_ospf_gr_helper_enable_cmd);
+       install_element(OSPF_NODE, &ospf_gr_helper_enable_lsacheck_cmd);
+       install_element(OSPF_NODE, &no_ospf_gr_helper_enable_lsacheck_cmd);
+       install_element(OSPF_NODE, &ospf_gr_helper_supported_grace_time_cmd);
+       install_element(OSPF_NODE, &no_ospf_gr_helper_supported_grace_time_cmd);
+       install_element(OSPF_NODE, &ospf_gr_helper_planned_only_cmd);
+       install_element(OSPF_NODE, &no_ospf_gr_helper_planned_only_cmd);
+
+       /* External LSA summarisation config commands.*/
+       install_element(OSPF_NODE, &ospf_external_route_aggregation_cmd);
+       install_element(OSPF_NODE, &no_ospf_external_route_aggregation_cmd);
+       install_element(OSPF_NODE,
+                       &ospf_external_route_aggregation_no_adrvertise_cmd);
+       install_element(OSPF_NODE,
+                       &no_ospf_external_route_aggregation_no_adrvertise_cmd);
+       install_element(OSPF_NODE, &ospf_route_aggregation_timer_cmd);
+       install_element(OSPF_NODE, &no_ospf_route_aggregation_timer_cmd);
+
 #if 0
   install_element (OSPF_NODE, &ospf_distance_source_cmd);
   install_element (OSPF_NODE, &no_ospf_distance_source_cmd);
index dc8a8dccd25c681eb6fbc35a1df9449144ec75e5..fd965e8f214c8a8557e8c971b46faba3b6c50dda 100644 (file)
@@ -73,12 +73,9 @@ static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
        struct prefix router_id;
        zebra_router_id_update_read(zclient->ibuf, &router_id);
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&router_id, buf, sizeof(buf));
-               zlog_debug("Zebra rcvd: router id update %s vrf %s id %u", buf,
-                          ospf_vrf_id_to_name(vrf_id), vrf_id);
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra rcvd: router id update %pFX vrf %s id %u",
+                          &router_id, ospf_vrf_id_to_name(vrf_id), vrf_id);
 
        ospf = ospf_lookup_by_vrf_id(vrf_id);
 
@@ -86,15 +83,11 @@ static int ospf_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
                ospf->router_id_zebra = router_id.u.prefix4;
                ospf_router_id_update(ospf);
        } else {
-               if (IS_DEBUG_OSPF_EVENT) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(&router_id, buf, sizeof(buf));
+               if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug(
-                               "%s: ospf instance not found for vrf %s id %u router_id %s",
+                               "%s: ospf instance not found for vrf %s id %u router_id %pFX",
                                __func__, ospf_vrf_id_to_name(vrf_id), vrf_id,
-                               buf);
-               }
+                               &router_id);
        }
        return 0;
 }
@@ -110,13 +103,10 @@ static int ospf_interface_address_add(ZAPI_CALLBACK_ARGS)
        if (c == NULL)
                return 0;
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(c->address, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s address add %s vrf %s id %u",
-                          c->ifp->name, buf, ospf_vrf_id_to_name(vrf_id),
-                          vrf_id);
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: interface %s address add %pFX vrf %s id %u",
+                          c->ifp->name, c->address,
+                          ospf_vrf_id_to_name(vrf_id), vrf_id);
 
        ospf = ospf_lookup_by_vrf_id(vrf_id);
        if (!ospf)
@@ -142,12 +132,9 @@ static int ospf_interface_address_delete(ZAPI_CALLBACK_ARGS)
        if (c == NULL)
                return 0;
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE)) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(c->address, buf, sizeof(buf));
-               zlog_debug("Zebra: interface %s address delete %s",
-                          c->ifp->name, buf);
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_INTERFACE))
+               zlog_debug("Zebra: interface %s address delete %pFX",
+                          c->ifp->name, c->address);
 
        ifp = c->ifp;
        p = *c->address;
@@ -279,17 +266,14 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
                count++;
 
                if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-                       char buf[2][PREFIX2STR_BUFFER];
                        struct interface *ifp;
 
                        ifp = if_lookup_by_index(path->ifindex, ospf->vrf_id);
 
                        zlog_debug(
-                               "Zebra: Route add %s nexthop %s, ifindex=%d %s",
-                               prefix2str(p, buf[0], sizeof(buf[0])),
-                               inet_ntop(AF_INET, &path->nexthop,
-                                         buf[1], sizeof(buf[1])),
-                               path->ifindex, ifp ? ifp->name : " ");
+                               "Zebra: Route add %pFX nexthop %pI4, ifindex=%d %s",
+                               p, &path->nexthop, path->ifindex,
+                               ifp ? ifp->name : " ");
                }
        }
        api.nexthop_num = count;
@@ -309,11 +293,8 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
        api.safi = SAFI_UNICAST;
        memcpy(&api.prefix, p, sizeof(*p));
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-               char buf[PREFIX2STR_BUFFER];
-               zlog_debug("Zebra: Route delete %s",
-                          prefix2str(p, buf, sizeof(buf)));
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
+               zlog_debug("Zebra: Route delete %pFX", p);
 
        zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 }
@@ -332,11 +313,8 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
 
        zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-               char buf[PREFIX2STR_BUFFER];
-               zlog_debug("Zebra: Route add discard %s",
-                          prefix2str(p, buf, sizeof(buf)));
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
+               zlog_debug("Zebra: Route add discard %pFX", p);
 }
 
 void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
@@ -353,11 +331,8 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
 
        zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-               char buf[PREFIX2STR_BUFFER];
-               zlog_debug("Zebra: Route delete discard %s",
-                          prefix2str(p, buf, sizeof(buf)));
-       }
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
+               zlog_debug("Zebra: Route delete discard %pFX", p);
 }
 
 struct ospf_external *ospf_external_lookup(struct ospf *ospf, uint8_t type,
@@ -433,8 +408,8 @@ bool ospf_external_default_routemap_apply_walk(struct ospf *ospf,
 
        if (ret && ei) {
                if (IS_DEBUG_OSPF_DEFAULT_INFO)
-                       zlog_debug("Default originate routemap permit ei: %s",
-                                  inet_ntoa(ei->p.prefix));
+                       zlog_debug("Default originate routemap permit ei: %pI4",
+                                  &ei->p.prefix);
                return true;
        }
 
@@ -488,7 +463,7 @@ static int ospf_external_lsa_default_routemap_timer(struct thread *thread)
        if (ret && !lsa)
                ospf_external_lsa_originate(ospf, default_ei);
        else if (ret && lsa && IS_LSA_MAXAGE(lsa))
-               ospf_external_lsa_refresh(ospf, lsa, default_ei, true);
+               ospf_external_lsa_refresh(ospf, lsa, default_ei, true, false);
        else if (!ret && lsa)
                ospf_external_lsa_flush(ospf, DEFAULT_ROUTE, &default_ei->p, 0);
 
@@ -875,8 +850,8 @@ static int ospf_external_lsa_originate_check(struct ospf *ospf,
        /* If prefix is multicast, then do not originate LSA. */
        if (IN_MULTICAST(htonl(ei->p.prefix.s_addr))) {
                zlog_info(
-                       "LSA[Type5:%s]: Not originate AS-external-LSA, Prefix belongs multicast",
-                       inet_ntoa(ei->p.prefix));
+                       "LSA[Type5:%pI4]: Not originate AS-external-LSA, Prefix belongs multicast",
+                       &ei->p.prefix);
                return 0;
        }
 
@@ -968,16 +943,16 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
        }
 
        if (IS_DEBUG_OSPF_DEFAULT_INFO)
-               zlog_debug("Apply default originate routemap on ei: %s cmd: %d",
-                          inet_ntoa(ei->p.prefix), cmd);
+               zlog_debug("Apply default originate routemap on ei: %pI4 cmd: %d",
+                          &ei->p.prefix, cmd);
 
        ret = ospf_external_info_apply_default_routemap(ospf, ei, default_ei);
 
        /* If deny then nothing to be done both in add and del case. */
        if (!ret) {
                if (IS_DEBUG_OSPF_DEFAULT_INFO)
-                       zlog_debug("Default originte routemap deny for ei: %s",
-                                  inet_ntoa(ei->p.prefix));
+                       zlog_debug("Default originte routemap deny for ei: %pI4",
+                                  &ei->p.prefix);
                return false;
        }
 
@@ -989,7 +964,7 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
                /* If permit and default already advertise then return. */
                if (lsa && !IS_LSA_MAXAGE(lsa)) {
                        if (IS_DEBUG_OSPF_DEFAULT_INFO)
-                               zlog_debug("Defult lsa already originated");
+                               zlog_debug("Default lsa already originated");
                        return true;
                }
 
@@ -998,7 +973,8 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
 
                if (lsa && IS_LSA_MAXAGE(lsa))
                        /* Refresh lsa.*/
-                       ospf_external_lsa_refresh(ospf, lsa, default_ei, true);
+                       ospf_external_lsa_refresh(ospf, lsa, default_ei, true,
+                                                 false);
                else
                        /* If permit and default not advertised then advertise.
                         */
@@ -1015,8 +991,8 @@ static bool ospf_external_lsa_default_routemap_apply(struct ospf *ospf,
 
                if (IS_DEBUG_OSPF_DEFAULT_INFO)
                        zlog_debug(
-                               "Running default route-map again as ei: %s deleted",
-                               inet_ntoa(ei->p.prefix));
+                               "Running default route-map again as ei: %pI4 deleted",
+                               &ei->p.prefix);
                /*
                 * if this route delete was permitted then we need to check
                 * there are any other external info which can still trigger
@@ -1061,13 +1037,10 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
                if (DISTRIBUTE_LIST(ospf, type))
                        if (access_list_apply(DISTRIBUTE_LIST(ospf, type), p)
                            == FILTER_DENY) {
-                               if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-                                       char buf[PREFIX2STR_BUFFER];
+                               if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                                        zlog_debug(
-                                               "Redistribute[%s]: %s filtered by distribute-list.",
-                                               ospf_redist_string(type),
-                                               prefix2str(p, buf, sizeof(buf)));
-                               }
+                                               "Redistribute[%s]: %pFX filtered by distribute-list.",
+                                               ospf_redist_string(type), p);
                                return 0;
                        }
 
@@ -1088,13 +1061,10 @@ int ospf_redistribute_check(struct ospf *ospf, struct external_info *ei,
 
                if (ret == RMAP_DENYMATCH) {
                        ei->route_map_set = save_values;
-                       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-                               char buf[PREFIX2STR_BUFFER];
+                       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
                                zlog_debug(
-                                       "Redistribute[%s]: %s filtered by route-map.",
-                                       ospf_redist_string(type),
-                                       prefix2str(p, buf, sizeof(buf)));
-                       }
+                                       "Redistribute[%s]: %pFX filtered by route-map.",
+                                       ospf_redist_string(type), p);
                        return 0;
                }
 
@@ -1171,14 +1141,10 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
        if (is_prefix_default(&p))
                rt_type = DEFAULT_ROUTE;
 
-       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE)) {
-               char buf_prefix[PREFIX_STRLEN];
-               prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
-
-               zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %s",
+       if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
+               zlog_debug("%s: cmd %s from client %s: vrf_id %d, p %pFX",
                           __func__, zserv_command_string(cmd),
-                          zebra_route_string(api.type), vrf_id, buf_prefix);
-       }
+                          zebra_route_string(api.type), vrf_id, &api.prefix);
 
        if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD) {
                /* XXX|HACK|TODO|FIXME:
@@ -1215,24 +1181,100 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
                                if (is_prefix_default(&p))
                                        ospf_external_lsa_refresh_default(ospf);
                                else {
-                                       struct ospf_lsa *current;
+                                       struct ospf_external_aggr_rt *aggr;
+                                       struct as_external_lsa *al;
+                                       struct ospf_lsa *lsa = NULL;
+                                       struct in_addr mask;
+
+                                       aggr = ospf_external_aggr_match(ospf,
+                                                                       &ei->p);
+
+                                       if (aggr) {
+                                               /* Check the AS-external-LSA
+                                                * should be originated.
+                                                */
+                                               if (!ospf_redistribute_check(
+                                                           ospf, ei, NULL))
+                                                       return 0;
 
-                                       current = ospf_external_info_find_lsa(
-                                               ospf, &ei->p);
-                                       if (!current)
-                                               ospf_external_lsa_originate(
-                                                       ospf, ei);
-                                       else {
                                                if (IS_DEBUG_OSPF(
-                                                           zebra,
-                                                           ZEBRA_REDISTRIBUTE))
+                                                           lsa,
+                                                           EXTNL_LSA_AGGR))
                                                        zlog_debug(
-                                                               "ospf_zebra_read_route() : %s refreshing LSA",
-                                                               inet_ntoa(
-                                                                       p.prefix));
-                                               ospf_external_lsa_refresh(
-                                                       ospf, current, ei,
-                                                       LSA_REFRESH_FORCE);
+                                                               "%s: Send Aggreate LSA (%pI4/%d)",
+                                                               __func__,
+                                                               &aggr->p.prefix,
+                                                               aggr->p.prefixlen);
+
+                                               ospf_originate_summary_lsa(
+                                                       ospf, aggr, ei);
+
+                                               /* Handling the case where the
+                                                * external route prefix
+                                                * and aggegate prefix is same
+                                                * If same dont flush the
+                                                * originated
+                                                * external LSA.
+                                                */
+                                               if (prefix_same(
+                                                           (struct prefix
+                                                                    *)&aggr->p,
+                                                           (struct prefix *)&ei
+                                                                   ->p))
+                                                       return 0;
+
+                                               lsa = ospf_external_info_find_lsa(
+                                                       ospf, &ei->p);
+
+                                               if (lsa) {
+                                                       al = (struct
+                                                             as_external_lsa *)
+                                                                    lsa->data;
+                                                       masklen2ip(
+                                                               ei->p.prefixlen,
+                                                               &mask);
+
+                                                       if (mask.s_addr
+                                                           != al->mask.s_addr)
+                                                               return 0;
+
+                                                       ospf_external_lsa_flush(
+                                                               ospf, ei->type,
+                                                               &ei->p, 0);
+                                               }
+                                       } else {
+                                               struct ospf_lsa *current;
+
+                                               current =
+                                                       ospf_external_info_find_lsa(
+                                                               ospf, &ei->p);
+                                               if (!current) {
+                                                       /* Check the
+                                                        * AS-external-LSA
+                                                        * should be
+                                                        * originated.
+                                                        */
+                                                       if (!ospf_redistribute_check(
+                                                                   ospf, ei,
+                                                                   NULL))
+                                                               return 0;
+
+                                                       ospf_external_lsa_originate(
+                                                               ospf, ei);
+                                               } else {
+                                                       if (IS_DEBUG_OSPF(
+                                                                   zebra,
+                                                                   ZEBRA_REDISTRIBUTE))
+                                                               zlog_debug(
+                                                                       "%s: %pI4 refreshing LSA",
+                                                                       __func__,
+                                                                       &p.prefix);
+                                                       ospf_external_lsa_refresh(
+                                                               ospf, current,
+                                                               ei,
+                                                               LSA_REFRESH_FORCE,
+                                                               false);
+                                               }
                                        }
                                }
                        }
@@ -1246,21 +1288,36 @@ static int ospf_zebra_read_route(ZAPI_CALLBACK_ARGS)
 
        } else /* if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_DEL) */
        {
-               /*
-                * Check if default-information originate is
-                * with some routemap prefix/access list match.
-                * Apply before ei is deleted.
-                */
+               struct ospf_external_aggr_rt *aggr;
+
                ei = ospf_external_info_lookup(ospf, rt_type, api.instance, &p);
-               if (ei)
+               if (ei == NULL)
+                       return 0;
+               else
+                       /*
+                        * Check if default-information originate i
+                        * with some routemap prefix/access list match.
+                        * Apply before ei is deleted.
+                        */
                        ospf_external_lsa_default_routemap_apply(ospf, ei, cmd);
 
-               ospf_external_info_delete(ospf, rt_type, api.instance, p);
-               if (is_prefix_default(&p))
-                       ospf_external_lsa_refresh_default(ospf);
-               else
-                       ospf_external_lsa_flush(ospf, rt_type, &p,
-                                               ifindex /*, nexthop */);
+               aggr = ospf_external_aggr_match(ospf, &ei->p);
+
+               if (aggr && (ei->aggr_route == aggr)) {
+                       ospf_unlink_ei_from_aggr(ospf, aggr, ei);
+
+                       ospf_external_info_delete(ospf, rt_type, api.instance,
+                                                 p);
+               } else {
+                       ospf_external_info_delete(ospf, rt_type, api.instance,
+                                                 p);
+
+                       if (is_prefix_default(&p))
+                               ospf_external_lsa_refresh_default(ospf);
+                       else
+                               ospf_external_lsa_flush(ospf, rt_type, &p,
+                                                       ifindex /*, nexthop */);
+               }
        }
 
 
@@ -1352,32 +1409,80 @@ static int ospf_distribute_list_update_timer(struct thread *thread)
                                if ((ei = rn->info) != NULL) {
                                        if (is_prefix_default(&ei->p))
                                                default_refresh = 1;
-                                       else if (
-                                               (lsa = ospf_external_info_find_lsa(
-                                                        ospf, &ei->p))) {
-                                               int force =
-                                                       LSA_REFRESH_IF_CHANGED;
-                                               /* If this is a MaxAge LSA, we
-                                                * need to force refresh it
-                                                * because distribute settings
-                                                * might have changed and now,
-                                                * this LSA needs to be
-                                                * originated, not be removed.
-                                                * If we don't force refresh it,
-                                                * it will remain a MaxAge LSA
-                                                * because it will look like it
-                                                * hasn't changed. Neighbors
-                                                * will not receive updates for
-                                                * this LSA.
-                                                */
-                                               if (IS_LSA_MAXAGE(lsa))
-                                                       force = LSA_REFRESH_FORCE;
-
-                                               ospf_external_lsa_refresh(
-                                                       ospf, lsa, ei, force);
-                                       } else
-                                               ospf_external_lsa_originate(
-                                                       ospf, ei);
+                                       else {
+                                               struct ospf_external_aggr_rt
+                                                       *aggr;
+                                               aggr = ospf_external_aggr_match(
+                                                       ospf, &ei->p);
+                                               if (aggr) {
+                                                       /* Check the
+                                                        * AS-external-LSA
+                                                        * should be originated.
+                                                        */
+                                                       if (!ospf_redistribute_check(
+                                                                   ospf, ei,
+                                                                   NULL)) {
+
+                                                               ospf_unlink_ei_from_aggr(
+                                                                       ospf,
+                                                                       aggr,
+                                                                       ei);
+                                                               continue;
+                                                       }
+
+                                                       if (IS_DEBUG_OSPF(
+                                                                   lsa,
+                                                                   EXTNL_LSA_AGGR))
+                                                               zlog_debug(
+                                                                       "%s: Send Aggregate LSA (%pI4/%d)",
+                                                                       __func__,
+                                                                       &aggr->p.prefix,
+                                                                       aggr->p.prefixlen);
+
+                                                       /* Originate Aggregate
+                                                        * LSA
+                                                        */
+                                                       ospf_originate_summary_lsa(
+                                                               ospf, aggr, ei);
+                                               } else if (
+                                                       (lsa = ospf_external_info_find_lsa(
+                                                                ospf,
+                                                                &ei->p))) {
+                                                       int force =
+                                                               LSA_REFRESH_IF_CHANGED;
+                                                       /* If this is a MaxAge
+                                                        * LSA, we need to
+                                                        * force refresh it
+                                                        * because distribute
+                                                        * settings might have
+                                                        * changed and now,
+                                                        * this LSA needs to be
+                                                        * originated, not be
+                                                        * removed.
+                                                        * If we don't force
+                                                        * refresh it, it will
+                                                        * remain a MaxAge LSA
+                                                        * because it will look
+                                                        * like it hasn't
+                                                        * changed. Neighbors
+                                                        * will not receive
+                                                        * updates for this LSA.
+                                                        */
+                                                       if (IS_LSA_MAXAGE(lsa))
+                                                               force = LSA_REFRESH_FORCE;
+
+                                                       ospf_external_lsa_refresh(
+                                                               ospf, lsa, ei,
+                                                               force, false);
+                                               } else {
+                                                       if (!ospf_redistribute_check(
+                                                                   ospf, ei,
+                                                                   NULL))
+                                                               continue;
+                                                       ospf_external_lsa_originate(
+                                                               ospf, ei);
+                                               }
+                                       }
                                }
                }
        }
index cc5839a810c442b347403035ddc17e3366b3d646..a839806720ea22d39baef04b88216f31006aded1 100644 (file)
@@ -59,6 +59,7 @@
 #include "ospfd/ospf_flood.h"
 #include "ospfd/ospf_ase.h"
 #include "ospfd/ospf_ldp_sync.h"
+#include "ospfd/ospf_gr_helper.h"
 
 
 DEFINE_QOBJ_TYPE(ospf)
@@ -102,8 +103,8 @@ void ospf_router_id_update(struct ospf *ospf)
        }
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("Router-ID[OLD:%s]: Update",
-                          inet_ntoa(ospf->router_id));
+               zlog_debug("Router-ID[OLD:%pI4]: Update",
+                          &ospf->router_id);
 
        router_id_old = ospf->router_id;
 
@@ -122,8 +123,8 @@ void ospf_router_id_update(struct ospf *ospf)
                router_id = ospf->router_id_zebra;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("Router-ID[OLD:%s]: Update to %s",
-                          inet_ntoa(ospf->router_id), inet_ntoa(router_id));
+               zlog_debug("Router-ID[OLD:%pI4]: Update to %pI4",
+                          &ospf->router_id, &router_id);
 
        if (!IPV4_ADDR_SAME(&router_id_old, &router_id)) {
 
@@ -161,8 +162,8 @@ void ospf_router_id_update(struct ospf *ospf)
 
                ospf->router_id = router_id;
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("Router-ID[NEW:%s]: Update",
-                                  inet_ntoa(ospf->router_id));
+                       zlog_debug("Router-ID[NEW:%pI4]: Update",
+                                  &ospf->router_id);
 
                /* Flush (inline) all external LSAs which now match the new
                   router-id,
@@ -309,6 +310,10 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
 
        new->proactive_arp = OSPF_PROACTIVE_ARP_DEFAULT;
 
+       ospf_gr_helper_init(new);
+
+       ospf_asbr_external_aggregator_init(new);
+
        QOBJ_REG(new, ospf);
 
        new->fd = -1;
@@ -382,6 +387,8 @@ struct ospf *ospf_lookup_by_inst_name(unsigned short instance, const char *name)
 struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
 {
        struct ospf *ospf;
+       struct vrf *vrf;
+       struct interface *ifp;
 
        /* vrf name provided call inst and name based api
         * in case of no name pass default ospf instance */
@@ -395,10 +402,39 @@ struct ospf *ospf_get(unsigned short instance, const char *name, bool *created)
                ospf = ospf_new(instance, name);
                ospf_add(ospf);
 
-               if (ospf->router_id_static.s_addr == INADDR_ANY)
-                       ospf_router_id_update(ospf);
-
                ospf_opaque_type11_lsa_init(ospf);
+
+               if (ospf->vrf_id != VRF_UNKNOWN)
+                       ospf->oi_running = 1;
+
+               /* Activate 'ip ospf area x' configured interfaces for given
+                * vrf. Activate area on vrf x aware interfaces.
+                * vrf_enable callback calls router_id_update which
+                * internally will call ospf_if_update to trigger
+                * network_run_state
+                */
+               vrf = vrf_lookup_by_id(ospf->vrf_id);
+
+               FOR_ALL_INTERFACES (vrf, ifp) {
+                       struct ospf_if_params *params;
+                       struct route_node *rn;
+                       uint32_t count = 0;
+
+                       params = IF_DEF_PARAMS(ifp);
+                       if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
+                               count++;
+
+                       for (rn = route_top(IF_OIFS_PARAMS(ifp)); rn; rn = route_next(rn))
+                               if ((params = rn->info) && OSPF_IF_PARAM_CONFIGURED(params, if_area))
+                                       count++;
+
+                       if (count > 0) {
+                               ospf_interface_area_set(ospf, ifp);
+                               ospf->if_ospf_cli_count += count;
+                       }
+               }
+
+               ospf_router_id_update(ospf);
        }
 
        return ospf;
@@ -414,9 +450,6 @@ struct ospf *ospf_get_instance(unsigned short instance, bool *created)
                ospf = ospf_new(instance, NULL /* VRF_DEFAULT*/);
                ospf_add(ospf);
 
-               if (ospf->router_id_static.s_addr == INADDR_ANY)
-                       ospf_router_id_update(ospf);
-
                ospf_opaque_type11_lsa_init(ospf);
        }
 
@@ -578,11 +611,10 @@ void ospf_finish(struct ospf *ospf)
 /* Final cleanup of ospf instance */
 static void ospf_finish_final(struct ospf *ospf)
 {
-       struct vrf *vrf = vrf_lookup_by_id(ospf->vrf_id);
+       struct vrf *vrf;
        struct route_node *rn;
        struct ospf_nbr_nbma *nbr_nbma;
        struct ospf_lsa *lsa;
-       struct interface *ifp;
        struct ospf_interface *oi;
        struct ospf_area *area;
        struct ospf_vl_data *vl_data;
@@ -625,15 +657,6 @@ static void ospf_finish_final(struct ospf *ospf)
        if (ospf->vrf_id == VRF_DEFAULT)
                ospf_ldp_sync_gbl_exit(ospf, true);
 
-       /* Remove any ospf interface config params */
-       FOR_ALL_INTERFACES (vrf, ifp) {
-               struct ospf_if_params *params;
-
-               params = IF_DEF_PARAMS(ifp);
-               if (OSPF_IF_PARAM_CONFIGURED(params, if_area))
-                       UNSET_IF_PARAM(params, if_area);
-       }
-
        /* Reset interface. */
        for (ALL_LIST_ELEMENTS(ospf->oiflist, node, nnode, oi))
                ospf_if_free(oi);
@@ -695,6 +718,7 @@ static void ospf_finish_final(struct ospf *ospf)
        OSPF_TIMER_OFF(ospf->t_opaque_lsa_self);
        OSPF_TIMER_OFF(ospf->t_sr_update);
        OSPF_TIMER_OFF(ospf->t_default_routemap_timer);
+       OSPF_TIMER_OFF(ospf->t_external_aggr);
 
        LSDB_LOOP (OPAQUE_AS_LSDB(ospf), rn, lsa)
                ospf_discard_from_db(ospf, ospf->lsdb, lsa);
@@ -763,9 +787,28 @@ static void ospf_finish_final(struct ospf *ospf)
        ospf_distance_reset(ospf);
        route_table_finish(ospf->distance_table);
 
+       /* Release extrenal Aggregator table */
+       for (rn = route_top(ospf->rt_aggr_tbl); rn; rn = route_next(rn)) {
+               struct ospf_external_aggr_rt *aggr;
+
+               aggr = rn->info;
+
+               if (aggr) {
+                       ospf_external_aggregator_free(aggr);
+                       rn->info = NULL;
+                       route_unlock_node(rn);
+               }
+       }
+
+       route_table_finish(ospf->rt_aggr_tbl);
+
+
        list_delete(&ospf->areas);
        list_delete(&ospf->oi_write_q);
 
+       /* Reset GR helper data structers */
+       ospf_gr_helper_stop(ospf);
+
        close(ospf->fd);
        stream_free(ospf->ibuf);
        ospf->fd = -1;
@@ -1138,32 +1181,6 @@ void ospf_interface_area_unset(struct ospf *ospf, struct interface *ifp)
        update_redistributed(ospf, 0); /* interfaces possibly removed */
 }
 
-bool ospf_interface_area_is_already_set(struct ospf *ospf,
-                                       struct interface *ifp)
-{
-       struct route_node *rn_oi;
-
-       if (!ospf)
-               return false; /* Ospf not ready yet */
-
-       /* Find interfaces that may need to be removed. */
-       for (rn_oi = route_top(IF_OIFS(ifp)); rn_oi;
-            rn_oi = route_next(rn_oi)) {
-               struct ospf_interface *oi = rn_oi->info;
-
-               if (oi == NULL)
-                       continue;
-
-               if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
-                       continue;
-               /* at least one route covered by interface
-                * that implies already done
-                */
-               return true;
-       }
-       return false;
-}
-
 /* Check whether interface matches given network
  * returns: 1, true. 0, false
  */
@@ -1318,10 +1335,7 @@ void ospf_ls_upd_queue_empty(struct ospf_interface *oi)
                }
 
        /* remove update event */
-       if (oi->t_ls_upd_event) {
-               thread_cancel(oi->t_ls_upd_event);
-               oi->t_ls_upd_event = NULL;
-       }
+       thread_cancel(&oi->t_ls_upd_event);
 }
 
 void ospf_if_update(struct ospf *ospf, struct interface *ifp)
@@ -1332,10 +1346,10 @@ void ospf_if_update(struct ospf *ospf, struct interface *ifp)
 
        if (IS_DEBUG_OSPF_EVENT)
                zlog_debug(
-                       "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %s",
+                       "%s: interface %s ifp->vrf_id %u ospf vrf %s vrf_id %u router_id %pI4",
                        __func__, ifp->name, ifp->vrf_id,
                        ospf_vrf_id_to_name(ospf->vrf_id), ospf->vrf_id,
-                       inet_ntoa(ospf->router_id));
+                       &ospf->router_id);
 
        /* OSPF must be ready. */
        if (!ospf_is_ready(ospf))
@@ -1372,16 +1386,16 @@ static void ospf_area_type_set(struct ospf_area *area, int type)
 
        if (area->external_routing == type) {
                if (IS_DEBUG_OSPF_EVENT)
-                       zlog_debug("Area[%s]: Types are the same, ignored.",
-                                  inet_ntoa(area->area_id));
+                       zlog_debug("Area[%pI4]: Types are the same, ignored.",
+                                  &area->area_id);
                return;
        }
 
        area->external_routing = type;
 
        if (IS_DEBUG_OSPF_EVENT)
-               zlog_debug("Area[%s]: Configured as %s",
-                          inet_ntoa(area->area_id),
+               zlog_debug("Area[%pI4]: Configured as %s",
+                          &area->area_id,
                           lookup_msg(ospf_area_type_msg, type, NULL));
 
        switch (area->external_routing) {
@@ -2152,7 +2166,7 @@ static int ospf_vrf_disable(struct vrf *vrf)
                if (IS_DEBUG_OSPF_EVENT)
                        zlog_debug("%s: ospf old_vrf_id %d unlinked", __func__,
                                   old_vrf_id);
-               thread_cancel(ospf->t_read);
+               thread_cancel(&ospf->t_read);
                close(ospf->fd);
                ospf->fd = -1;
        }
index 55bc64317ed3f045310ff849eabda24d9e060636..bdd09e1e766cb15398d4b3400ffcd608529ac25f 100644 (file)
@@ -319,7 +319,57 @@ struct ospf {
 
        /* Redistributed external information. */
        struct list *external[ZEBRA_ROUTE_MAX + 1];
-#define EXTERNAL_INFO(E)      (E->external_info)
+#define EXTERNAL_INFO(E) (E->external_info)
+
+       /* Gracefull restart Helper supported configs*/
+       /* Supported grace interval*/
+       uint32_t supported_grace_time;
+
+       /* Helper support
+        * Supported : True
+        * Not Supported : False.
+        */
+       bool is_helper_supported;
+
+       /* Support for strict LSA check.
+        * if it is set,Helper aborted
+        * upon a TOPO change.
+        */
+       bool strict_lsa_check;
+
+       /* Support as HELPER only for
+        * planned restarts.
+        */
+       bool only_planned_restart;
+
+       /* This list contains the advertisement
+        * routerids which are not support for HELPERs.
+        */
+       struct hash *enable_rtr_list;
+
+       /* HELPER for number of active
+        * RESTARTERs.
+        */
+       uint16_t active_restarter_cnt;
+
+       /* last HELPER exit reason */
+       uint32_t last_exit_reason;
+
+       /* delay timer to process external routes
+        * with summary address.
+        */
+       struct thread *t_external_aggr;
+
+       /* delay interval in seconds */
+       unsigned int aggr_delay_interval;
+
+       /* Table of configured Aggregate addresses */
+       struct route_table *rt_aggr_tbl;
+
+       /* used as argument for aggr delay
+        * timer thread.
+        */
+       int aggr_action;
 
        /* MPLS LDP-IGP Sync */
        struct ldp_sync_info_cmd ldp_sync_cmd;
@@ -501,13 +551,7 @@ struct ospf_nbr_nbma {
 #define OSPF_AREA_TIMER_ON(T,F,V) thread_add_timer (master, (F), area, (V), &(T))
 #define OSPF_POLL_TIMER_ON(T,F,V) thread_add_timer (master, (F), nbr_nbma, (V), &(T))
 #define OSPF_POLL_TIMER_OFF(X) OSPF_TIMER_OFF((X))
-#define OSPF_TIMER_OFF(X)                                                      \
-       do {                                                                   \
-               if (X) {                                                       \
-                       thread_cancel(X);                                      \
-                       (X) = NULL;                                            \
-               }                                                              \
-       } while (0)
+#define OSPF_TIMER_OFF(X) thread_cancel(&(X))
 
 /* Extern variables. */
 extern struct ospf_master *om;
@@ -580,8 +624,6 @@ extern void ospf_area_del_if(struct ospf_area *, struct ospf_interface *);
 
 extern void ospf_interface_area_set(struct ospf *, struct interface *);
 extern void ospf_interface_area_unset(struct ospf *, struct interface *);
-extern bool ospf_interface_area_is_already_set(struct ospf *ospf,
-                                              struct interface *ifp);
 
 extern void ospf_route_map_init(void);
 
index e586937478dda3dc57ab3f7656a80bb51d73498a..1a807ea12b9a5f255e1fbd9ace8cdcdbed93ca54 100644 (file)
@@ -57,6 +57,7 @@ ospfd_libfrrospf_a_SOURCES = \
        ospfd/ospf_vty.c \
        ospfd/ospf_zebra.c \
        ospfd/ospfd.c \
+       ospfd/ospf_gr_helper.c \
        # end
 
 if OSPFD
@@ -78,6 +79,7 @@ endif
 clippy_scan += \
        ospfd/ospf_vty.c \
        ospfd/ospf_ldp_sync.c \
+       ospfd/ospf_dump.c \
        # end
 
 noinst_HEADERS += \
@@ -102,6 +104,7 @@ noinst_HEADERS += \
        ospfd/ospf_te.h \
        ospfd/ospf_vty.h \
        ospfd/ospf_zebra.h \
+       ospfd/ospf_gr_helper.h \
        # end
 
 ospfd_ospfd_LDADD = ospfd/libfrrospf.a lib/libfrr.la $(LIBCAP) $(LIBM)
index 9a9edd79c6712266b4f6c0e26a8fd8ea36f07ea3..01c52f24e53c95cc7e36361f7061c030fd1ba04d 100644 (file)
@@ -82,6 +82,8 @@ static void sigint(void)
 {
        zlog_notice("Terminating on signal");
 
+       pbr_vrf_terminate();
+
        frr_fini();
 
        exit(0);
index 3fb3759049759a3a4deed100b35a6d9abb07d8ce..ce7780ed498f486a53dcd73e03a08921686aca80 100644 (file)
@@ -827,16 +827,14 @@ static void pbr_nht_individual_nexthop_update_lookup(struct hash_bucket *b,
 {
        struct pbr_nexthop_cache *pnhc = b->data;
        struct pbr_nht_individual *pnhi = data;
-       char buf[PREFIX_STRLEN];
        bool old_valid;
 
        old_valid = pnhc->valid;
 
        pbr_nht_individual_nexthop_update(pnhc, pnhi);
 
-       DEBUGD(&pbr_dbg_nht, "\tFound %s: old: %d new: %d",
-              prefix2str(&pnhi->nhr->prefix, buf, sizeof(buf)), old_valid,
-              pnhc->valid);
+       DEBUGD(&pbr_dbg_nht, "\tFound %pFX: old: %d new: %d",
+              &pnhi->nhr->prefix, old_valid, pnhc->valid);
 
        if (pnhc->valid)
                pnhi->valid = true;
index 389e5e8be0db189d04ad03ea0aff0355fbd94fe2..3284607406d09d481b192c61239ad82aa1c10936 100644 (file)
@@ -26,6 +26,7 @@
 #include "pbr_map.h"
 #include "pbr_debug.h"
 #include "pbr_nht.h"
+#include "pbr_zebra.h"
 
 DEFINE_MTYPE_STATIC(PBRD, PBR_MAP_VRF, "PBR Map VRF")
 
@@ -137,3 +138,14 @@ void pbr_vrf_init(void)
        vrf_init(pbr_vrf_new, pbr_vrf_enable, pbr_vrf_disable, pbr_vrf_delete,
                 NULL);
 }
+
+void pbr_vrf_terminate(void)
+{
+       struct vrf *vrf;
+       struct interface *ifp;
+
+       RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+               FOR_ALL_INTERFACES (vrf, ifp)
+                       pbr_if_del(ifp);
+       }
+}
index c9448762ebf843ec0c4c18f47392ef888190d129..5953387de22d6527c2ae5693f489bc32845ab6a9 100644 (file)
@@ -40,4 +40,5 @@ extern bool pbr_vrf_is_valid(const struct pbr_vrf *pbr_vrf);
 extern bool pbr_vrf_is_enabled(const struct pbr_vrf *pbr_vrf);
 
 extern void pbr_vrf_init(void);
+extern void pbr_vrf_terminate(void);
 #endif
index 9f966f617ff4911733d9df781ed23a34750f1584..26163dcc56de3e5fdfb7d3f7c3058f9e2330978f 100644 (file)
@@ -648,7 +648,6 @@ pbrms_nexthop_group_write_individual_nexthop(
 static void vty_show_pbrms(struct vty *vty,
                           const struct pbr_map_sequence *pbrms, bool detail)
 {
-       char buf[PREFIX_STRLEN];
        char rbuf[64];
 
        if (pbrms->reason)
@@ -666,11 +665,9 @@ static void vty_show_pbrms(struct vty *vty,
                        pbrms->reason ? rbuf : "Valid");
 
        if (pbrms->src)
-               vty_out(vty, "        SRC Match: %s\n",
-                       prefix2str(pbrms->src, buf, sizeof(buf)));
+               vty_out(vty, "        SRC Match: %pFX\n", pbrms->src);
        if (pbrms->dst)
-               vty_out(vty, "        DST Match: %s\n",
-                       prefix2str(pbrms->dst, buf, sizeof(buf)));
+               vty_out(vty, "        DST Match: %pFX\n", pbrms->dst);
        if (pbrms->dsfield & PBR_DSFIELD_DSCP)
                vty_out(vty, "        DSCP Match: %u\n",
                        (pbrms->dsfield & PBR_DSFIELD_DSCP) >> 2);
@@ -910,16 +907,22 @@ DEFPY (show_pbr_interface,
                        if (j)
                                this_iface = json_object_new_object();
 
-                       if (!ifp->info)
+                       if (!ifp->info) {
+                               json_object_free(this_iface);
                                continue;
+                       }
 
-                       if (name && strcmp(ifp->name, name) != 0)
+                       if (name && strcmp(ifp->name, name) != 0) {
+                               json_object_free(this_iface);
                                continue;
+                       }
 
                        pbr_ifp = ifp->info;
 
-                       if (strcmp(pbr_ifp->mapname, "") == 0)
+                       if (strcmp(pbr_ifp->mapname, "") == 0) {
+                               json_object_free(this_iface);
                                continue;
+                       }
 
                        pbrm = pbrm_find(pbr_ifp->mapname);
 
@@ -1058,17 +1061,13 @@ static int pbr_vty_map_config_write_sequence(struct vty *vty,
                                             struct pbr_map *pbrm,
                                             struct pbr_map_sequence *pbrms)
 {
-       char buff[PREFIX_STRLEN];
-
        vty_out(vty, "pbr-map %s seq %u\n", pbrm->name, pbrms->seqno);
 
        if (pbrms->src)
-               vty_out(vty, " match src-ip %s\n",
-                       prefix2str(pbrms->src, buff, sizeof(buff)));
+               vty_out(vty, " match src-ip %pFX\n", pbrms->src);
 
        if (pbrms->dst)
-               vty_out(vty, " match dst-ip %s\n",
-                       prefix2str(pbrms->dst, buff, sizeof(buff)));
+               vty_out(vty, " match dst-ip %pFX\n", pbrms->dst);
 
        if (pbrms->dsfield & PBR_DSFIELD_DSCP)
                vty_out(vty, " match dscp %u\n",
@@ -1145,9 +1144,9 @@ void pbr_vty_init(void)
 
        /* debug */
        install_node(&debug_node);
-       install_element(VIEW_NODE, &debug_pbr_cmd);
+       install_element(ENABLE_NODE, &debug_pbr_cmd);
        install_element(CONFIG_NODE, &debug_pbr_cmd);
-       install_element(VIEW_NODE, &show_debugging_pbr_cmd);
+       install_element(ENABLE_NODE, &show_debugging_pbr_cmd);
 
        install_default(PBRMAP_NODE);
 
index 866f27136eeaaa1e368341a1c481adcde8e0f873..32660b4dee121febedf89bc740bc1994814f5d63 100644 (file)
@@ -59,6 +59,11 @@ struct pbr_interface *pbr_if_new(struct interface *ifp)
        return pbr_ifp;
 }
 
+void pbr_if_del(struct interface *ifp)
+{
+       XFREE(MTYPE_PBR_INTERFACE, ifp->info);
+}
+
 /* Inteface addition message from zebra. */
 int pbr_ifp_create(struct interface *ifp)
 {
@@ -102,15 +107,14 @@ static int interface_address_add(ZAPI_CALLBACK_ARGS)
 static int interface_address_delete(ZAPI_CALLBACK_ARGS)
 {
        struct connected *c;
-       char buf[PREFIX_STRLEN];
 
        c = zebra_interface_address_read(cmd, zclient->ibuf, vrf_id);
 
        if (!c)
                return 0;
 
-       DEBUGD(&pbr_dbg_zebra, "%s: %s deleted %s", __func__, c->ifp->name,
-              prefix2str(c->address, buf, sizeof(buf)));
+       DEBUGD(&pbr_dbg_zebra, "%s: %s deleted %pFX", __func__, c->ifp->name,
+              c->address);
 
        connected_free(&c);
        return 0;
@@ -162,40 +166,37 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS)
        struct prefix p;
        enum zapi_route_notify_owner note;
        uint32_t table_id;
-       char buf[PREFIX_STRLEN];
 
        if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note))
                return -1;
 
-       prefix2str(&p, buf, sizeof(buf));
-
        switch (note) {
        case ZAPI_ROUTE_FAIL_INSTALL:
                DEBUGD(&pbr_dbg_zebra,
-                      "%s: [%s] Route install failure for table: %u", __func__,
-                      buf, table_id);
+                      "%s: [%pFX] Route install failure for table: %u",
+                      __func__, &p, table_id);
                break;
        case ZAPI_ROUTE_BETTER_ADMIN_WON:
                DEBUGD(&pbr_dbg_zebra,
-                      "%s: [%s] Route better admin distance won for table: %u",
-                      __func__, buf, table_id);
+                      "%s: [%pFX] Route better admin distance won for table: %u",
+                      __func__, &p, table_id);
                break;
        case ZAPI_ROUTE_INSTALLED:
                DEBUGD(&pbr_dbg_zebra,
-                      "%s: [%s] Route installed succeeded for table: %u",
-                      __func__, buf, table_id);
+                      "%s: [%pFX] Route installed succeeded for table: %u",
+                      __func__, &p, table_id);
                pbr_nht_route_installed_for_table(table_id);
                break;
        case ZAPI_ROUTE_REMOVED:
                DEBUGD(&pbr_dbg_zebra,
-                      "%s: [%s] Route Removed succeeded for table: %u",
-                      __func__, buf, table_id);
+                      "%s: [%pFX] Route Removed succeeded for table: %u",
+                      __func__, &p, table_id);
                pbr_nht_route_removed_for_table(table_id);
                break;
        case ZAPI_ROUTE_REMOVE_FAIL:
                DEBUGD(&pbr_dbg_zebra,
-                      "%s: [%s] Route remove fail for table: %u", __func__,
-                      buf, table_id);
+                      "%s: [%pFX] Route remove fail for table: %u", __func__,
+                      &p, table_id);
                break;
        }
 
@@ -259,14 +260,12 @@ static void route_add_helper(struct zapi_route *api, struct nexthop_group nhg,
                             uint8_t install_afi)
 {
        struct zapi_nexthop *api_nh;
-       char buf[PREFIX_STRLEN];
        struct nexthop *nhop;
        int i;
 
        api->prefix.family = install_afi;
 
-       DEBUGD(&pbr_dbg_zebra, "\tEncoding %s",
-              prefix2str(&api->prefix, buf, sizeof(buf)));
+       DEBUGD(&pbr_dbg_zebra, "\tEncoding %pFX", &api->prefix);
 
        i = 0;
        for (ALL_NEXTHOPS(nhg, nhop)) {
@@ -397,7 +396,6 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi)
 static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
 {
        struct zapi_route nhr;
-       char buf[PREFIX2STR_BUFFER];
        uint32_t i;
 
        if (!zapi_nexthop_update_decode(zclient->ibuf, &nhr)) {
@@ -407,18 +405,18 @@ static int pbr_zebra_nexthop_update(ZAPI_CALLBACK_ARGS)
 
        if (DEBUG_MODE_CHECK(&pbr_dbg_zebra, DEBUG_MODE_ALL)) {
 
-               DEBUGD(&pbr_dbg_zebra, "%s: Received Nexthop update: %s",
-                      __func__, prefix2str(&nhr.prefix, buf, sizeof(buf)));
+               DEBUGD(&pbr_dbg_zebra, "%s: Received Nexthop update: %pFX",
+                      __func__, &nhr.prefix);
 
                DEBUGD(&pbr_dbg_zebra, "%s: (\tNexthops(%u)", __func__,
                       nhr.nexthop_num);
 
                for (i = 0; i < nhr.nexthop_num; i++) {
                        DEBUGD(&pbr_dbg_zebra,
-                              "%s: \tType: %d: vrf: %d, ifindex: %d gate: %s",
+                              "%s: \tType: %d: vrf: %d, ifindex: %d gate: %pI4",
                               __func__, nhr.nexthops[i].type,
                               nhr.nexthops[i].vrf_id, nhr.nexthops[i].ifindex,
-                              inet_ntoa(nhr.nexthops[i].gate.ipv4));
+                              &nhr.nexthops[i].gate.ipv4);
                }
        }
 
index e8f9bff5d9dd96079c358e5d13659a8bfd6fef7d..d0f9ff910ca4fefd604ab187d60b80595bd39b89 100644 (file)
@@ -46,4 +46,7 @@ extern int pbr_ifp_up(struct interface *ifp);
 extern int pbr_ifp_down(struct interface *ifp);
 extern int pbr_ifp_destroy(struct interface *ifp);
 
+/* Free the ifp->info pointer */
+extern void pbr_if_del(struct interface *ifp);
+
 #endif
index 1b812de92c72068729406af6f29a397b07d4032e..3b69964960f93608a25015cec74df14011f55fe3 100644 (file)
@@ -26,7 +26,6 @@
 #include "checksum.h"
 #include "prefix.h"
 #include "mtracebis_routeget.h"
-
 #include <sys/select.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
@@ -64,13 +63,14 @@ static void version(void)
 static void print_host(struct in_addr addr)
 {
        struct hostent *h;
+       char buf[PREFIX_STRLEN];
 
        h = gethostbyaddr(&addr, sizeof(addr), AF_INET);
        if (h == NULL)
                printf("?");
        else
                printf("%s", h->h_name);
-       printf(" (%s) ", inet_ntoa(addr));
+       printf(" (%s) ", inet_ntop(AF_INET, &addr, buf, sizeof(buf)));
 }
 
 static void print_line_no(int i)
index 146b53fa8f7fdbd98ca643c76d2a9e0a97357fd9..1d653cdc3f01c5bb48731af1389cfd192654f6cd 100644 (file)
@@ -244,12 +244,9 @@ static int pim_bfd_interface_dest_update(ZAPI_CALLBACK_ARGS)
                return 0;
        }
 
-       if (PIM_DEBUG_PIM_TRACE) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&p, buf, sizeof(buf));
-               zlog_debug("%s: interface %s bfd destination %s %s", __func__,
-                          ifp->name, buf, bfd_get_status_str(status));
-       }
+       if (PIM_DEBUG_PIM_TRACE)
+               zlog_debug("%s: interface %s bfd destination %pFX %s", __func__,
+                          ifp->name, &p, bfd_get_status_str(status));
 
        for (ALL_LIST_ELEMENTS(pim_ifp->pim_neighbor_list, neigh_node,
                               neigh_nextnode, neigh)) {
index 1c9005588fe08ea7dce4f8817f05fa0b728805fc..1acfece895a0aaeed020b01e19273355552facc5 100644 (file)
@@ -117,8 +117,7 @@ static int pim_g2rp_list_compare(struct bsm_rpinfo *node1,
 
 static void pim_free_bsrp_node(struct bsm_rpinfo *bsrp_info)
 {
-       if (bsrp_info->g2rp_timer)
-               THREAD_OFF(bsrp_info->g2rp_timer);
+       THREAD_OFF(bsrp_info->g2rp_timer);
        XFREE(MTYPE_PIM_BSRP_NODE, bsrp_info);
 }
 
@@ -171,7 +170,6 @@ static int pim_on_bs_timer(struct thread *t)
        struct bsgrp_node *bsgrp_node;
        struct bsm_rpinfo *bsrp;
        struct prefix nht_p;
-       char buf[PREFIX2STR_BUFFER];
        bool is_bsr_tracking = true;
 
        scope = THREAD_ARG(t);
@@ -185,11 +183,9 @@ static int pim_on_bs_timer(struct thread *t)
        nht_p.family = AF_INET;
        nht_p.prefixlen = IPV4_MAX_BITLEN;
        nht_p.u.prefix4 = scope->current_bsr;
-       if (PIM_DEBUG_BSM) {
-               prefix2str(&nht_p, buf, sizeof(buf));
-               zlog_debug("%s: Deregister BSR addr %s with Zebra NHT",
-                          __func__, buf);
-       }
+       if (PIM_DEBUG_BSM)
+               zlog_debug("%s: Deregister BSR addr %pFX with Zebra NHT",
+                          __func__, &nht_p);
        pim_delete_tracked_nexthop(scope->pim, &nht_p, NULL, NULL,
                                   is_bsr_tracking);
 
@@ -378,15 +374,12 @@ static void pim_g2rp_timer_start(struct bsm_rpinfo *bsrp, int hold_time)
                return;
        }
        THREAD_OFF(bsrp->g2rp_timer);
-       if (PIM_DEBUG_BSM) {
-               char buf[48];
-
+       if (PIM_DEBUG_BSM)
                zlog_debug(
-                       "%s : starting g2rp timer for grp: %s - rp: %s with timeout  %d secs(Actual Hold time : %d secs)",
-                       __func__, prefix2str(&bsrp->bsgrp_node->group, buf, 48),
-                       inet_ntoa(bsrp->rp_address), hold_time,
+                       "%s : starting g2rp timer for grp: %pFX - rp: %pI4 with timeout  %d secs(Actual Hold time : %d secs)",
+                       __func__, &bsrp->bsgrp_node->group,
+                       &bsrp->rp_address, hold_time,
                        bsrp->rp_holdtime);
-       }
 
        thread_add_timer(router->master, pim_on_g2rp_timer, bsrp, hold_time,
                         &bsrp->g2rp_timer);
@@ -403,14 +396,10 @@ static void pim_g2rp_timer_stop(struct bsm_rpinfo *bsrp)
        if (!bsrp)
                return;
 
-       if (PIM_DEBUG_BSM) {
-               char buf[48];
-
-               zlog_debug("%s : stopping g2rp timer for grp: %s - rp: %s",
-                          __func__,
-                          prefix2str(&bsrp->bsgrp_node->group, buf, 48),
-                          inet_ntoa(bsrp->rp_address));
-       }
+       if (PIM_DEBUG_BSM)
+               zlog_debug("%s : stopping g2rp timer for grp: %pFX - rp: %pI4",
+                          __func__, &bsrp->bsgrp_node->group,
+                          &bsrp->rp_address);
 
        THREAD_OFF(bsrp->g2rp_timer);
 }
@@ -617,7 +606,6 @@ static void pim_bsm_update(struct pim_instance *pim, struct in_addr bsr,
 
        if (bsr.s_addr != pim->global_scope.current_bsr.s_addr) {
                struct prefix nht_p;
-               char buf[PREFIX2STR_BUFFER];
                bool is_bsr_tracking = true;
 
                /* De-register old BSR and register new BSR with Zebra NHT */
@@ -626,23 +614,19 @@ static void pim_bsm_update(struct pim_instance *pim, struct in_addr bsr,
 
                if (pim->global_scope.current_bsr.s_addr != INADDR_ANY) {
                        nht_p.u.prefix4 = pim->global_scope.current_bsr;
-                       if (PIM_DEBUG_BSM) {
-                               prefix2str(&nht_p, buf, sizeof(buf));
+                       if (PIM_DEBUG_BSM)
                                zlog_debug(
-                                       "%s: Deregister BSR addr %s with Zebra NHT",
-                                       __func__, buf);
-                       }
+                                       "%s: Deregister BSR addr %pFX with Zebra NHT",
+                                       __func__, &nht_p);
                        pim_delete_tracked_nexthop(pim, &nht_p, NULL, NULL,
                                                   is_bsr_tracking);
                }
 
                nht_p.u.prefix4 = bsr;
-               if (PIM_DEBUG_BSM) {
-                       prefix2str(&nht_p, buf, sizeof(buf));
+               if (PIM_DEBUG_BSM)
                        zlog_debug(
-                               "%s: NHT Register BSR addr %s with Zebra NHT",
-                               __func__, buf);
-               }
+                               "%s: NHT Register BSR addr %pFX with Zebra NHT",
+                               __func__, &nht_p);
 
                memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
                pim_find_or_track_nexthop(pim, &nht_p, NULL, NULL,
index db3f0b8b234903d317f6d372509c5aadbb574bd8..2a7ff4e7f8ecef5c6d46ac5c8592bb66bb24a019 100644 (file)
@@ -199,6 +199,7 @@ static void pim_show_assert_helper(struct vty *vty,
        struct in_addr ifaddr;
        char uptime[10];
        char timer[10];
+       char buf[PREFIX_STRLEN];
 
        ifaddr = pim_ifp->primary_address;
 
@@ -211,9 +212,10 @@ static void pim_show_assert_helper(struct vty *vty,
        pim_time_timer_to_mmss(timer, sizeof(timer), ch->t_ifassert_timer);
 
        vty_out(vty, "%-16s %-15s %-15s %-15s %-6s %-15s %-8s %-5s\n",
-               ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
-               pim_ifchannel_ifassert_name(ch->ifassert_state), winner_str,
-               uptime, timer);
+               ch->interface->name,
+               inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), ch_src_str,
+               ch_grp_str, pim_ifchannel_ifassert_name(ch->ifassert_state),
+               winner_str, uptime, timer);
 }
 
 static void pim_show_assert(struct pim_instance *pim, struct vty *vty)
@@ -246,13 +248,16 @@ static void pim_show_assert_internal_helper(struct vty *vty,
        char ch_src_str[INET_ADDRSTRLEN];
        char ch_grp_str[INET_ADDRSTRLEN];
        struct in_addr ifaddr;
+       char buf[PREFIX_STRLEN];
 
        ifaddr = pim_ifp->primary_address;
 
        pim_inet4_dump("<ch_src?>", ch->sg.src, ch_src_str, sizeof(ch_src_str));
        pim_inet4_dump("<ch_grp?>", ch->sg.grp, ch_grp_str, sizeof(ch_grp_str));
        vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-3s %-3s %-4s\n",
-               ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
+               ch->interface->name,
+               inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
+               ch_src_str, ch_grp_str,
                PIM_IF_FLAG_TEST_COULD_ASSERT(ch->flags) ? "yes" : "no",
                pim_macro_ch_could_assert_eval(ch) ? "yes" : "no",
                PIM_IF_FLAG_TEST_ASSERT_TRACKING_DESIRED(ch->flags) ? "yes"
@@ -294,6 +299,7 @@ static void pim_show_assert_metric_helper(struct vty *vty,
        char addr_str[INET_ADDRSTRLEN];
        struct pim_assert_metric am;
        struct in_addr ifaddr;
+       char buf[PREFIX_STRLEN];
 
        ifaddr = pim_ifp->primary_address;
 
@@ -305,9 +311,10 @@ static void pim_show_assert_metric_helper(struct vty *vty,
        pim_inet4_dump("<addr?>", am.ip_address, addr_str, sizeof(addr_str));
 
        vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %4u %6u %-15s\n",
-               ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
-               am.rpt_bit_flag ? "yes" : "no", am.metric_preference,
-               am.route_metric, addr_str);
+               ch->interface->name,
+               inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
+               ch_src_str, ch_grp_str, am.rpt_bit_flag ? "yes" : "no",
+               am.metric_preference, am.route_metric, addr_str);
 }
 
 static void pim_show_assert_metric(struct pim_instance *pim, struct vty *vty)
@@ -341,6 +348,7 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty,
        struct in_addr ifaddr;
        char pref_str[16];
        char metr_str[16];
+       char buf[PREFIX_STRLEN];
 
        ifaddr = pim_ifp->primary_address;
 
@@ -362,8 +370,10 @@ static void pim_show_assert_winner_metric_helper(struct vty *vty,
                snprintf(metr_str, sizeof(metr_str), "%6u", am->route_metric);
 
        vty_out(vty, "%-16s %-15s %-15s %-15s %-3s %-4s %-6s %-15s\n",
-               ch->interface->name, inet_ntoa(ifaddr), ch_src_str, ch_grp_str,
-               am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str, addr_str);
+               ch->interface->name,
+               inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)), ch_src_str,
+               ch_grp_str, am->rpt_bit_flag ? "yes" : "no", pref_str, metr_str,
+               addr_str);
 }
 
 static void pim_show_assert_winner_metric(struct pim_instance *pim,
@@ -391,12 +401,14 @@ static void json_object_pim_ifp_add(struct json_object *json,
                                    struct interface *ifp)
 {
        struct pim_interface *pim_ifp;
+       char buf[PREFIX_STRLEN];
 
        pim_ifp = ifp->info;
        json_object_string_add(json, "name", ifp->name);
        json_object_string_add(json, "state", if_is_up(ifp) ? "up" : "down");
        json_object_string_add(json, "address",
-                              inet_ntoa(pim_ifp->primary_address));
+                              inet_ntop(AF_INET, &pim_ifp->primary_address,
+                                        buf, sizeof(buf)));
        json_object_int_add(json, "index", ifp->ifindex);
 
        if (if_is_multicast(ifp))
@@ -569,6 +581,7 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
 {
        struct interface *ifp;
        time_t now;
+       char buf[PREFIX_STRLEN];
        json_object *json = NULL;
        json_object *json_row = NULL;
 
@@ -632,7 +645,8 @@ static void igmp_show_interfaces(struct pim_instance *pim, struct vty *vty,
                                                ? (igmp->mtrace_only ? "mtrc"
                                                                     : "up")
                                                : "down",
-                                       inet_ntoa(igmp->ifaddr),
+                                       inet_ntop(AF_INET, &igmp->ifaddr,
+                                                 buf, sizeof(buf)),
                                        pim_ifp->igmp_version,
                                        igmp->t_igmp_query_timer ? "local"
                                                                 : "other",
@@ -797,8 +811,8 @@ static void igmp_show_interfaces_single(struct pim_instance *pim,
                                                ? (igmp->mtrace_only ? "mtrace"
                                                                     : "up")
                                                : "down");
-                               vty_out(vty, "Address   : %s\n",
-                                       inet_ntoa(pim_ifp->primary_address));
+                               vty_out(vty, "Address   : %pI4\n",
+                                       &pim_ifp->primary_address);
                                vty_out(vty, "Uptime    : %s\n", uptime);
                                vty_out(vty, "Version   : %d\n",
                                        pim_ifp->igmp_version);
@@ -940,6 +954,7 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
        int mloop = 0;
        int found_ifname = 0;
        int print_header;
+       char buf[PREFIX_STRLEN];
        json_object *json = NULL;
        json_object *json_row = NULL;
        json_object *json_pim_neighbor = NULL;
@@ -992,7 +1007,9 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
                        if (pim_ifp->update_source.s_addr != INADDR_ANY) {
                                json_object_string_add(
                                        json_row, "useSource",
-                                       inet_ntoa(pim_ifp->update_source));
+                                       inet_ntop(AF_INET,
+                                                 &pim_ifp->update_source,
+                                                 buf, sizeof(buf)));
                        }
                        if (pim_ifp->sec_addr_list) {
                                json_object *sec_list = NULL;
@@ -1160,23 +1177,20 @@ static void pim_show_interfaces_single(struct pim_instance *pim,
                        vty_out(vty, "State      : %s\n",
                                if_is_up(ifp) ? "up" : "down");
                        if (pim_ifp->update_source.s_addr != INADDR_ANY) {
-                               vty_out(vty, "Use Source : %s\n",
-                                       inet_ntoa(pim_ifp->update_source));
+                               vty_out(vty, "Use Source : %pI4\n",
+                                       &pim_ifp->update_source);
                        }
                        if (pim_ifp->sec_addr_list) {
-                               char pbuf[PREFIX2STR_BUFFER];
-                               vty_out(vty, "Address    : %s (primary)\n",
-                                       inet_ntoa(ifaddr));
+                               vty_out(vty, "Address    : %pI4 (primary)\n",
+                                       &ifaddr);
                                for (ALL_LIST_ELEMENTS_RO(
                                             pim_ifp->sec_addr_list, sec_node,
-                                            sec_addr)) {
-                                       vty_out(vty, "             %s\n",
-                                               prefix2str(&sec_addr->addr,
-                                                          pbuf, sizeof(pbuf)));
-                               }
+                                            sec_addr))
+                                       vty_out(vty, "             %pFX\n",
+                                               &sec_addr->addr);
                        } else {
-                               vty_out(vty, "Address    : %s\n",
-                                       inet_ntoa(ifaddr));
+                               vty_out(vty, "Address    : %pI4\n",
+                                       &ifaddr);
                        }
                        vty_out(vty, "\n");
 
@@ -1400,6 +1414,7 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
        int fhr = 0;
        int pim_nbrs = 0;
        int pim_ifchannels = 0;
+       char buf[PREFIX_STRLEN];
        json_object *json = NULL;
        json_object *json_row = NULL;
        json_object *json_tmp;
@@ -1430,7 +1445,9 @@ static void pim_show_interfaces(struct pim_instance *pim, struct vty *vty,
                json_object_int_add(json_row, "pimIfChannels", pim_ifchannels);
                json_object_int_add(json_row, "firstHopRouterCount", fhr);
                json_object_string_add(json_row, "pimDesignatedRouter",
-                                      inet_ntoa(pim_ifp->pim_dr_addr));
+                                      inet_ntop(AF_INET,
+                                                &pim_ifp->pim_dr_addr, buf,
+                                                sizeof(buf)));
 
                if (pim_ifp->pim_dr_addr.s_addr
                    == pim_ifp->primary_address.s_addr)
@@ -1685,6 +1702,7 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
        char uptime[10];
        char expire[10];
        char prune[10];
+       char buf[PREFIX_STRLEN];
 
        ifaddr = pim_ifp->primary_address;
 
@@ -1733,8 +1751,9 @@ static void pim_show_join_helper(struct vty *vty, struct pim_interface *pim_ifp,
                        json_object_object_add(json_grp, ch_src_str, json_row);
        } else {
                vty_out(vty, "%-16s %-15s %-15s %-15s %-10s %8s %-6s %5s\n",
-                       ch->interface->name, inet_ntoa(ifaddr), ch_src_str,
-                       ch_grp_str,
+                       ch->interface->name,
+                       inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
+                       ch_src_str, ch_grp_str,
                        pim_ifchannel_ifjoin_name(ch->ifjoin_state, ch->flags),
                        uptime, expire, prune);
        }
@@ -2307,6 +2326,7 @@ static void pim_show_neighbors_secondary(struct pim_instance *pim,
                struct in_addr ifaddr;
                struct listnode *neighnode;
                struct pim_neighbor *neigh;
+               char buf[PREFIX_STRLEN];
 
                pim_ifp = ifp->info;
 
@@ -2331,16 +2351,12 @@ static void pim_show_neighbors_secondary(struct pim_instance *pim,
                                       neigh_src_str, sizeof(neigh_src_str));
 
                        for (ALL_LIST_ELEMENTS_RO(neigh->prefix_list,
-                                                 prefix_node, p)) {
-                               char neigh_sec_str[PREFIX2STR_BUFFER];
-
-                               prefix2str(p, neigh_sec_str,
-                                          sizeof(neigh_sec_str));
-
-                               vty_out(vty, "%-16s %-15s %-15s %-15s\n",
-                                       ifp->name, inet_ntoa(ifaddr),
-                                       neigh_src_str, neigh_sec_str);
-                       }
+                                                 prefix_node, p))
+                               vty_out(vty, "%-16s %-15s %-15s %-15pFX\n",
+                                       ifp->name,
+                                       inet_ntop(AF_INET, &ifaddr,
+                                                 buf, sizeof(buf)),
+                                       neigh_src_str, p);
                }
        }
 }
@@ -2984,14 +3000,17 @@ static int pim_print_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
        struct nexthop *nh_node = NULL;
        ifindex_t first_ifindex;
        struct interface *ifp = NULL;
+       char buf[PREFIX_STRLEN];
 
        for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) {
                first_ifindex = nh_node->ifindex;
                ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
 
-               vty_out(vty, "%-15s ", inet_ntoa(pnc->rpf.rpf_addr.u.prefix4));
+               vty_out(vty, "%-15s ", inet_ntop(AF_INET,
+                                                &pnc->rpf.rpf_addr.u.prefix4,
+                                                buf, sizeof(buf)));
                vty_out(vty, "%-16s ", ifp ? ifp->name : "NULL");
-               vty_out(vty, "%s ", inet_ntoa(nh_node->gate.ipv4));
+               vty_out(vty, "%pI4 ", &nh_node->gate.ipv4);
                vty_out(vty, "\n");
        }
        return CMD_SUCCESS;
@@ -3215,7 +3234,7 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
                                                       json_group);
                        }
                } else {
-                       vty_out(vty, "Group Address %s\n", grp_str);
+                       vty_out(vty, "Group Address %pFX\n", &bsgrp->group);
                        vty_out(vty, "--------------------------\n");
                        vty_out(vty, "%-15s %-15s %-15s %-15s\n", "Rp Address",
                                "priority", "Holdtime", "Hash");
@@ -5665,6 +5684,7 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
                                      bool uj)
 {
        struct interface *ifp;
+       char buf[PREFIX_STRLEN];
        json_object *json = NULL;
        json_object *json_row = NULL;
 
@@ -5705,7 +5725,8 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
                                               if_is_up(ifp) ? "up" : "down");
                        json_object_string_add(
                                json_row, "address",
-                               inet_ntoa(pim_ifp->primary_address));
+                               inet_ntop(AF_INET, &pim_ifp->primary_address,
+                                         buf, sizeof(buf)));
                        json_object_int_add(json_row, "ifIndex", ifp->ifindex);
                        json_object_int_add(json_row, "vif",
                                            pim_ifp->mroute_vif_index);
@@ -5721,8 +5742,9 @@ static void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
                } else {
                        vty_out(vty,
                                "%-16s %-15s %3d %3d %7lu %7lu %10lu %10lu\n",
-                               ifp->name, inet_ntoa(ifaddr), ifp->ifindex,
-                               pim_ifp->mroute_vif_index,
+                               ifp->name,
+                               inet_ntop(AF_INET, &ifaddr, buf, sizeof(buf)),
+                               ifp->ifindex, pim_ifp->mroute_vif_index,
                                (unsigned long)vreq.icount,
                                (unsigned long)vreq.ocount,
                                (unsigned long)vreq.ibytes,
@@ -9694,7 +9716,7 @@ static int ip_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
        return ret;
 }
 
-DEFUN_HIDDEN (ip_msdp_peer,
+DEFUN (ip_msdp_peer,
        ip_msdp_peer_cmd,
        "ip msdp peer A.B.C.D source A.B.C.D",
        IP_STR
@@ -9735,7 +9757,7 @@ static int ip_no_msdp_peer_cmd_worker(struct pim_instance *pim, struct vty *vty,
        return result ? CMD_WARNING_CONFIG_FAILED : CMD_SUCCESS;
 }
 
-DEFUN_HIDDEN (no_ip_msdp_peer,
+DEFUN (no_ip_msdp_peer,
        no_ip_msdp_peer_cmd,
        "no ip msdp peer A.B.C.D",
        NO_STR
@@ -11236,7 +11258,6 @@ void pim_cmd_init(void)
        install_element(VIEW_NODE, &show_ip_mroute_summary_vrf_all_cmd);
        install_element(VIEW_NODE, &show_ip_rib_cmd);
        install_element(VIEW_NODE, &show_ip_ssmpingd_cmd);
-       install_element(VIEW_NODE, &show_debugging_pim_cmd);
        install_element(VIEW_NODE, &show_ip_pim_nexthop_cmd);
        install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
        install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
@@ -11252,6 +11273,8 @@ void pim_cmd_init(void)
        install_element(ENABLE_NODE, &clear_ip_pim_oil_cmd);
        install_element(ENABLE_NODE, &clear_ip_pim_statistics_cmd);
 
+       install_element(ENABLE_NODE, &show_debugging_pim_cmd);
+
        install_element(ENABLE_NODE, &debug_igmp_cmd);
        install_element(ENABLE_NODE, &no_debug_igmp_cmd);
        install_element(ENABLE_NODE, &debug_igmp_events_cmd);
index 0caa360df92a7a4cc76fb70766c442b04f5f2d45..cff237f965962e5361e18edd2dd784983f684c3c 100644 (file)
@@ -518,15 +518,12 @@ void pim_if_addr_add(struct connected *ifc)
        if (!if_is_operative(ifp))
                return;
 
-       if (PIM_DEBUG_ZEBRA) {
-               char buf[BUFSIZ];
-               prefix2str(ifc->address, buf, BUFSIZ);
-               zlog_debug("%s: %s ifindex=%d connected IP address %s %s",
-                          __func__, ifp->name, ifp->ifindex, buf,
+       if (PIM_DEBUG_ZEBRA)
+               zlog_debug("%s: %s ifindex=%d connected IP address %pFX %s",
+                          __func__, ifp->name, ifp->ifindex, ifc->address,
                           CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
                                   ? "secondary"
                                   : "primary");
-       }
 
        ifaddr = ifc->address->u.prefix4;
 
@@ -715,15 +712,12 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
        ifp = ifc->ifp;
        zassert(ifp);
 
-       if (PIM_DEBUG_ZEBRA) {
-               char buf[BUFSIZ];
-               prefix2str(ifc->address, buf, BUFSIZ);
-               zlog_debug("%s: %s ifindex=%d disconnected IP address %s %s",
-                          __func__, ifp->name, ifp->ifindex, buf,
+       if (PIM_DEBUG_ZEBRA)
+               zlog_debug("%s: %s ifindex=%d disconnected IP address %pFX %s",
+                          __func__, ifp->name, ifp->ifindex, ifc->address,
                           CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
                                   ? "secondary"
                                   : "primary");
-       }
 
        detect_address_change(ifp, force_prim_as_any, __func__);
 
index 212c77c039dc6d630f56fdef78245a9a01536778..b2971e5f1feb6bc124fe088c617f111e2c75b04d 100644 (file)
@@ -950,14 +950,44 @@ void pim_ifchannel_join_add(struct interface *ifp, struct in_addr neigh_addr,
                        pim_ifchannel_ifjoin_handler(ch, pim_ifp);
                break;
        case PIM_IFJOIN_PRUNE_PENDING:
+               /*
+                * Transitions from Prune-Pending State (Receive Join)
+                * RFC 7761 Sec 4.5.2:
+                *    The (S,G) downstream state machine on interface I
+                * transitions to the Join state.  The Prune-Pending Timer is
+                * canceled (without triggering an expiry event).  The
+                * Expiry Timer (ET) is restarted and is then set to the
+                * maximum of its current value and the HoldTime from the
+                * triggering Join/Prune message.
+                */
                THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
-               if (source_flags & PIM_ENCODE_RPT_BIT) {
+
+               /* Check if SGRpt join Received */
+               if ((source_flags & PIM_ENCODE_RPT_BIT)
+                   && (sg->src.s_addr != INADDR_ANY)) {
+                       /*
+                        * Transitions from Prune-Pending State (Rcv SGRpt Join)
+                        * RFC 7761 Sec 4.5.3:
+                        * The (S,G,rpt) downstream state machine on interface
+                        * I transitions to the NoInfo state.The ET and PPT are
+                        * cancelled.
+                        */
                        THREAD_OFF(ch->t_ifjoin_expiry_timer);
                        pim_ifchannel_ifjoin_switch(__func__, ch,
                                                    PIM_IFJOIN_NOINFO);
-               } else {
-                       pim_ifchannel_ifjoin_handler(ch, pim_ifp);
+                       return;
                }
+
+               pim_ifchannel_ifjoin_handler(ch, pim_ifp);
+
+               if (ch->t_ifjoin_expiry_timer) {
+                       unsigned long remain = thread_timer_remain_second(
+                               ch->t_ifjoin_expiry_timer);
+
+                       if (remain > holdtime)
+                               return;
+               }
+
                break;
        case PIM_IFJOIN_PRUNE_TMP:
                break;
@@ -1034,7 +1064,14 @@ void pim_ifchannel_prune(struct interface *ifp, struct in_addr upstream,
                /* nothing to do */
                break;
        case PIM_IFJOIN_JOIN:
-               THREAD_OFF(ch->t_ifjoin_expiry_timer);
+               /*
+                * The (S,G) downstream state machine on interface I
+                * transitions to the Prune-Pending state.  The
+                * Prune-Pending Timer is started.  It is set to the
+                * J/P_Override_Interval(I) if the router has more than one
+                * neighbor on that interface; otherwise, it is set to zero,
+                * causing it to expire immediately.
+                */
 
                pim_ifchannel_ifjoin_switch(__func__, ch,
                                            PIM_IFJOIN_PRUNE_PENDING);
index 04ece6dbb0d85787675de4fc28affa6de53e5b0e..19d78175772c8fd422b50af7a77308cb02c0b101 100644 (file)
@@ -63,8 +63,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
                                ++join;
                } else {
                        zlog_warn(
-                               "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
-                               __FILE__, __func__, fd, inet_ntoa(ifaddr),
+                               "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s",
+                               __FILE__, __func__, fd, &ifaddr,
                                PIM_ALL_ROUTERS, errno, safe_strerror(errno));
                }
        }
@@ -79,8 +79,8 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
                        ++join;
        } else {
                zlog_warn(
-                       "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
-                       __FILE__, __func__, fd, inet_ntoa(ifaddr),
+                       "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s",
+                       __FILE__, __func__, fd, &ifaddr,
                        PIM_ALL_SYSTEMS, errno, safe_strerror(errno));
        }
 
@@ -90,16 +90,16 @@ static int igmp_sock_open(struct in_addr ifaddr, struct interface *ifp,
                }
        } else {
                zlog_warn(
-                       "%s %s: IGMP socket fd=%d interface %s: could not solve %s to group address: errno=%d: %s",
-                       __FILE__, __func__, fd, inet_ntoa(ifaddr),
+                       "%s %s: IGMP socket fd=%d interface %pI4: could not solve %s to group address: errno=%d: %s",
+                       __FILE__, __func__, fd, &ifaddr,
                        PIM_ALL_IGMP_ROUTERS, errno, safe_strerror(errno));
        }
 
        if (!join) {
                flog_err_sys(
                        EC_LIB_SOCKET,
-                       "IGMP socket fd=%d could not join any group on interface address %s",
-                       fd, inet_ntoa(ifaddr));
+                       "IGMP socket fd=%d could not join any group on interface address %pI4",
+                       fd, &ifaddr);
                close(fd);
                fd = -1;
        }
@@ -117,8 +117,8 @@ static void igmp_sock_dump(array_t *igmp_sock_array)
 
                struct igmp_sock *igmp = array_get(igmp_sock_array, i);
 
-               zlog_debug("%s %s: [%d/%d] igmp_addr=%s fd=%d", __FILE__,
-                          __func__, i, size, inet_ntoa(igmp->ifaddr),
+               zlog_debug("%s %s: [%d/%d] igmp_addr=%pI4 fd=%d", __FILE__,
+                          __func__, i, size, &igmp->ifaddr,
                           igmp->fd);
        }
 }
@@ -701,8 +701,8 @@ static void sock_close(struct igmp_sock *igmp)
        if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
                if (igmp->t_igmp_read) {
                        zlog_debug(
-                               "Cancelling READ event on IGMP socket %s fd=%d on interface %s",
-                               inet_ntoa(igmp->ifaddr), igmp->fd,
+                               "Cancelling READ event on IGMP socket %pI4 fd=%d on interface %s",
+                               &igmp->ifaddr, igmp->fd,
                                igmp->interface->name);
                }
        }
@@ -711,14 +711,14 @@ static void sock_close(struct igmp_sock *igmp)
        if (close(igmp->fd)) {
                flog_err(
                        EC_LIB_SOCKET,
-                       "Failure closing IGMP socket %s fd=%d on interface %s: errno=%d: %s",
-                       inet_ntoa(igmp->ifaddr), igmp->fd,
+                       "Failure closing IGMP socket %pI4 fd=%d on interface %s: errno=%d: %s",
+                       &igmp->ifaddr, igmp->fd,
                        igmp->interface->name, errno, safe_strerror(errno));
        }
 
        if (PIM_DEBUG_IGMP_TRACE_DETAIL) {
-               zlog_debug("Deleted IGMP socket %s fd=%d on interface %s",
-                          inet_ntoa(igmp->ifaddr), igmp->fd,
+               zlog_debug("Deleted IGMP socket %pI4 fd=%d on interface %s",
+                          &igmp->ifaddr, igmp->fd,
                           igmp->interface->name);
        }
 }
@@ -804,9 +804,7 @@ void igmp_group_delete(struct igmp_group *group)
                igmp_source_delete(src);
        }
 
-       if (group->t_group_query_retransmit_timer) {
-               THREAD_OFF(group->t_group_query_retransmit_timer);
-       }
+       THREAD_OFF(group->t_group_query_retransmit_timer);
 
        group_timer_off(group);
        igmp_group_count_decr(group->group_igmp_sock);
@@ -902,8 +900,8 @@ static struct igmp_sock *igmp_sock_new(int fd, struct in_addr ifaddr,
 
        if (PIM_DEBUG_IGMP_TRACE) {
                zlog_debug(
-                       "Creating IGMP socket fd=%d for address %s on interface %s",
-                       fd, inet_ntoa(ifaddr), ifp->name);
+                       "Creating IGMP socket fd=%d for address %pI4 on interface %s",
+                       fd, &ifaddr, ifp->name);
        }
 
        igmp = XCALLOC(MTYPE_PIM_IGMP_SOCKET, sizeof(*igmp));
@@ -1002,8 +1000,8 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
 
        fd = igmp_sock_open(ifaddr, ifp, pim_ifp->options);
        if (fd < 0) {
-               zlog_warn("Could not open IGMP socket for %s on %s",
-                         inet_ntoa(ifaddr), ifp->name);
+               zlog_warn("Could not open IGMP socket for %pI4 on %s",
+                         &ifaddr, ifp->name);
                return NULL;
        }
 
@@ -1011,8 +1009,8 @@ struct igmp_sock *pim_igmp_sock_add(struct list *igmp_sock_list,
        sin.sin_addr = ifaddr;
        sin.sin_port = 0;
        if (bind(fd, (struct sockaddr *) &sin, sizeof(sin)) != 0) {
-               zlog_warn("Could not bind IGMP socket for %s on %s",
-                         inet_ntoa(ifaddr), ifp->name);
+               zlog_warn("Could not bind IGMP socket for %pI4 on %s",
+                         &ifaddr, ifp->name);
                close(fd);
 
                return NULL;
@@ -1155,8 +1153,8 @@ struct igmp_group *igmp_add_group_by_addr(struct igmp_sock *igmp,
        if (pim_is_group_224_0_0_0_24(group_addr)) {
                if (PIM_DEBUG_IGMP_TRACE)
                        zlog_debug(
-                               "%s: Group specified %s is part of 224.0.0.0/24",
-                               __func__, inet_ntoa(group_addr));
+                               "%s: Group specified %pI4 is part of 224.0.0.0/24",
+                               __func__, &group_addr);
                return NULL;
        }
        /*
index 9e78b76008c0939d9f77a43daff31456f0259fdf..941d06761935abfccfed4e80f179898536e87cb5 100644 (file)
@@ -82,10 +82,10 @@ static bool mtrace_fwd_info_weak(struct pim_instance *pim,
                zlog_debug("mtrace pim_nexthop_lookup OK");
 
        if (PIM_DEBUG_MTRACE)
-               zlog_warn("mtrace next_hop=%s",
-                         inet_ntop(nexthop.mrib_nexthop_addr.family,
-                                   &nexthop.mrib_nexthop_addr.u.prefix,
-                                   nexthop_str, sizeof(nexthop_str)));
+               zlog_debug("mtrace next_hop=%s",
+                          inet_ntop(nexthop.mrib_nexthop_addr.family,
+                                    &nexthop.mrib_nexthop_addr.u.prefix,
+                                    nexthop_str, sizeof(nexthop_str)));
 
        if (nexthop.mrib_nexthop_addr.family == AF_INET)
                nh_addr = nexthop.mrib_nexthop_addr.u.prefix4;
@@ -270,8 +270,8 @@ static uint32_t query_arrival_time(void)
 
        if (gettimeofday(&tv, NULL) < 0) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn("Query arrival time lookup failed: errno=%d: %s",
-                                 errno, safe_strerror(errno));
+                       zlog_debug("Query arrival time lookup failed: errno=%d: %s",
+                                  errno, safe_strerror(errno));
                return 0;
        }
        /* not sure second offset correct, as I get different value */
@@ -336,7 +336,7 @@ static int mtrace_send_packet(struct interface *ifp,
 
                if (ret < 0) {
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn("Failed to set socket multicast TTL");
+                               zlog_debug("Failed to set socket multicast TTL");
                        ret = -1;
                        goto close_fd;
                }
@@ -354,14 +354,14 @@ static int mtrace_send_packet(struct interface *ifp,
                               sizeof(group_str));
                if (sent < 0) {
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn(
+                               zlog_debug(
                                        "Send mtrace request failed for %s on%s: group=%s msg_size=%zd: errno=%d:  %s",
                                        dst_str, ifp->name, group_str,
                                        mtrace_buf_len, errno,
                                        safe_strerror(errno));
                } else {
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn(
+                               zlog_debug(
                                        "Send mtrace request failed for %s on %s: group=%s msg_size=%zd: sent=%zd",
                                        dst_str, ifp->name, group_str,
                                        mtrace_buf_len, sent);
@@ -411,7 +411,7 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr,
                if (!pim_nexthop_lookup(pim, &nexthop, ip_hdr->ip_dst, 0)) {
                        close(fd);
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn(
+                               zlog_debug(
                                        "Dropping mtrace packet, no route to destination");
                        return -1;
                }
@@ -440,15 +440,15 @@ static int mtrace_un_forward_packet(struct pim_instance *pim, struct ip *ip_hdr,
 
        if (sent < 0) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
+                       zlog_debug(
                                "Failed to forward mtrace packet: sendto errno=%d, %s",
                                errno, safe_strerror(errno));
                return -1;
        }
 
        if (PIM_DEBUG_MTRACE) {
-               zlog_debug("Fwd mtrace packet len=%u to %s ttl=%u",
-                          ntohs(ip_hdr->ip_len), inet_ntoa(ip_hdr->ip_dst),
+               zlog_debug("Fwd mtrace packet len=%u to %pI4 ttl=%u",
+                          ntohs(ip_hdr->ip_len), &ip_hdr->ip_dst,
                           ip_hdr->ip_ttl);
        }
 
@@ -472,9 +472,9 @@ static int mtrace_mc_forward_packet(struct pim_instance *pim, struct ip *ip_hdr)
        if (c_oil == NULL) {
                if (PIM_DEBUG_MTRACE) {
                        zlog_debug(
-                               "Dropping mtrace multicast packet len=%u to %s ttl=%u",
+                               "Dropping mtrace multicast packet len=%u to %pI4 ttl=%u",
                                ntohs(ip_hdr->ip_len),
-                               inet_ntoa(ip_hdr->ip_dst), ip_hdr->ip_ttl);
+                               &ip_hdr->ip_dst, ip_hdr->ip_ttl);
                }
                return -1;
        }
@@ -514,6 +514,7 @@ static int mtrace_send_mc_response(struct pim_instance *pim,
        struct listnode *chnextnode;
        struct pim_ifchannel *ch = NULL;
        int ret = -1;
+       char buf[PREFIX_STRLEN];
 
        memset(&sg, 0, sizeof(struct prefix_sg));
        sg.grp = mtracep->rsp_addr;
@@ -525,7 +526,8 @@ static int mtrace_send_mc_response(struct pim_instance *pim,
                        zlog_debug(
                                "Dropping mtrace multicast response packet len=%u to %s",
                                (unsigned int)mtrace_len,
-                               inet_ntoa(mtracep->rsp_addr));
+                               inet_ntop(AF_INET, &mtracep->rsp_addr,
+                                         buf, sizeof(buf)));
                }
                return -1;
        }
@@ -570,10 +572,10 @@ static int mtrace_send_response(struct pim_instance *pim,
 
                if (p_rpf == NULL) {
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn("mtrace no RP for %s",
-                                         inet_ntop(AF_INET,
-                                                   &(mtracep->rsp_addr),
-                                                   grp_str, sizeof(grp_str)));
+                               zlog_debug("mtrace no RP for %s",
+                                          inet_ntop(AF_INET,
+                                                    &(mtracep->rsp_addr),
+                                                    grp_str, sizeof(grp_str)));
                        return -1;
                }
                nexthop = p_rpf->source_nexthop;
@@ -584,7 +586,7 @@ static int mtrace_send_response(struct pim_instance *pim,
                /* TODO: should use unicast rib lookup */
                if (!pim_nexthop_lookup(pim, &nexthop, mtracep->rsp_addr, 1)) {
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn(
+                               zlog_debug(
                                        "Dropped response qid=%ud, no route to response address",
                                        mtracep->qry_id);
                        return -1;
@@ -633,7 +635,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
 
        if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
+                       zlog_debug(
                                "Recv mtrace packet from %s on %s: too short, len=%d, min=%zu",
                                from_str, ifp->name, igmp_msg_len,
                                sizeof(struct igmp_mtrace));
@@ -650,7 +652,7 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
 
        if (recv_checksum != checksum) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
+                       zlog_debug(
                                "Recv mtrace packet from %s on %s: checksum mismatch: received=%x computed=%x",
                                from_str, ifp->name, recv_checksum, checksum);
                return -1;
@@ -700,12 +702,12 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
                        last_rsp_ind = r_len / sizeof(struct igmp_mtrace_rsp);
                if (last_rsp_ind > MTRACE_MAX_HOPS) {
                        if (PIM_DEBUG_MTRACE)
-                               zlog_warn("Mtrace request of excessive size");
+                               zlog_debug("Mtrace request of excessive size");
                        return -1;
                }
        } else {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
+                       zlog_debug(
                                "Recv mtrace packet from %s on %s: invalid length %d",
                                from_str, ifp->name, igmp_msg_len);
                return -1;
@@ -715,9 +717,9 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
        if (IPV4_CLASS_DE(ntohl(ip_hdr->ip_dst.s_addr))
            && !IPV4_MC_LINKLOCAL(ntohl(ip_hdr->ip_dst.s_addr))) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
-                               "Recv mtrace packet from %s on %s: not link-local multicast %s",
-                               from_str, ifp->name, inet_ntoa(ip_hdr->ip_dst));
+                       zlog_debug(
+                               "Recv mtrace packet from %s on %s: not link-local multicast %pI4",
+                               from_str, ifp->name, &ip_hdr->ip_dst);
                return -1;
        }
 
@@ -848,7 +850,7 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr,
 
        if (igmp_msg_len < (int)sizeof(struct igmp_mtrace)) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
+                       zlog_debug(
                                "Recv mtrace packet from %s on %s: too short, len=%d, min=%zu",
                                from_str, ifp->name, igmp_msg_len,
                                sizeof(struct igmp_mtrace));
@@ -865,7 +867,7 @@ int igmp_mtrace_recv_response(struct igmp_sock *igmp, struct ip *ip_hdr,
 
        if (recv_checksum != checksum) {
                if (PIM_DEBUG_MTRACE)
-                       zlog_warn(
+                       zlog_debug(
                                "Recv mtrace response from %s on %s: checksum mismatch: received=%x computed=%x",
                                from_str, ifp->name, recv_checksum, checksum);
                return -1;
index 8eaca75821d04b257c39d8ac8f27e65f9eb66741..22767a8629700f22f87d6d0240320bf7d86cab9f 100644 (file)
@@ -1921,10 +1921,10 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
 
                if (PIM_DEBUG_IGMP_PACKETS) {
                        zlog_debug(
-                               "    Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%s",
+                               "    Recv IGMP report v3 from %s on %s: record=%d type=%d auxdatalen=%d sources=%d group=%pI4",
                                from_str, ifp->name, i, rec_type,
                                rec_auxdatalen, rec_num_sources,
-                               inet_ntoa(rec_group));
+                               &rec_group);
                }
 
                /* Scan sources */
@@ -1949,9 +1949,9 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
                                                 "<source?>");
 
                                zlog_debug(
-                                       "        Recv IGMP report v3 from %s on %s: record=%d group=%s source=%s",
+                                       "        Recv IGMP report v3 from %s on %s: record=%d group=%pI4 source=%s",
                                        from_str, ifp->name, i,
-                                       inet_ntoa(rec_group), src_str);
+                                       &rec_group, src_str);
                        }
                } /* for (sources) */
 
@@ -1969,8 +1969,8 @@ int igmp_v3_recv_report(struct igmp_sock *igmp, struct in_addr from,
 
                if (PIM_DEBUG_IGMP_PACKETS && filtered)
                        zlog_debug(
-                               "Filtering IGMPv3 group record %s from %s on %s per prefix-list %s",
-                               inet_ntoa(rec_group), from_str, ifp->name,
+                               "Filtering IGMPv3 group record %pI4 from %s on %s per prefix-list %s",
+                               &rec_group, from_str, ifp->name,
                                pim_ifp->boundary_oil_plist);
 
                /*
index 3a88de20700fc4d0cd5db6addd30b047bb779942..f54d5bf9bfe48b448cc4f40a7473566518e296bd 100644 (file)
@@ -173,6 +173,8 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
        uint8_t *pastend;
        int remain;
        int group;
+       struct pim_ifchannel *child = NULL;
+       struct listnode *ch_node, *nch_node;
 
        buf = tlv_buf;
        pastend = tlv_buf + tlv_buf_size;
@@ -337,9 +339,24 @@ int pim_joinprune_recv(struct interface *ifp, struct pim_neighbor *neigh,
                         */
                        sg_ch = pim_ifchannel_find(ifp, &sg);
 
+                       if (!sg_ch)
+                               continue;
+
+                       /* (*,G) prune received */
+                       for (ALL_LIST_ELEMENTS(sg_ch->sources, ch_node,
+                                              nch_node, child)) {
+                               if (PIM_IF_FLAG_TEST_S_G_RPT(child->flags)) {
+                                       if (child->ifjoin_state
+                                           == PIM_IFJOIN_PRUNE_PENDING_TMP)
+                                               THREAD_OFF(
+                                                       child->t_ifjoin_prune_pending_timer);
+                                       PIM_IF_FLAG_UNSET_S_G_RPT(child->flags);
+                                       child->ifjoin_state = PIM_IFJOIN_NOINFO;
+                               }
+                       }
+
                        /* Received SG-RPT Prune delete oif from specific S,G */
-                       if (starg_ch && sg_ch
-                           && (msg_source_flags & PIM_RPT_BIT_MASK)
+                       if (starg_ch && (msg_source_flags & PIM_RPT_BIT_MASK)
                            && !(msg_source_flags & PIM_WILDCARD_BIT_MASK)) {
                                struct pim_upstream *up = sg_ch->upstream;
                                PIM_IF_FLAG_SET_S_G_RPT(sg_ch->flags);
index 2dfc0af1de0dbce1151fa70619db9d83845a0137..a06c0a6f4e18aab0161913589ffb6de5cd2a83bd 100644 (file)
@@ -96,7 +96,7 @@ static void pim_mlag_inherit_mlag_flags(struct pim_upstream *up, bool is_df)
        struct channel_oil *ch_oil = NULL;
 
        if (PIM_DEBUG_MLAG)
-               zlog_debug("%s: Updating DF for uptream:%s childs", __func__,
+               zlog_debug("%s: Updating DF for uptream:%s children", __func__,
                           up->sg_str);
 
 
index b42092a464981ae52d6aaf0d3a4279bdb523e713..7336cdfef8b8c6c2962e81a0fb0217194b084553 100644 (file)
@@ -423,6 +423,7 @@ void pim_msdp_sa_ref(struct pim_instance *pim, struct pim_msdp_peer *mp,
                                           sa->sg_str);
                        }
                        /* send an immediate SA update to peers */
+                       sa->rp = pim->msdp.originator_id;
                        pim_msdp_pkt_sa_tx_one(sa);
                }
                sa->flags &= ~PIM_MSDP_SAF_STALE;
@@ -721,10 +722,18 @@ static int pim_msdp_sa_comp(const void *p1, const void *p2)
 /* XXX: this can use a bit of refining and extensions */
 bool pim_msdp_peer_rpf_check(struct pim_msdp_peer *mp, struct in_addr rp)
 {
+       struct pim_nexthop nexthop;
+
        if (mp->peer.s_addr == rp.s_addr) {
                return true;
        }
 
+       /* check if the MSDP peer is the nexthop for the RP */
+       if (pim_nexthop_lookup(mp->pim, &nexthop, rp, 0)
+           && nexthop.mrib_nexthop_addr.u.prefix4.s_addr == mp->peer.s_addr) {
+               return true;
+       }
+
        return false;
 }
 
index 6caa3181e72043d7683c792b7400e3d8e58df4b1..15a1041e2181f771f48325def6a4177472d4df02 100644 (file)
@@ -208,8 +208,8 @@ struct pim_msdp {
        thread_add_write(mp->pim->msdp.master, pim_msdp_write, mp, mp->fd,     \
                         &mp->t_write)
 
-#define PIM_MSDP_PEER_READ_OFF(mp) THREAD_READ_OFF(mp->t_read)
-#define PIM_MSDP_PEER_WRITE_OFF(mp) THREAD_WRITE_OFF(mp->t_write)
+#define PIM_MSDP_PEER_READ_OFF(mp) thread_cancel(&mp->t_read)
+#define PIM_MSDP_PEER_WRITE_OFF(mp) thread_cancel(&mp->t_write)
 
 // struct pim_msdp *msdp;
 struct pim_instance;
index 39e39b9557fe8596fce50952c643e016c3ad1fe2..4aaf0f53d178905c754c47d7f47f90a677155075 100644 (file)
@@ -348,7 +348,8 @@ static void pim_msdp_pkt_sa_push(struct pim_instance *pim,
        }
 }
 
-static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt)
+static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt,
+                                   struct in_addr rp)
 {
        int curr_tlv_ecnt;
 
@@ -361,7 +362,7 @@ static int pim_msdp_pkt_sa_fill_hdr(struct pim_instance *pim, int local_cnt)
        stream_putw(pim->msdp.work_obuf,
                    PIM_MSDP_SA_ENTRY_CNT2SIZE(curr_tlv_ecnt));
        stream_putc(pim->msdp.work_obuf, curr_tlv_ecnt);
-       stream_put_ipv4(pim->msdp.work_obuf, pim->msdp.originator_id.s_addr);
+       stream_put_ipv4(pim->msdp.work_obuf, rp.s_addr);
 
        return local_cnt;
 }
@@ -387,7 +388,8 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
                zlog_debug("  sa gen  %d", local_cnt);
        }
 
-       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt);
+       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt,
+                                            pim->msdp.originator_id);
 
        for (ALL_LIST_ELEMENTS_RO(pim->msdp.sa_list, sanode, sa)) {
                if (!(sa->flags & PIM_MSDP_SAF_LOCAL)) {
@@ -408,7 +410,8 @@ static void pim_msdp_pkt_sa_gen(struct pim_instance *pim,
                                zlog_debug("  sa gen for remainder %d",
                                           local_cnt);
                        }
-                       local_cnt = pim_msdp_pkt_sa_fill_hdr(pim, local_cnt);
+                       local_cnt = pim_msdp_pkt_sa_fill_hdr(
+                               pim, local_cnt, pim->msdp.originator_id);
                }
        }
 
@@ -441,7 +444,7 @@ void pim_msdp_pkt_sa_tx(struct pim_instance *pim)
 
 void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa)
 {
-       pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */);
+       pim_msdp_pkt_sa_fill_hdr(sa->pim, 1 /* cnt */, sa->rp);
        pim_msdp_pkt_sa_fill_one(sa);
        pim_msdp_pkt_sa_push(sa->pim, NULL);
        pim_msdp_pkt_sa_tx_done(sa->pim);
@@ -454,6 +457,24 @@ void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp)
        pim_msdp_pkt_sa_tx_done(mp->pim);
 }
 
+void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp,
+                                       struct in_addr rp, struct prefix_sg sg)
+{
+       struct pim_msdp_sa sa;
+
+       /* Fills the SA header. */
+       pim_msdp_pkt_sa_fill_hdr(mp->pim, 1, rp);
+
+       /* Fills the message contents. */
+       sa.pim = mp->pim;
+       sa.sg = sg;
+       pim_msdp_pkt_sa_fill_one(&sa);
+
+       /* Pushes the message. */
+       pim_msdp_pkt_sa_push(sa.pim, mp);
+       pim_msdp_pkt_sa_tx_done(sa.pim);
+}
+
 static void pim_msdp_pkt_rxed_with_fatal_error(struct pim_msdp_peer *mp)
 {
        pim_msdp_peer_reset_tcp_conn(mp, "invalid-pkt-rx");
@@ -473,6 +494,8 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
 {
        int prefix_len;
        struct prefix_sg sg;
+       struct listnode *peer_node;
+       struct pim_msdp_peer *peer;
 
        /* just throw away the three reserved bytes */
        stream_get3(mp->ibuf);
@@ -493,6 +516,18 @@ static void pim_msdp_pkt_sa_rx_one(struct pim_msdp_peer *mp, struct in_addr rp)
                zlog_debug("  sg %s", pim_str_sg_dump(&sg));
        }
        pim_msdp_sa_ref(mp->pim, mp, &sg, rp);
+
+       /* Forwards the SA to the peers that are not in the RPF to the RP nor in
+        * the same mesh group as the peer from which we received the message.
+        * If the message group is not set, i.e. "default", then we assume that
+        * the message must be forwarded.*/
+       for (ALL_LIST_ELEMENTS_RO(mp->pim->msdp.peer_list, peer_node, peer)) {
+               if (!pim_msdp_peer_rpf_check(peer, rp)
+                   && (strcmp(mp->mesh_group_name, peer->mesh_group_name)
+                       || !strcmp(mp->mesh_group_name, "default"))) {
+                       pim_msdp_pkt_sa_tx_one_to_one_peer(peer, rp, sg);
+               }
+       }
 }
 
 static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
@@ -510,10 +545,9 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
 
        entry_cnt = stream_getc(mp->ibuf);
        /* some vendors include the actual multicast data in the tlv (at the
-        * end).
-        * we will ignore such data. in the future we may consider pushing it
-        * down
-        * the RPT */
+        * end). we will ignore such data. in the future we may consider pushing
+        * it down the RPT
+        */
        if (len < PIM_MSDP_SA_ENTRY_CNT2SIZE(entry_cnt)) {
                pim_msdp_pkt_rxed_with_fatal_error(mp);
                return;
@@ -526,6 +560,8 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
                zlog_debug("  entry_cnt %d rp %s", entry_cnt, rp_str);
        }
 
+       pim_msdp_peer_pkt_rxed(mp);
+
        if (!pim_msdp_peer_rpf_check(mp, rp)) {
                /* if peer-RPF check fails don't process the packet any further
                 */
@@ -535,8 +571,6 @@ static void pim_msdp_pkt_sa_rx(struct pim_msdp_peer *mp, int len)
                return;
        }
 
-       pim_msdp_peer_pkt_rxed(mp);
-
        /* update SA cache */
        for (i = 0; i < entry_cnt; ++i) {
                pim_msdp_pkt_sa_rx_one(mp, rp);
index d922fa50dfb8e059ea30480261c5e4d0dfd3c7a4..f5af8d11408596d7b394e63304d683e46fd2a9a3 100644 (file)
@@ -67,5 +67,7 @@ int pim_msdp_read(struct thread *thread);
 void pim_msdp_pkt_sa_tx(struct pim_instance *pim);
 void pim_msdp_pkt_sa_tx_one(struct pim_msdp_sa *sa);
 void pim_msdp_pkt_sa_tx_to_one_peer(struct pim_msdp_peer *mp);
+void pim_msdp_pkt_sa_tx_one_to_one_peer(struct pim_msdp_peer *mp,
+                                       struct in_addr rp, struct prefix_sg sg);
 
 #endif
index 4d6625bf6fa5b1758c90f25b0f860bca82982764..167aa3c604377a4843f1a7781d9d3104340eaada 100644 (file)
@@ -294,7 +294,7 @@ static int on_neighbor_jp_timer(struct thread *t)
 
 static void pim_neighbor_start_jp_timer(struct pim_neighbor *neigh)
 {
-       THREAD_TIMER_OFF(neigh->jp_timer);
+       THREAD_OFF(neigh->jp_timer);
        thread_add_timer(router->master, on_neighbor_jp_timer, neigh,
                         router->t_periodic, &neigh->jp_timer);
 }
index f06d4ae6054140029cec10b96b49935d2f83cc7c..f691e8b75592d541316cfc65673dcfca718b0c0a 100644 (file)
@@ -26,6 +26,8 @@
 #include "hash.h"
 #include "jhash.h"
 
+#include "lib/printfrr.h"
+
 #include "pimd.h"
 #include "pimd/pim_nht.h"
 #include "log.h"
@@ -56,15 +58,12 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
        if (ret < 0)
                zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
 
-       if (PIM_DEBUG_PIM_NHT) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(p, buf, sizeof(buf));
+       if (PIM_DEBUG_PIM_NHT)
                zlog_debug(
-                       "%s: NHT %sregistered addr %s(%s) with Zebra ret:%d ",
+                       "%s: NHT %sregistered addr %pFX(%s) with Zebra ret:%d ",
                        __func__,
-                       (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", buf,
+                       (command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", p,
                        pim->vrf->name, ret);
-       }
 
        return;
 }
@@ -89,7 +88,6 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
 {
        struct pim_nexthop_cache *pnc;
        char hash_name[64];
-       char buf1[64];
 
        pnc = XCALLOC(MTYPE_PIM_NEXTHOP_CACHE,
                      sizeof(struct pim_nexthop_cache));
@@ -103,8 +101,8 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
        pnc->rp_list = list_new();
        pnc->rp_list->cmp = pim_rp_list_cmp;
 
-       snprintf(hash_name, sizeof(hash_name), "PNC %s(%s) Upstream Hash",
-                prefix2str(&pnc->rpf.rpf_addr, buf1, 64), pim->vrf->name);
+       snprintfrr(hash_name, sizeof(hash_name), "PNC %pFX(%s) Upstream Hash",
+                  &pnc->rpf.rpf_addr, pim->vrf->name);
        pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
                                              pim_upstream_equal, hash_name);
 
@@ -140,13 +138,10 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
                pnc = pim_nexthop_cache_add(pim, &rpf);
                pim_sendmsg_zebra_rnh(pim, zclient, pnc,
                                      ZEBRA_NEXTHOP_REGISTER);
-               if (PIM_DEBUG_PIM_NHT) {
-                       char buf[PREFIX2STR_BUFFER];
-                       prefix2str(addr, buf, sizeof(buf));
+               if (PIM_DEBUG_PIM_NHT)
                        zlog_debug(
-                               "%s: NHT cache and zebra notification added for %s(%s)",
-                               __func__, buf, pim->vrf->name);
-               }
+                               "%s: NHT cache and zebra notification added for %pFX(%s)",
+                               __func__, addr, pim->vrf->name);
        }
 
        if (rp != NULL) {
@@ -215,14 +210,11 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
                if (del_bsr_tracking)
                        pnc->bsr_tracking = false;
 
-               if (PIM_DEBUG_PIM_NHT) {
-                       char buf[PREFIX_STRLEN];
-                       prefix2str(addr, buf, sizeof(buf));
+               if (PIM_DEBUG_PIM_NHT)
                        zlog_debug(
-                               "%s: NHT %s(%s) rp_list count:%d upstream count:%ld",
-                               __func__, buf, pim->vrf->name,
+                               "%s: NHT %pFX(%s) rp_list count:%d upstream count:%ld",
+                               __func__, addr, pim->vrf->name,
                                pnc->rp_list->count, pnc->upstream_hash->count);
-               }
 
                if (pnc->rp_list->count == 0
                    && pnc->upstream_hash->count == 0
@@ -744,13 +736,10 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
                prefix_copy(&rpf.rpf_addr, &nhr.prefix);
                pnc = pim_nexthop_cache_find(pim, &rpf);
                if (!pnc) {
-                       if (PIM_DEBUG_PIM_NHT) {
-                               char buf[PREFIX2STR_BUFFER];
-                               prefix2str(&rpf.rpf_addr, buf, sizeof(buf));
+                       if (PIM_DEBUG_PIM_NHT)
                                zlog_debug(
-                                       "%s: Skipping NHT update, addr %s is not in local cached DB.",
-                                       __func__, buf);
-                       }
+                                       "%s: Skipping NHT update, addr %pFX is not in local cached DB.",
+                                       __func__, &rpf.rpf_addr);
                        return 0;
                }
        } else {
@@ -819,17 +808,13 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
                                continue;
                        }
 
-                       if (PIM_DEBUG_PIM_NHT) {
-                               char p_str[PREFIX2STR_BUFFER];
-
-                               prefix2str(&nhr.prefix, p_str, sizeof(p_str));
+                       if (PIM_DEBUG_PIM_NHT)
                                zlog_debug(
-                                       "%s: NHT addr %s(%s) %d-nhop via %s(%s) type %d distance:%u metric:%u ",
-                                       __func__, p_str, pim->vrf->name, i + 1,
-                                       inet_ntoa(nexthop->gate.ipv4),
+                                       "%s: NHT addr %pFX(%s) %d-nhop via %pI4(%s) type %d distance:%u metric:%u ",
+                                       __func__, &nhr.prefix, pim->vrf->name,
+                                       i + 1, &nexthop->gate.ipv4,
                                        ifp->name, nexthop->type, nhr.distance,
                                        nhr.metric);
-                       }
 
                        if (!ifp->info) {
                                /*
@@ -879,15 +864,12 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
        }
        SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED);
 
-       if (PIM_DEBUG_PIM_NHT) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&nhr.prefix, buf, sizeof(buf));
+       if (PIM_DEBUG_PIM_NHT)
                zlog_debug(
-                       "%s: NHT Update for %s(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
-                       __func__, buf, pim->vrf->name, nhr.nexthop_num,
+                       "%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
+                       __func__, &nhr.prefix, pim->vrf->name, nhr.nexthop_num,
                        pnc->nexthop_num, vrf_id, pnc->upstream_hash->count,
                        listcount(pnc->rp_list));
-       }
 
        pim_rpf_set_refresh_time(pim);
 
index 19e15f3edec041edfd955d49da714fbe01f345a1..90b69a54f2cd18da27b7bed221a3e8ec3e658a8a 100644 (file)
@@ -75,8 +75,8 @@ void pim_register_stop_send(struct interface *ifp, struct prefix_sg *sg,
        struct prefix p;
 
        if (PIM_DEBUG_PIM_REG) {
-               zlog_debug("Sending Register stop for %s to %s on %s",
-                          pim_str_sg_dump(sg), inet_ntoa(originator),
+               zlog_debug("Sending Register stop for %s to %pI4 on %s",
+                          pim_str_sg_dump(sg), &originator,
                           ifp->name);
        }
 
@@ -170,9 +170,9 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
        struct interface *ifp;
 
        if (PIM_DEBUG_PIM_REG) {
-               zlog_debug("Sending %s %sRegister Packet to %s", up->sg_str,
+               zlog_debug("Sending %s %sRegister Packet to %pI4", up->sg_str,
                           null_register ? "NULL " : "",
-                          inet_ntoa(rpg->rpf_addr.u.prefix4));
+                          &rpg->rpf_addr.u.prefix4);
        }
 
        ifp = rpg->source_nexthop.interface;
@@ -192,12 +192,9 @@ void pim_register_send(const uint8_t *buf, int buf_size, struct in_addr src,
        }
 
        if (PIM_DEBUG_PIM_REG) {
-               char rp_str[INET_ADDRSTRLEN];
-               strlcpy(rp_str, inet_ntoa(rpg->rpf_addr.u.prefix4),
-                       sizeof(rp_str));
-               zlog_debug("%s: Sending %s %sRegister Packet to %s on %s",
+               zlog_debug("%s: Sending %s %sRegister Packet to %pI4 on %s",
                           __func__, up->sg_str, null_register ? "NULL " : "",
-                          rp_str, ifp->name);
+                          &rpg->rpf_addr.u.prefix4, ifp->name);
        }
 
        memset(buffer, 0, 10000);
index 93fe787a93cda97e717cf7458fcc6b9d188de438..7246482f022f4601b79c841e6eb69b6f78a25fac 100644 (file)
@@ -134,7 +134,7 @@ void pim_rp_init(struct pim_instance *pim)
        if (PIM_DEBUG_PIM_TRACE)
                zlog_debug(
                        "Allocated: %p for rp_info: %p(224.0.0.0/4) Lock: %d",
-                       rn, rp_info, rn->lock);
+                       rn, rp_info, route_node_get_lock_count(rn));
 }
 
 void pim_rp_free(struct pim_instance *pim)
@@ -248,14 +248,10 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
        }
 
        rp_info = rn->info;
-       if (PIM_DEBUG_PIM_TRACE) {
-               char buf[PREFIX_STRLEN];
-
-               zlog_debug("Lookedup: %p for rp_info: %p(%s) Lock: %d", rn,
-                          rp_info,
-                          prefix2str(&rp_info->group, buf, sizeof(buf)),
-                          rn->lock);
-       }
+       if (PIM_DEBUG_PIM_TRACE)
+               zlog_debug("Lookedup: %p for rp_info: %p(%pFX) Lock: %d", rn,
+                          rp_info, &rp_info->group,
+                          route_node_get_lock_count(rn));
 
        route_unlock_node(rn);
 
@@ -354,8 +350,8 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
                                 up->sg.grp);
 
        if (PIM_DEBUG_PIM_TRACE)
-               zlog_debug("%s: pim upstream update for  old upstream %s",
-                          __func__, inet_ntoa(old_upstream_addr));
+               zlog_debug("%s: pim upstream update for  old upstream %pI4",
+                          __func__, &old_upstream_addr);
 
        if (old_upstream_addr.s_addr == new_upstream_addr.s_addr)
                return;
@@ -370,14 +366,10 @@ void pim_upstream_update(struct pim_instance *pim, struct pim_upstream *up)
                nht_p.family = AF_INET;
                nht_p.prefixlen = IPV4_MAX_BITLEN;
                nht_p.u.prefix4 = old_upstream_addr;
-               if (PIM_DEBUG_PIM_TRACE) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(&nht_p, buf, sizeof(buf));
+               if (PIM_DEBUG_PIM_TRACE)
                        zlog_debug(
-                               "%s: Deregister upstream %s addr %s with Zebra NHT",
-                               __func__, up->sg_str, buf);
-               }
+                               "%s: Deregister upstream %s addr %pFX with Zebra NHT",
+                               __func__, up->sg_str, &nht_p);
                pim_delete_tracked_nexthop(pim, &nht_p, up, NULL, false);
        }
 
@@ -547,15 +539,10 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
                        nht_p.prefixlen = IPV4_MAX_BITLEN;
                        nht_p.u.prefix4 =
                                rp_all->rp.rpf_addr.u.prefix4; // RP address
-                       if (PIM_DEBUG_PIM_NHT_RP) {
-                               char buf[PREFIX2STR_BUFFER];
-                               char buf1[PREFIX2STR_BUFFER];
-                               prefix2str(&nht_p, buf, sizeof(buf));
-                               prefix2str(&rp_all->group, buf1, sizeof(buf1));
+                       if (PIM_DEBUG_PIM_NHT_RP)
                                zlog_debug(
-                                       "%s: NHT Register rp_all addr %s grp %s ",
-                                       __func__, buf, buf1);
-                       }
+                                       "%s: NHT Register rp_all addr %pFX grp %pFX ",
+                                       __func__, &nht_p, &rp_all->group);
 
                        frr_each (rb_pim_upstream, &pim->upstream_head, up) {
                                /* Find (*, G) upstream whose RP is not
@@ -643,14 +630,10 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
        rn = route_node_get(pim->rp_table, &rp_info->group);
        rn->info = rp_info;
 
-       if (PIM_DEBUG_PIM_TRACE) {
-               char buf[PREFIX_STRLEN];
-
-               zlog_debug("Allocated: %p for rp_info: %p(%s) Lock: %d", rn,
-                          rp_info,
-                          prefix2str(&rp_info->group, buf, sizeof(buf)),
-                          rn->lock);
-       }
+       if (PIM_DEBUG_PIM_TRACE)
+               zlog_debug("Allocated: %p for rp_info: %p(%pFX) Lock: %d", rn,
+                          rp_info, &rp_info->group,
+                          route_node_get_lock_count(rn));
 
        frr_each (rb_pim_upstream, &pim->upstream_head, up) {
                if (up->sg.src.s_addr == INADDR_ANY) {
@@ -674,14 +657,9 @@ int pim_rp_new(struct pim_instance *pim, struct in_addr rp_addr,
        nht_p.family = AF_INET;
        nht_p.prefixlen = IPV4_MAX_BITLEN;
        nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-       if (PIM_DEBUG_PIM_NHT_RP) {
-               char buf[PREFIX2STR_BUFFER];
-               char buf1[PREFIX2STR_BUFFER];
-               prefix2str(&nht_p, buf, sizeof(buf));
-               prefix2str(&rp_info->group, buf1, sizeof(buf1));
-               zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ",
-                          __func__, buf, buf1);
-       }
+       if (PIM_DEBUG_PIM_NHT_RP)
+               zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ",
+                          __func__, &nht_p, &rp_info->group);
        pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL);
        if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
                                     &rp_info->group, 1))
@@ -727,12 +705,10 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
        struct pim_upstream *up;
        struct bsgrp_node *bsgrp = NULL;
        struct bsm_rpinfo *bsrp = NULL;
-       char grp_str[PREFIX2STR_BUFFER];
        char rp_str[INET_ADDRSTRLEN];
 
        if (!inet_ntop(AF_INET, &rp_addr, rp_str, sizeof(rp_str)))
                snprintf(rp_str, sizeof(rp_str), "<rp?>");
-       prefix2str(&group, grp_str, sizeof(grp_str));
 
        if (plist)
                rp_info = pim_rp_find_prefix_list(pim, rp_addr, plist);
@@ -748,8 +724,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
        }
 
        if (PIM_DEBUG_PIM_TRACE)
-               zlog_debug("%s: Delete RP %s for the group %s", __func__,
-                          rp_str, grp_str);
+               zlog_debug("%s: Delete RP %s for the group %pFX", __func__,
+                          rp_str, &group);
 
        /* While static RP is getting deleted, we need to check if dynamic RP
         * present for the same group in BSM RP table, then install the dynamic
@@ -771,8 +747,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
                                                         "<bsrp?>");
 
                                        zlog_debug(
-                                               "%s: BSM RP %s found for the group %s",
-                                               __func__, bsrp_str, grp_str);
+                                               "%s: BSM RP %s found for the group %pFX",
+                                               __func__, bsrp_str, &group);
                                }
                                return pim_rp_change(pim, bsrp->rp_address,
                                                     group, RP_SRC_BSR);
@@ -780,8 +756,8 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
                } else {
                        if (PIM_DEBUG_PIM_TRACE)
                                zlog_debug(
-                                       "%s: BSM RP not found for the group %s",
-                                       __func__, grp_str);
+                                       "%s: BSM RP not found for the group %pFX",
+                                       __func__, &group);
                }
        }
 
@@ -789,12 +765,9 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
        nht_p.family = AF_INET;
        nht_p.prefixlen = IPV4_MAX_BITLEN;
        nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-       if (PIM_DEBUG_PIM_NHT_RP) {
-               char buf[PREFIX2STR_BUFFER];
-               prefix2str(&nht_p, buf, sizeof(buf));
-               zlog_debug("%s: Deregister RP addr %s with Zebra ", __func__,
-                          buf);
-       }
+       if (PIM_DEBUG_PIM_NHT_RP)
+               zlog_debug("%s: Deregister RP addr %pFX with Zebra ", __func__,
+                          &nht_p);
        pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false);
 
        if (!str2prefix("224.0.0.0/4", &g_all))
@@ -837,16 +810,12 @@ int pim_rp_del(struct pim_instance *pim, struct in_addr rp_addr,
                                        EC_LIB_DEVELOPMENT,
                                        "Expected rn->info to be equal to rp_info");
 
-                       if (PIM_DEBUG_PIM_TRACE) {
-                               char buf[PREFIX_STRLEN];
-
+                       if (PIM_DEBUG_PIM_TRACE)
                                zlog_debug(
-                                       "%s:Found for Freeing: %p for rp_info: %p(%s) Lock: %d",
-                                       __func__, rn, rp_info,
-                                       prefix2str(&rp_info->group, buf,
-                                                  sizeof(buf)),
-                                       rn->lock);
-                       }
+                                       "%s:Found for Freeing: %p for rp_info: %p(%pFX) Lock: %d",
+                                       __func__, rn, rp_info, &rp_info->group,
+                                       route_node_get_lock_count(rn));
+
                        rn->info = NULL;
                        route_unlock_node(rn);
                        route_unlock_node(rn);
@@ -925,13 +894,9 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
        /* Deregister old RP addr with Zebra NHT */
        if (rp_info->rp.rpf_addr.u.prefix4.s_addr != INADDR_ANY) {
                nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-               if (PIM_DEBUG_PIM_NHT_RP) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(&nht_p, buf, sizeof(buf));
-                       zlog_debug("%s: Deregister RP addr %s with Zebra ",
-                                  __func__, buf);
-               }
+               if (PIM_DEBUG_PIM_NHT_RP)
+                       zlog_debug("%s: Deregister RP addr %pFX with Zebra ",
+                                  __func__, &nht_p);
                pim_delete_tracked_nexthop(pim, &nht_p, NULL, rp_info, false);
        }
 
@@ -961,15 +926,9 @@ int pim_rp_change(struct pim_instance *pim, struct in_addr new_rp_addr,
 
        /* Register new RP addr with Zebra NHT */
        nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-       if (PIM_DEBUG_PIM_NHT_RP) {
-               char buf[PREFIX2STR_BUFFER];
-               char buf1[PREFIX2STR_BUFFER];
-
-               prefix2str(&nht_p, buf, sizeof(buf));
-               prefix2str(&rp_info->group, buf1, sizeof(buf1));
-               zlog_debug("%s: NHT Register RP addr %s grp %s with Zebra ",
-                          __func__, buf, buf1);
-       }
+       if (PIM_DEBUG_PIM_NHT_RP)
+               zlog_debug("%s: NHT Register RP addr %pFX grp %pFX with Zebra ",
+                          __func__, &nht_p, &rp_info->group);
 
        pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false, NULL);
        if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop, &nht_p,
@@ -1145,15 +1104,10 @@ struct pim_rpf *pim_rp_g(struct pim_instance *pim, struct in_addr group)
                nht_p.family = AF_INET;
                nht_p.prefixlen = IPV4_MAX_BITLEN;
                nht_p.u.prefix4 = rp_info->rp.rpf_addr.u.prefix4;
-               if (PIM_DEBUG_PIM_NHT_RP) {
-                       char buf[PREFIX2STR_BUFFER];
-                       char buf1[PREFIX2STR_BUFFER];
-                       prefix2str(&nht_p, buf, sizeof(buf));
-                       prefix2str(&rp_info->group, buf1, sizeof(buf1));
+               if (PIM_DEBUG_PIM_NHT_RP)
                        zlog_debug(
-                               "%s: NHT Register RP addr %s grp %s with Zebra",
-                               __func__, buf, buf1);
-               }
+                               "%s: NHT Register RP addr %pFX grp %pFX with Zebra",
+                               __func__, &nht_p, &rp_info->group);
                pim_find_or_track_nexthop(pim, &nht_p, NULL, rp_info, false,
                                          NULL);
                pim_rpf_set_refresh_time(pim);
@@ -1208,7 +1162,6 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
        struct listnode *node;
        struct rp_info *rp_info;
        char rp_buffer[32];
-       char group_buffer[32];
        int count = 0;
 
        for (ALL_LIST_ELEMENTS_RO(pim->rp_list, node, rp_info)) {
@@ -1225,11 +1178,11 @@ int pim_rp_config_write(struct pim_instance *pim, struct vty *vty,
                                          rp_buffer, 32),
                                rp_info->plist);
                else
-                       vty_out(vty, "%sip pim rp %s %s\n", spaces,
+                       vty_out(vty, "%sip pim rp %s %pFX\n", spaces,
                                inet_ntop(AF_INET,
                                          &rp_info->rp.rpf_addr.u.prefix4,
                                          rp_buffer, 32),
-                               prefix2str(&rp_info->group, group_buffer, 32));
+                               &rp_info->group);
                count++;
        }
 
@@ -1251,6 +1204,7 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
        struct rp_info *prev_rp_info = NULL;
        struct listnode *node;
        char source[7];
+       char buf[PREFIX_STRLEN];
 
        json_object *json = NULL;
        json_object *json_rp_rows = NULL;
@@ -1283,9 +1237,11 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
                                                          .s_addr) {
                                        json_object_object_add(
                                                json,
-                                               inet_ntoa(prev_rp_info->rp
+                                               inet_ntop(AF_INET,
+                                                         &prev_rp_info->rp
                                                                  .rpf_addr.u
-                                                                 .prefix4),
+                                                                 .prefix4,
+                                                         buf, sizeof(buf)),
                                                json_rp_rows);
                                        json_rp_rows = NULL;
                                }
@@ -1296,8 +1252,10 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
                                json_row = json_object_new_object();
                                json_object_string_add(
                                        json_row, "rpAddress",
-                                       inet_ntoa(rp_info->rp.rpf_addr.u
-                                                         .prefix4));
+                                       inet_ntop(AF_INET,
+                                                 &rp_info->rp.rpf_addr.u
+                                                     .prefix4,
+                                                 buf, sizeof(buf)));
                                if (rp_info->rp.source_nexthop.interface)
                                        json_object_string_add(
                                                json_row, "outboundInterface",
@@ -1329,15 +1287,16 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
                                json_object_array_add(json_rp_rows, json_row);
                        } else {
                                vty_out(vty, "%-15s  ",
-                                       inet_ntoa(rp_info->rp.rpf_addr.u
-                                                         .prefix4));
+                                       inet_ntop(AF_INET,
+                                                 &rp_info->rp.rpf_addr.u
+                                                         .prefix4,
+                                                 buf, sizeof(buf)));
 
                                if (rp_info->plist)
                                        vty_out(vty, "%-18s  ", rp_info->plist);
                                else
-                                       vty_out(vty, "%-18s  ",
-                                               prefix2str(&rp_info->group, buf,
-                                                          48));
+                                       vty_out(vty, "%-18pFX  ",
+                                               &rp_info->group);
 
                                if (rp_info->rp.source_nexthop.interface)
                                        vty_out(vty, "%-16s  ",
@@ -1361,7 +1320,9 @@ void pim_rp_show_information(struct pim_instance *pim, struct vty *vty, bool uj)
                if (prev_rp_info && json_rp_rows)
                        json_object_object_add(
                                json,
-                               inet_ntoa(prev_rp_info->rp.rpf_addr.u.prefix4),
+                               inet_ntop(AF_INET,
+                                         &prev_rp_info->rp.rpf_addr.u.prefix4,
+                                         buf, sizeof(buf)),
                                json_rp_rows);
 
                vty_out(vty, "%s\n", json_object_to_json_string_ext(
index d3fb0d46de9652a997f17bd56d45c9920dc1e3c3..d95b092d947a16f01c74d1f0a0d540d95897abac 100644 (file)
@@ -267,13 +267,10 @@ struct pim_upstream *pim_upstream_del(struct pim_instance *pim,
                nht_p.family = AF_INET;
                nht_p.prefixlen = IPV4_MAX_BITLEN;
                nht_p.u.prefix4 = up->upstream_addr;
-               if (PIM_DEBUG_PIM_TRACE) {
-                       char buf[PREFIX2STR_BUFFER];
-                       prefix2str(&nht_p, buf, sizeof(buf));
+               if (PIM_DEBUG_PIM_TRACE)
                        zlog_debug(
-                               "%s: Deregister upstream %s addr %s with Zebra NHT",
-                               __func__, up->sg_str, buf);
-               }
+                               "%s: Deregister upstream %s addr %pFX with Zebra NHT",
+                               __func__, up->sg_str, &nht_p);
                pim_delete_tracked_nexthop(pim, &nht_p, up, NULL, false);
        }
 
@@ -954,8 +951,8 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
 
        if (PIM_DEBUG_PIM_TRACE) {
                zlog_debug(
-                       "%s: Created Upstream %s upstream_addr %s ref count %d increment",
-                       __func__, up->sg_str, inet_ntoa(up->upstream_addr),
+                       "%s: Created Upstream %s upstream_addr %pI4 ref count %d increment",
+                       __func__, up->sg_str, &up->upstream_addr,
                        up->ref_count);
        }
 
@@ -1062,15 +1059,13 @@ struct pim_upstream *pim_upstream_add(struct pim_instance *pim,
        }
 
        if (PIM_DEBUG_PIM_TRACE) {
-               if (up) {
-                       char buf[PREFIX2STR_BUFFER];
-                       prefix2str(&up->rpf.rpf_addr, buf, sizeof(buf));
-                       zlog_debug("%s(%s): %s, iif %s (%s) found: %d: ref_count: %d",
+               if (up)
+                       zlog_debug("%s(%s): %s, iif %pFX (%s) found: %d: ref_count: %d",
                   __func__, name,
-                  up->sg_str, buf, up->rpf.source_nexthop.interface ?
+                  up->sg_str, &up->rpf.rpf_addr, up->rpf.source_nexthop.interface ?
                    up->rpf.source_nexthop.interface->name : "Unknown" ,
                   found, up->ref_count);
-               else
+               else
                        zlog_debug("%s(%s): (%s) failure to create", __func__,
                                   name, pim_str_sg_dump(sg));
        }
@@ -1773,7 +1768,7 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up,
 {
        uint32_t time;
 
-       THREAD_TIMER_OFF(up->t_rs_timer);
+       THREAD_OFF(up->t_rs_timer);
 
        if (!null_register) {
                uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD);
index d089dfda51cd702f4f25f21a62e408b868b1e6fa..f0eae955cceaea4912249524df65b8b44ab32420 100644 (file)
@@ -98,8 +98,8 @@ static void dump_if_address(struct interface *ifp)
                if (p->family != AF_INET)
                        continue;
 
-               zlog_debug("%s %s: interface %s address %s %s", __FILE__,
-                          __func__, ifp->name, inet_ntoa(p->u.prefix4),
+               zlog_debug("%s %s: interface %s address %pI4 %s", __FILE__,
+                          __func__, ifp->name, &p->u.prefix4,
                           CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY)
                                   ? "secondary"
                                   : "primary");
@@ -130,10 +130,8 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
        p = c->address;
 
        if (PIM_DEBUG_ZEBRA) {
-               char buf[BUFSIZ];
-               prefix2str(p, buf, BUFSIZ);
-               zlog_debug("%s: %s(%u) connected IP address %s flags %u %s",
-                          __func__, c->ifp->name, vrf_id, buf, c->flags,
+               zlog_debug("%s: %s(%u) connected IP address %pFX flags %u %s",
+                          __func__, c->ifp->name, vrf_id, p, c->flags,
                           CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
                                   ? "secondary"
                                   : "primary");
@@ -149,17 +147,10 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
                struct in_addr primary_addr = pim_find_primary_addr(c->ifp);
                if (p->family != AF_INET
                    || primary_addr.s_addr != p->u.prefix4.s_addr) {
-                       if (PIM_DEBUG_ZEBRA) {
-                               /* but we had a primary address already */
-
-                               char buf[BUFSIZ];
-
-                               prefix2str(p, buf, BUFSIZ);
-
+                       if (PIM_DEBUG_ZEBRA)
                                zlog_warn(
-                                       "%s: %s : forcing secondary flag on %s",
-                                       __func__, c->ifp->name, buf);
-                       }
+                                       "%s: %s : forcing secondary flag on %pFX",
+                                       __func__, c->ifp->name, p);
                        SET_FLAG(c->flags, ZEBRA_IFA_SECONDARY);
                }
        }
@@ -211,11 +202,9 @@ static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
        p = c->address;
        if (p->family == AF_INET) {
                if (PIM_DEBUG_ZEBRA) {
-                       char buf[BUFSIZ];
-                       prefix2str(p, buf, BUFSIZ);
                        zlog_debug(
-                               "%s: %s(%u) disconnected IP address %s flags %u %s",
-                               __func__, c->ifp->name, vrf_id, buf, c->flags,
+                               "%s: %s(%u) disconnected IP address %pFX flags %u %s",
+                               __func__, c->ifp->name, vrf_id, p, c->flags,
                                CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
                                        ? "secondary"
                                        : "primary");
@@ -848,9 +837,9 @@ void pim_forward_start(struct pim_ifchannel *ch)
                               sizeof(group_str));
                pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str,
                               sizeof(upstream_str));
-               zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%s)", __func__,
+               zlog_debug("%s: (S,G)=(%s,%s) oif=%s (%pI4)", __func__,
                           source_str, group_str, ch->interface->name,
-                          inet_ntoa(up->upstream_addr));
+                          &up->upstream_addr);
        }
 
        if (PIM_IF_FLAG_TEST_PROTO_IGMP(ch->flags))
index 4faf1dae16ee66f59ba63f36e4235bd31f94ba61..f80766a080844216ebca46a3041a93a472bedf59 100644 (file)
@@ -20,6 +20,7 @@ import re
 import sys
 import json
 
+
 class FunctionNode(object):
     funcs = {}
 
@@ -39,7 +40,7 @@ class FunctionNode(object):
 
     def define(self, attrs):
         self.defined = True
-        self.defs.append((attrs['filename'], attrs['line']))
+        self.defs.append((attrs["filename"], attrs["line"]))
         return self
 
     def add_call(self, called, attrs):
@@ -63,11 +64,12 @@ class FunctionNode(object):
             return cls.funcs[name]
         return FunctionNode(name)
 
+
 class CallEdge(object):
     def __init__(self, i, o, attrs):
         self.i = i
         self.o = o
-        self.is_external = attrs['is_external']
+        self.is_external = attrs["is_external"]
         self.attrs = attrs
 
         i.out.append(self)
@@ -76,11 +78,13 @@ class CallEdge(object):
     def __repr__(self):
         return '<"%s()" -> "%s()">' % (self.i.name, self.o.name)
 
+
 def nameclean(n):
-    if '.' in n:
-        return n.split('.', 1)[0]
+    if "." in n:
+        return n.split(".", 1)[0]
     return n
 
+
 def calc_rank(queue, direction):
     nextq = queue
 
@@ -98,7 +102,7 @@ def calc_rank(queue, direction):
         queue = nextq
         nextq = []
 
-        #sys.stderr.write('rank %d\n' % currank)
+        # sys.stderr.write('rank %d\n' % currank)
 
         cont = False
 
@@ -123,6 +127,7 @@ def calc_rank(queue, direction):
 
     return nextq
 
+
 class Graph(dict):
     class Subgraph(set):
         def __init__(self):
@@ -166,6 +171,7 @@ class Graph(dict):
 
         def calls(self):
             return self._calls
+
         def calld(self):
             return self._calld
 
@@ -245,7 +251,7 @@ class Graph(dict):
                     else:
                         evalset.add(evnode)
 
-            #if len(candidates) > 1:
+            # if len(candidates) > 1:
             #    for candidate in candidates:
             #        if candidate != node:
             #            #node.merge(candidate)
@@ -266,7 +272,7 @@ class Graph(dict):
         self._linear_nodes = []
 
         while len(nodes):
-            sys.stderr.write('%d\n' % len(nodes))
+            sys.stderr.write("%d\n" % len(nodes))
             node = nodes.pop(0)
 
             down[node] = set()
@@ -304,106 +310,90 @@ class Graph(dict):
         return self._subgraphs, self._linear_nodes
 
 
-with open(sys.argv[1], 'r') as fd:
+with open(sys.argv[1], "r") as fd:
     data = json.load(fd)
 
 extra_info = {
     # zebra - LSP WQ
-    ('lsp_processq_add', 'work_queue_add'): [
-        'lsp_process',
-        'lsp_processq_del',
-        'lsp_processq_complete',
+    ("lsp_processq_add", "work_queue_add"): [
+        "lsp_process",
+        "lsp_processq_del",
+        "lsp_processq_complete",
     ],
     # zebra - main WQ
-    ('mq_add_handler', 'work_queue_add'): [
-        'meta_queue_process',
-    ],
-    ('meta_queue_process', 'work_queue_add'): [
-        'meta_queue_process',
-    ],
+    ("mq_add_handler", "work_queue_add"): ["meta_queue_process",],
+    ("meta_queue_process", "work_queue_add"): ["meta_queue_process",],
     # bgpd - label pool WQ
-    ('bgp_lp_get', 'work_queue_add'): [
-        'lp_cbq_docallback',
-    ],
-    ('bgp_lp_event_chunk', 'work_queue_add'): [
-        'lp_cbq_docallback',
-    ],
-    ('bgp_lp_event_zebra_up', 'work_queue_add'): [
-        'lp_cbq_docallback',
-    ],
+    ("bgp_lp_get", "work_queue_add"): ["lp_cbq_docallback",],
+    ("bgp_lp_event_chunk", "work_queue_add"): ["lp_cbq_docallback",],
+    ("bgp_lp_event_zebra_up", "work_queue_add"): ["lp_cbq_docallback",],
     # bgpd - main WQ
-    ('bgp_process', 'work_queue_add'): [
-        'bgp_process_wq',
-        'bgp_processq_del',
-    ],
-    ('bgp_add_eoiu_mark', 'work_queue_add'): [
-        'bgp_process_wq',
-        'bgp_processq_del',
-    ],
+    ("bgp_process", "work_queue_add"): ["bgp_process_wq", "bgp_processq_del",],
+    ("bgp_add_eoiu_mark", "work_queue_add"): ["bgp_process_wq", "bgp_processq_del",],
     # clear node WQ
-    ('bgp_clear_route_table', 'work_queue_add'): [
-        'bgp_clear_route_node',
-        'bgp_clear_node_queue_del',
-        'bgp_clear_node_complete',
+    ("bgp_clear_route_table", "work_queue_add"): [
+        "bgp_clear_route_node",
+        "bgp_clear_node_queue_del",
+        "bgp_clear_node_complete",
     ],
     # rfapi WQs
-    ('rfapi_close', 'work_queue_add'): [
-        'rfapi_deferred_close_workfunc',
-    ],
-    ('rfapiRibUpdatePendingNode', 'work_queue_add'): [
-        'rfapiRibDoQueuedCallback',
-        'rfapiRibQueueItemDelete',
+    ("rfapi_close", "work_queue_add"): ["rfapi_deferred_close_workfunc",],
+    ("rfapiRibUpdatePendingNode", "work_queue_add"): [
+        "rfapiRibDoQueuedCallback",
+        "rfapiRibQueueItemDelete",
     ],
 }
 
 
-for func, fdata in data['functions'].items():
+for func, fdata in data["functions"].items():
     func = nameclean(func)
     fnode = FunctionNode.get(func).define(fdata)
 
-    for call in fdata['calls']:
-        if call.get('type') in [None, 'unnamed', 'thread_sched']:
-            if call.get('target') is None:
+    for call in fdata["calls"]:
+        if call.get("type") in [None, "unnamed", "thread_sched"]:
+            if call.get("target") is None:
                 continue
-            tgt = nameclean(call['target'])
+            tgt = nameclean(call["target"])
             fnode.add_call(FunctionNode.get(tgt), call)
-            for fptr in call.get('funcptrs', []):
+            for fptr in call.get("funcptrs", []):
                 fnode.add_call(FunctionNode.get(nameclean(fptr)), call)
-            if tgt == 'work_queue_add':
+            if tgt == "work_queue_add":
                 if (func, tgt) not in extra_info:
-                    sys.stderr.write('%s:%d:%s(): work_queue_add() not handled\n' % (
-                        call['filename'], call['line'], func))
+                    sys.stderr.write(
+                        "%s:%d:%s(): work_queue_add() not handled\n"
+                        % (call["filename"], call["line"], func)
+                    )
                 else:
                     attrs = dict(call)
-                    attrs.update({'is_external': False, 'type': 'workqueue'})
+                    attrs.update({"is_external": False, "type": "workqueue"})
                     for dst in extra_info[func, tgt]:
                         fnode.add_call(FunctionNode.get(dst), call)
-        elif call['type'] == 'install_element':
-            vty_node = FunctionNode.get('VTY_NODE_%d' % call['vty_node'])
-            vty_node.add_call(FunctionNode.get(nameclean(call['target'])), call)
-        elif call['type'] == 'hook':
+        elif call["type"] == "install_element":
+            vty_node = FunctionNode.get("VTY_NODE_%d" % call["vty_node"])
+            vty_node.add_call(FunctionNode.get(nameclean(call["target"])), call)
+        elif call["type"] == "hook":
             # TODO: edges for hooks from data['hooks']
             pass
 
 n = FunctionNode.funcs
 
 # fix some very low end functions cycling back very far to the top
-if 'peer_free' in n:
-    n['peer_free'].unlink(n['bgp_timer_set'])
-    n['peer_free'].unlink(n['bgp_addpath_set_peer_type'])
-if 'bgp_path_info_extra_free' in n:
-    n['bgp_path_info_extra_free'].rank = 0
+if "peer_free" in n:
+    n["peer_free"].unlink(n["bgp_timer_set"])
+    n["peer_free"].unlink(n["bgp_addpath_set_peer_type"])
+if "bgp_path_info_extra_free" in n:
+    n["bgp_path_info_extra_free"].rank = 0
 
-if 'zlog_ref' in n:
-    n['zlog_ref'].rank = 0
-if 'mt_checkalloc' in n:
-    n['mt_checkalloc'].rank = 0
+if "zlog_ref" in n:
+    n["zlog_ref"].rank = 0
+if "mt_checkalloc" in n:
+    n["mt_checkalloc"].rank = 0
 
 queue = list(FunctionNode.funcs.values())
 queue = calc_rank(queue, 1)
 queue = calc_rank(queue, -1)
 
-sys.stderr.write('%d functions in cyclic set\n' % len(queue))
+sys.stderr.write("%d functions in cyclic set\n" % len(queue))
 
 graph = Graph(queue)
 graph.automerge()
@@ -411,10 +401,12 @@ graph.automerge()
 gv_nodes = []
 gv_edges = []
 
-sys.stderr.write('%d groups after automerge\n' % len(graph._groups))
+sys.stderr.write("%d groups after automerge\n" % len(graph._groups))
+
 
 def is_vnc(n):
-    return n.startswith('rfapi') or n.startswith('vnc') or ('_vnc_' in n)
+    return n.startswith("rfapi") or n.startswith("vnc") or ("_vnc_" in n)
+
 
 _vncstyle = ',fillcolor="#ffffcc",style=filled'
 cyclic_set_names = set([fn.name for fn in graph.values()])
@@ -422,55 +414,76 @@ cyclic_set_names = set([fn.name for fn in graph.values()])
 for i, group in enumerate(graph._groups):
     if len(group) > 1:
         group.num = i
-        gv_nodes.append('\tsubgraph cluster_%d {' % i)
-        gv_nodes.append('\t\tcolor=blue;')
+        gv_nodes.append("\tsubgraph cluster_%d {" % i)
+        gv_nodes.append("\t\tcolor=blue;")
         for gn in group:
             has_cycle_callers = set(gn.calld()) - group
-            has_ext_callers = set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names
+            has_ext_callers = (
+                set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names
+            )
 
-            style = ''
-            etext = ''
+            style = ""
+            etext = ""
             if is_vnc(gn.name):
                 style += _vncstyle
             if has_cycle_callers:
-                style += ',color=blue,penwidth=3'
+                style += ",color=blue,penwidth=3"
             if has_ext_callers:
                 style += ',fillcolor="#ffeebb",style=filled'
-                etext += '<br/><font point-size="10">(%d other callers)</font>' % (len(has_ext_callers))
-
-            gv_nodes.append('\t\t"%s" [shape=box,label=<%s%s>%s];' % (gn.name, '<br/>'.join([fn.name for fn in gn._fns]), etext, style))
-        gv_nodes.append('\t}')
+                etext += '<br/><font point-size="10">(%d other callers)</font>' % (
+                    len(has_ext_callers)
+                )
+
+            gv_nodes.append(
+                '\t\t"%s" [shape=box,label=<%s%s>%s];'
+                % (gn.name, "<br/>".join([fn.name for fn in gn._fns]), etext, style)
+            )
+        gv_nodes.append("\t}")
     else:
         for gn in group:
-            has_ext_callers = set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names
+            has_ext_callers = (
+                set([edge.i.name for edge in gn._fn.inb]) - cyclic_set_names
+            )
 
-            style = ''
-            etext = ''
+            style = ""
+            etext = ""
             if is_vnc(gn.name):
                 style += _vncstyle
             if has_ext_callers:
                 style += ',fillcolor="#ffeebb",style=filled'
-                etext += '<br/><font point-size="10">(%d other callers)</font>' % (len(has_ext_callers))
-            gv_nodes.append('\t"%s" [shape=box,label=<%s%s>%s];' % (gn.name, '<br/>'.join([fn.name for fn in gn._fns]), etext, style))
+                etext += '<br/><font point-size="10">(%d other callers)</font>' % (
+                    len(has_ext_callers)
+                )
+            gv_nodes.append(
+                '\t"%s" [shape=box,label=<%s%s>%s];'
+                % (gn.name, "<br/>".join([fn.name for fn in gn._fns]), etext, style)
+            )
 
 edges = set()
 for gn in graph.values():
     for calls in gn.calls():
         if gn._group == calls._group:
-            gv_edges.append('\t"%s" -> "%s" [color="#55aa55",style=dashed];' % (gn.name, calls.name))
+            gv_edges.append(
+                '\t"%s" -> "%s" [color="#55aa55",style=dashed];' % (gn.name, calls.name)
+            )
         else:
+
             def xname(nn):
                 if len(nn._group) > 1:
-                    return 'cluster_%d' % nn._group.num
+                    return "cluster_%d" % nn._group.num
                 else:
                     return nn.name
+
             tup = xname(gn), calls.name
             if tup[0] != tup[1] and tup not in edges:
                 gv_edges.append('\t"%s" -> "%s" [weight=0.0,w=0.0,color=blue];' % tup)
                 edges.add(tup)
 
-with open(sys.argv[2], 'w') as fd:
-    fd.write('''digraph {
+with open(sys.argv[2], "w") as fd:
+    fd.write(
+        """digraph {
     node [fontsize=13,fontname="Fira Sans"];
 %s
-}''' % '\n'.join(gv_nodes + [''] + gv_edges))
+}"""
+        % "\n".join(gv_nodes + [""] + gv_edges)
+    )
index baa6ed52b25aac22d118e314bb928bfb56ce2439..a47cee2d6b47efe4b5dff5dd9b501f8d7480d2fd 100644 (file)
@@ -26,39 +26,49 @@ from io import StringIO
 # the various handlers generate output C code for a particular type of
 # CLI token, choosing the most useful output C type.
 
+
 class RenderHandler(object):
     def __init__(self, token):
         pass
+
     def combine(self, other):
         if type(self) == type(other):
             return other
         return StringHandler(None)
 
-    deref = ''
+    deref = ""
     drop_str = False
     canfail = True
     canassert = False
 
+
 class StringHandler(RenderHandler):
-    argtype = 'const char *'
-    decl = Template('const char *$varname = NULL;')
-    code = Template('$varname = (argv[_i]->type == WORD_TKN) ? argv[_i]->text : argv[_i]->arg;')
+    argtype = "const char *"
+    decl = Template("const char *$varname = NULL;")
+    code = Template(
+        "$varname = (argv[_i]->type == WORD_TKN) ? argv[_i]->text : argv[_i]->arg;"
+    )
     drop_str = True
     canfail = False
     canassert = True
 
+
 class LongHandler(RenderHandler):
-    argtype = 'long'
-    decl = Template('long $varname = 0;')
-    code = Template('''\
+    argtype = "long"
+    decl = Template("long $varname = 0;")
+    code = Template(
+        """\
 char *_end;
 $varname = strtol(argv[_i]->arg, &_end, 10);
-_fail = (_end == argv[_i]->arg) || (*_end != '\\0');''')
+_fail = (_end == argv[_i]->arg) || (*_end != '\\0');"""
+    )
+
 
 # A.B.C.D/M (prefix_ipv4) and
 # X:X::X:X/M (prefix_ipv6) are "compatible" and can merge into a
 # struct prefix:
 
+
 class PrefixBase(RenderHandler):
     def combine(self, other):
         if type(self) == type(other):
@@ -66,23 +76,33 @@ class PrefixBase(RenderHandler):
         if isinstance(other, PrefixBase):
             return PrefixGenHandler(None)
         return StringHandler(None)
-    deref = '&'
+
+    deref = "&"
+
+
 class Prefix4Handler(PrefixBase):
-    argtype = 'const struct prefix_ipv4 *'
-    decl = Template('struct prefix_ipv4 $varname = { };')
-    code = Template('_fail = !str2prefix_ipv4(argv[_i]->arg, &$varname);')
+    argtype = "const struct prefix_ipv4 *"
+    decl = Template("struct prefix_ipv4 $varname = { };")
+    code = Template("_fail = !str2prefix_ipv4(argv[_i]->arg, &$varname);")
+
+
 class Prefix6Handler(PrefixBase):
-    argtype = 'const struct prefix_ipv6 *'
-    decl = Template('struct prefix_ipv6 $varname = { };')
-    code = Template('_fail = !str2prefix_ipv6(argv[_i]->arg, &$varname);')
+    argtype = "const struct prefix_ipv6 *"
+    decl = Template("struct prefix_ipv6 $varname = { };")
+    code = Template("_fail = !str2prefix_ipv6(argv[_i]->arg, &$varname);")
+
+
 class PrefixEthHandler(PrefixBase):
-    argtype = 'struct prefix_eth *'
-    decl = Template('struct prefix_eth $varname = { };')
-    code = Template('_fail = !str2prefix_eth(argv[_i]->arg, &$varname);')
+    argtype = "struct prefix_eth *"
+    decl = Template("struct prefix_eth $varname = { };")
+    code = Template("_fail = !str2prefix_eth(argv[_i]->arg, &$varname);")
+
+
 class PrefixGenHandler(PrefixBase):
-    argtype = 'const struct prefix *'
-    decl = Template('struct prefix $varname = { };')
-    code = Template('_fail = !str2prefix(argv[_i]->arg, &$varname);')
+    argtype = "const struct prefix *"
+    decl = Template("struct prefix $varname = { };")
+    code = Template("_fail = !str2prefix(argv[_i]->arg, &$varname);")
+
 
 # same for IP addresses.  result is union sockunion.
 class IPBase(RenderHandler):
@@ -92,18 +112,27 @@ class IPBase(RenderHandler):
         if type(other) in [IP4Handler, IP6Handler, IPGenHandler]:
             return IPGenHandler(None)
         return StringHandler(None)
+
+
 class IP4Handler(IPBase):
-    argtype = 'struct in_addr'
-    decl = Template('struct in_addr $varname = { INADDR_ANY };')
-    code = Template('_fail = !inet_aton(argv[_i]->arg, &$varname);')
+    argtype = "struct in_addr"
+    decl = Template("struct in_addr $varname = { INADDR_ANY };")
+    code = Template("_fail = !inet_aton(argv[_i]->arg, &$varname);")
+
+
 class IP6Handler(IPBase):
-    argtype = 'struct in6_addr'
-    decl = Template('struct in6_addr $varname = {};')
-    code = Template('_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);')
+    argtype = "struct in6_addr"
+    decl = Template("struct in6_addr $varname = {};")
+    code = Template("_fail = !inet_pton(AF_INET6, argv[_i]->arg, &$varname);")
+
+
 class IPGenHandler(IPBase):
-    argtype = 'const union sockunion *'
-    decl = Template('''union sockunion s__$varname = { .sa.sa_family = AF_UNSPEC }, *$varname = NULL;''')
-    code = Template('''\
+    argtype = "const union sockunion *"
+    decl = Template(
+        """union sockunion s__$varname = { .sa.sa_family = AF_UNSPEC }, *$varname = NULL;"""
+    )
+    code = Template(
+        """\
 if (argv[_i]->text[0] == 'X') {
        s__$varname.sa.sa_family = AF_INET6;
        _fail = !inet_pton(AF_INET6, argv[_i]->arg, &s__$varname.sin6.sin6_addr);
@@ -112,26 +141,30 @@ if (argv[_i]->text[0] == 'X') {
        s__$varname.sa.sa_family = AF_INET;
        _fail = !inet_aton(argv[_i]->arg, &s__$varname.sin.sin_addr);
        $varname = &s__$varname;
-}''')
+}"""
+    )
     canassert = True
 
+
 def mix_handlers(handlers):
     def combine(a, b):
         if a is None:
             return b
         return a.combine(b)
+
     return reduce(combine, handlers, None)
 
+
 handlers = {
-    'WORD_TKN':         StringHandler,
-    'VARIABLE_TKN':     StringHandler,
-    'RANGE_TKN':        LongHandler,
-    'IPV4_TKN':         IP4Handler,
-    'IPV4_PREFIX_TKN':  Prefix4Handler,
-    'IPV6_TKN':         IP6Handler,
-    'IPV6_PREFIX_TKN':  Prefix6Handler,
-    'MAC_TKN':          PrefixEthHandler,
-    'MAC_PREFIX_TKN':   PrefixEthHandler,
+    "WORD_TKN": StringHandler,
+    "VARIABLE_TKN": StringHandler,
+    "RANGE_TKN": LongHandler,
+    "IPV4_TKN": IP4Handler,
+    "IPV4_PREFIX_TKN": Prefix4Handler,
+    "IPV6_TKN": IP6Handler,
+    "IPV6_PREFIX_TKN": Prefix6Handler,
+    "MAC_TKN": PrefixEthHandler,
+    "MAC_PREFIX_TKN": PrefixEthHandler,
 }
 
 # core template invoked for each occurence of DEFPY.
@@ -139,7 +172,8 @@ handlers = {
 # the "#if $..." bits are there to keep this template unified into one
 # common form, without requiring a more advanced template engine (e.g.
 # jinja2)
-templ = Template('''/* $fnname => "$cmddef" */
+templ = Template(
+    """/* $fnname => "$cmddef" */
 DEFUN_CMD_FUNC_DECL($fnname)
 #define funcdecl_$fnname static int ${fnname}_magic(\\
        const struct cmd_element *self __attribute__ ((unused)),\\
@@ -178,18 +212,22 @@ $argassert
        return ${fnname}_magic(self, vty, argc, argv$arglist);
 }
 
-''')
+"""
+)
 
 # invoked for each named parameter
-argblock = Template('''
+argblock = Template(
+    """
                if (!strcmp(argv[_i]->varname, \"$varname\")) {$strblock
                        $code
-               }''')
+               }"""
+)
 
-def get_always_args(token, always_args, args = [], stack = []):
+
+def get_always_args(token, always_args, args=[], stack=[]):
     if token in stack:
         return
-    if token.type == 'END_TKN':
+    if token.type == "END_TKN":
         for arg in list(always_args):
             if arg not in args:
                 always_args.remove(arg)
@@ -201,38 +239,45 @@ def get_always_args(token, always_args, args = [], stack = []):
     for nexttkn in token.next():
         get_always_args(nexttkn, always_args, args, stack)
 
+
 class Macros(dict):
     def load(self, filename):
         filedata = clippy.parse(filename)
-        for entry in filedata['data']:
-            if entry['type'] != 'PREPROC':
+        for entry in filedata["data"]:
+            if entry["type"] != "PREPROC":
                 continue
-            ppdir = entry['line'].lstrip().split(None, 1)
-            if ppdir[0] != 'define' or len(ppdir) != 2:
+            ppdir = entry["line"].lstrip().split(None, 1)
+            if ppdir[0] != "define" or len(ppdir) != 2:
                 continue
             ppdef = ppdir[1].split(None, 1)
             name = ppdef[0]
-            if '(' in name:
+            if "(" in name:
                 continue
-            val = ppdef[1] if len(ppdef) == 2 else ''
+            val = ppdef[1] if len(ppdef) == 2 else ""
 
-            val = val.strip(' \t\n\\')
+            val = val.strip(" \t\n\\")
             if name in self:
-                sys.stderr.write('warning: macro %s redefined!\n' % (name))
+                sys.stderr.write("warning: macro %s redefined!\n" % (name))
             self[name] = val
 
+
 def process_file(fn, ofd, dumpfd, all_defun, macros):
     errors = 0
     filedata = clippy.parse(fn)
 
-    for entry in filedata['data']:
-        if entry['type'].startswith('DEFPY') or (all_defun and entry['type'].startswith('DEFUN')):
-            if len(entry['args'][0]) != 1:
-                sys.stderr.write('%s:%d: DEFPY function name not parseable (%r)\n' % (fn, entry['lineno'], entry['args'][0]))
+    for entry in filedata["data"]:
+        if entry["type"].startswith("DEFPY") or (
+            all_defun and entry["type"].startswith("DEFUN")
+        ):
+            if len(entry["args"][0]) != 1:
+                sys.stderr.write(
+                    "%s:%d: DEFPY function name not parseable (%r)\n"
+                    % (fn, entry["lineno"], entry["args"][0])
+                )
                 errors += 1
                 continue
 
-            cmddef = entry['args'][2]
+            cmddef = entry["args"][2]
             cmddefx = []
             for i in cmddef:
                 while i in macros:
@@ -241,13 +286,16 @@ def process_file(fn, ofd, dumpfd, all_defun, macros):
                     cmddefx.append(i[1:-1])
                     continue
 
-                sys.stderr.write('%s:%d: DEFPY command string not parseable (%r)\n' % (fn, entry['lineno'], cmddef))
+                sys.stderr.write(
+                    "%s:%d: DEFPY command string not parseable (%r)\n"
+                    % (fn, entry["lineno"], cmddef)
+                )
                 errors += 1
                 cmddefx = None
                 break
             if cmddefx is None:
                 continue
-            cmddef = ''.join([i for i in cmddefx])
+            cmddef = "".join([i for i in cmddefx])
 
             graph = clippy.Graph(cmddef)
             args = OrderedDict()
@@ -263,12 +311,12 @@ def process_file(fn, ofd, dumpfd, all_defun, macros):
 
             get_always_args(graph.first(), always_args)
 
-            #print('-' * 76)
-            #pprint(entry)
-            #clippy.dump(graph)
-            #pprint(args)
+            # print('-' * 76)
+            # pprint(entry)
+            # clippy.dump(graph)
+            # pprint(args)
 
-            params = { 'cmddef': cmddef, 'fnname': entry['args'][0][0] }
+            params = {"cmddef": cmddef, "fnname": entry["args"][0][0]}
             argdefs = []
             argdecls = []
             arglist = []
@@ -277,63 +325,96 @@ def process_file(fn, ofd, dumpfd, all_defun, macros):
             doc = []
             canfail = 0
 
-            def do_add(handler, basename, varname, attr = ''):
-                argdefs.append(',\\\n\t%s %s%s' % (handler.argtype, varname, attr))
-                argdecls.append('\t%s\n' % (handler.decl.substitute({'varname': varname}).replace('\n', '\n\t')))
-                arglist.append(', %s%s' % (handler.deref, varname))
+            def do_add(handler, basename, varname, attr=""):
+                argdefs.append(",\\\n\t%s %s%s" % (handler.argtype, varname, attr))
+                argdecls.append(
+                    "\t%s\n"
+                    % (
+                        handler.decl.substitute({"varname": varname}).replace(
+                            "\n", "\n\t"
+                        )
+                    )
+                )
+                arglist.append(", %s%s" % (handler.deref, varname))
                 if basename in always_args and handler.canassert:
-                    argassert.append('''\tif (!%s) {
+                    argassert.append(
+                        """\tif (!%s) {
 \t\tvty_out(vty, "Internal CLI error [%%s]\\n", "%s");
 \t\treturn CMD_WARNING;
-\t}\n''' % (varname, varname))
-                if attr == '':
+\t}\n"""
+                        % (varname, varname)
+                    )
+                if attr == "":
                     at = handler.argtype
-                    if not at.startswith('const '):
-                        at = '. . . ' + at
-                    doc.append('\t%-26s %s  %s' % (at, 'alw' if basename in always_args else 'opt', varname))
+                    if not at.startswith("const "):
+                        at = ". . . " + at
+                    doc.append(
+                        "\t%-26s %s  %s"
+                        % (at, "alw" if basename in always_args else "opt", varname)
+                    )
 
             for varname in args.keys():
                 handler = mix_handlers(args[varname])
-                #print(varname, handler)
-                if handler is None: continue
+                # print(varname, handler)
+                if handler is None:
+                    continue
                 do_add(handler, varname, varname)
-                code = handler.code.substitute({'varname': varname}).replace('\n', '\n\t\t\t')
+                code = handler.code.substitute({"varname": varname}).replace(
+                    "\n", "\n\t\t\t"
+                )
                 if handler.canfail:
                     canfail = 1
-                strblock = ''
+                strblock = ""
                 if not handler.drop_str:
-                    do_add(StringHandler(None), varname, '%s_str' % (varname), ' __attribute__ ((unused))')
-                    strblock = '\n\t\t\t%s_str = argv[_i]->arg;' % (varname)
-                argblocks.append(argblock.substitute({'varname': varname, 'strblock': strblock, 'code': code}))
+                    do_add(
+                        StringHandler(None),
+                        varname,
+                        "%s_str" % (varname),
+                        " __attribute__ ((unused))",
+                    )
+                    strblock = "\n\t\t\t%s_str = argv[_i]->arg;" % (varname)
+                argblocks.append(
+                    argblock.substitute(
+                        {"varname": varname, "strblock": strblock, "code": code}
+                    )
+                )
 
             if dumpfd is not None:
                 if len(arglist) > 0:
-                    dumpfd.write('"%s":\n%s\n\n' % (cmddef, '\n'.join(doc)))
+                    dumpfd.write('"%s":\n%s\n\n' % (cmddef, "\n".join(doc)))
                 else:
                     dumpfd.write('"%s":\n\t---- no magic arguments ----\n\n' % (cmddef))
 
-            params['argdefs'] = ''.join(argdefs)
-            params['argdecls'] = ''.join(argdecls)
-            params['arglist'] = ''.join(arglist)
-            params['argblocks'] = ''.join(argblocks)
-            params['canfail'] = canfail
-            params['nonempty'] = len(argblocks)
-            params['argassert'] = ''.join(argassert)
+            params["argdefs"] = "".join(argdefs)
+            params["argdecls"] = "".join(argdecls)
+            params["arglist"] = "".join(arglist)
+            params["argblocks"] = "".join(argblocks)
+            params["canfail"] = canfail
+            params["nonempty"] = len(argblocks)
+            params["argassert"] = "".join(argassert)
             ofd.write(templ.substitute(params))
 
     return errors
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     import argparse
 
-    argp = argparse.ArgumentParser(description = 'FRR CLI preprocessor in Python')
-    argp.add_argument('--all-defun', action = 'store_const', const = True,
-            help = 'process DEFUN() statements in addition to DEFPY()')
-    argp.add_argument('--show', action = 'store_const', const = True,
-            help = 'print out list of arguments and types for each definition')
-    argp.add_argument('-o', type = str, metavar = 'OUTFILE',
-            help = 'output C file name')
-    argp.add_argument('cfile', type = str)
+    argp = argparse.ArgumentParser(description="FRR CLI preprocessor in Python")
+    argp.add_argument(
+        "--all-defun",
+        action="store_const",
+        const=True,
+        help="process DEFUN() statements in addition to DEFPY()",
+    )
+    argp.add_argument(
+        "--show",
+        action="store_const",
+        const=True,
+        help="print out list of arguments and types for each definition",
+    )
+    argp.add_argument("-o", type=str, metavar="OUTFILE", help="output C file name")
+    argp.add_argument("cfile", type=str)
     args = argp.parse_args()
 
     dumpfd = None
@@ -349,15 +430,17 @@ if __name__ == '__main__':
     basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
     macros = Macros()
-    macros.load('lib/route_types.h')
-    macros.load(os.path.join(basepath, 'lib/command.h'))
-    macros.load(os.path.join(basepath, 'bgpd/bgp_vty.h'))
+    macros.load("lib/route_types.h")
+    macros.load(os.path.join(basepath, "lib/command.h"))
+    macros.load(os.path.join(basepath, "bgpd/bgp_vty.h"))
     # sigh :(
-    macros['PROTO_REDIST_STR'] = 'FRR_REDIST_STR_ISISD'
+    macros["PROTO_REDIST_STR"] = "FRR_REDIST_STR_ISISD"
 
     errors = process_file(args.cfile, ofd, dumpfd, args.all_defun, macros)
     if errors != 0:
         sys.exit(1)
 
     if args.o is not None:
-        clippy.wrdiff(args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable])
+        clippy.wrdiff(
+            args.o, ofd, [args.cfile, os.path.realpath(__file__), sys.executable]
+        )
index 41aeae6b4d8da09b58051ba4e0b8018954af5886..d6865ff4842e6c0e7738f43b7fd692b87557611e 100644 (file)
@@ -20,11 +20,12 @@ import os, stat
 import _clippy
 from _clippy import parse, Graph, GraphNode
 
+
 def graph_iterate(graph):
-    '''iterator yielding all nodes of a graph
+    """iterator yielding all nodes of a graph
 
     nodes arrive in input/definition order, graph circles are avoided.
-    '''
+    """
 
     queue = [(graph.first(), frozenset(), 0)]
     while len(queue) > 0:
@@ -42,21 +43,25 @@ def graph_iterate(graph):
             if n not in stop and n is not node:
                 queue.insert(0, (n, stop, depth + 1))
 
+
 def dump(graph):
-    '''print out clippy.Graph'''
+    """print out clippy.Graph"""
 
     for i, depth in graph_iterate(graph):
-        print('\t%s%s %r' % ('  ' * (depth * 2), i.type, i.text))
+        print("\t%s%s %r" % ("  " * (depth * 2), i.type, i.text))
+
 
-def wrdiff(filename, buf, reffiles = []):
-    '''write buffer to file if contents changed'''
+def wrdiff(filename, buf, reffiles=[]):
+    """write buffer to file if contents changed"""
 
-    expl = ''
-    if hasattr(buf, 'getvalue'):
+    expl = ""
+    if hasattr(buf, "getvalue"):
         buf = buf.getvalue()
     old = None
-    try:    old = open(filename, 'r').read()
-    except: pass
+    try:
+        old = open(filename, "r").read()
+    except:
+        pass
     if old == buf:
         for reffile in reffiles:
             # ensure output timestamp is newer than inputs, for make
@@ -67,7 +72,7 @@ def wrdiff(filename, buf, reffiles = []):
         # sys.stderr.write('%s unchanged, not written\n' % (filename))
         return
 
-    newname = '%s.new-%d' % (filename, os.getpid())
-    with open(newname, 'w') as out:
+    newname = "%s.new-%d" % (filename, os.getpid())
+    with open(newname, "w") as out:
         out.write(buf)
     os.rename(newname, filename)
index 19a85b63e5f36e7900e799348820e29d07ca6a3f..bf50f33a334f6d5feadf10c51415878abd9c34f5 100644 (file)
@@ -9,21 +9,21 @@ include_re = re.compile('^#\s*include\s+["<]([^ ">]+)[">]', re.M)
 
 errors = 0
 
-files = subprocess.check_output(['git', 'ls-files']).decode('ASCII')
+files = subprocess.check_output(["git", "ls-files"]).decode("ASCII")
 for fn in files.splitlines():
-    if not fn.endswith('.c'):
+    if not fn.endswith(".c"):
         continue
-    if fn.startswith('tools/'):
+    if fn.startswith("tools/"):
         continue
-    with open(fn, 'r') as fd:
+    with open(fn, "r") as fd:
         data = fd.read()
         m = include_re.search(data)
         if m is None:
-            #sys.stderr.write('no #include in %s?\n' % (fn))
+            # sys.stderr.write('no #include in %s?\n' % (fn))
             continue
-        if m.group(1) in ['config.h', 'zebra.h', 'lib/zebra.h']:
+        if m.group(1) in ["config.h", "zebra.h", "lib/zebra.h"]:
             continue
-        sys.stderr.write('%s: %s\n' % (fn, m.group(0)))
+        sys.stderr.write("%s: %s\n" % (fn, m.group(0)))
         errors += 1
 
 if errors:
index fe20945ccccbfee16c8ffbe3f09ae42fffba5f31..10c73df72df3a3873750730f48091ad98b4c21c0 100644 (file)
@@ -13,69 +13,91 @@ import argparse
 from string import Template
 from makevars import MakeReVars
 
-argp = argparse.ArgumentParser(description = 'FRR Makefile extensions')
-argp.add_argument('--dev-build', action = 'store_const', const = True,
-            help = 'run additional developer checks')
+argp = argparse.ArgumentParser(description="FRR Makefile extensions")
+argp.add_argument(
+    "--dev-build",
+    action="store_const",
+    const=True,
+    help="run additional developer checks",
+)
 args = argp.parse_args()
 
-with open('Makefile', 'r') as fd:
+with open("Makefile", "r") as fd:
     before = fd.read()
 
 mv = MakeReVars(before)
 
-clippy_scan = mv['clippy_scan'].strip().split()
+clippy_scan = mv["clippy_scan"].strip().split()
 for clippy_file in clippy_scan:
-    assert clippy_file.endswith('.c')
+    assert clippy_file.endswith(".c")
 
 # check for files using clippy but not listed in clippy_scan
 if args.dev_build:
     basepath = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-    if os.path.exists(os.path.join(basepath, '.git')):
-        clippy_ref = subprocess.check_output([
-            'git', '-C', basepath, 'grep', '-l', '-P', '^#\s*include.*_clippy.c', '--', '**.c']).decode('US-ASCII')
+    if os.path.exists(os.path.join(basepath, ".git")):
+        clippy_ref = subprocess.check_output(
+            [
+                "git",
+                "-C",
+                basepath,
+                "grep",
+                "-l",
+                "-P",
+                "^#\s*include.*_clippy.c",
+                "--",
+                "**.c",
+            ]
+        ).decode("US-ASCII")
 
         clippy_ref = set(clippy_ref.splitlines())
         missing = clippy_ref - set(clippy_scan)
 
         if len(missing) > 0:
-            sys.stderr.write('error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n' % ('\n\t'.join(sorted(missing))))
+            sys.stderr.write(
+                'error: files seem to be using clippy, but not listed in "clippy_scan" in subdir.am:\n\t%s\n'
+                % ("\n\t".join(sorted(missing)))
+            )
             sys.exit(1)
 
-clippydep = Template('''
+clippydep = Template(
+    """
 ${clippybase}.$$(OBJEXT): ${clippybase}_clippy.c
 ${clippybase}.lo: ${clippybase}_clippy.c
-${clippybase}_clippy.c: $$(CLIPPY_DEPS)''')
+${clippybase}_clippy.c: $$(CLIPPY_DEPS)"""
+)
 
-clippyauxdep = Template('''# clippy{
+clippyauxdep = Template(
+    """# clippy{
 # auxiliary clippy target
 ${target}: ${clippybase}_clippy.c
-# }clippy''')
+# }clippy"""
+)
 
 lines = before.splitlines()
-autoderp = '#AUTODERP# '
+autoderp = "#AUTODERP# "
 out_lines = []
 bcdeps = []
-make_rule_re = re.compile('^([^:\s]+):\s*([^:\s]+)\s*($|\n)')
+make_rule_re = re.compile("^([^:\s]+):\s*([^:\s]+)\s*($|\n)")
 
 while lines:
     line = lines.pop(0)
     if line.startswith(autoderp):
-        line = line[len(autoderp):]
+        line = line[len(autoderp) :]
 
-    if line == '# clippy{':
+    if line == "# clippy{":
         while lines:
             line = lines.pop(0)
-            if line == '# }clippy':
+            if line == "# }clippy":
                 break
         continue
 
-    if line.startswith('#'):
+    if line.startswith("#"):
         out_lines.append(line)
         continue
 
     full_line = line
     full_lines = lines[:]
-    while full_line.endswith('\\'):
+    while full_line.endswith("\\"):
         full_line = full_line[:-1] + full_lines.pop(0)
 
     m = make_rule_re.match(full_line)
@@ -87,43 +109,51 @@ while lines:
 
     target, dep = m.group(1), m.group(2)
 
-    if target.endswith('.lo') or target.endswith('.o'):
-        if not dep.endswith('.h'):
-            bcdeps.append('%s.bc: %s' % (target, target))
-            bcdeps.append('\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s' % (dep))
+    if target.endswith(".lo") or target.endswith(".o"):
+        if not dep.endswith(".h"):
+            bcdeps.append("%s.bc: %s" % (target, target))
+            bcdeps.append("\t$(AM_V_LLVM_BC)$(COMPILE) -emit-llvm -c -o $@ %s" % (dep))
     if m.group(2) in clippy_scan:
-        out_lines.append(clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2]))
+        out_lines.append(
+            clippyauxdep.substitute(target=m.group(1), clippybase=m.group(2)[:-2])
+        )
 
     out_lines.append(line)
 
-out_lines.append('# clippy{\n# main clippy targets')
+out_lines.append("# clippy{\n# main clippy targets")
 for clippy_file in clippy_scan:
-    out_lines.append(clippydep.substitute(clippybase = clippy_file[:-2]))
+    out_lines.append(clippydep.substitute(clippybase=clippy_file[:-2]))
 
-out_lines.append('')
+out_lines.append("")
 out_lines.extend(bcdeps)
-out_lines.append('')
+out_lines.append("")
 bc_targets = []
-for varname in ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES', 'noinst_LIBRARIES']:
+for varname in [
+    "bin_PROGRAMS",
+    "sbin_PROGRAMS",
+    "lib_LTLIBRARIES",
+    "module_LTLIBRARIES",
+    "noinst_LIBRARIES",
+]:
     bc_targets.extend(mv[varname].strip().split())
 for target in bc_targets:
-    amtgt = target.replace('/', '_').replace('.', '_').replace('-', '_')
-    objs = mv[amtgt + '_OBJECTS'].strip().split()
-    objs = [obj + '.bc' for obj in objs]
-    deps = mv.get(amtgt + '_DEPENDENCIES', '').strip().split()
-    deps = [d + '.bc' for d in deps if d.endswith('.a')]
+    amtgt = target.replace("/", "_").replace(".", "_").replace("-", "_")
+    objs = mv[amtgt + "_OBJECTS"].strip().split()
+    objs = [obj + ".bc" for obj in objs]
+    deps = mv.get(amtgt + "_DEPENDENCIES", "").strip().split()
+    deps = [d + ".bc" for d in deps if d.endswith(".a")]
     objs.extend(deps)
-    out_lines.append('%s.bc: %s' % (target, ' '.join(objs)))
-    out_lines.append('\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^')
-    out_lines.append('')
+    out_lines.append("%s.bc: %s" % (target, " ".join(objs)))
+    out_lines.append("\t$(AM_V_LLVM_LD)$(LLVM_LINK) -o $@ $^")
+    out_lines.append("")
 
-out_lines.append('# }clippy')
-out_lines.append('')
+out_lines.append("# }clippy")
+out_lines.append("")
 
-after = '\n'.join(out_lines)
+after = "\n".join(out_lines)
 if after == before:
     sys.exit(0)
 
-with open('Makefile.pyout', 'w') as fd:
+with open("Makefile.pyout", "w") as fd:
     fd.write(after)
-os.rename('Makefile.pyout', 'Makefile')
+os.rename("Makefile.pyout", "Makefile")
index 63bf8c5eeb3b0e773ec42432d48635f2f6b99cd4..951cd3438b75fe05c635998613a406b0d6979144 100644 (file)
@@ -6,10 +6,12 @@ import os
 import subprocess
 import re
 
+
 class MakeVarsBase(object):
-    '''
+    """
     common code between MakeVars and MakeReVars
-    '''
+    """
+
     def __init__(self):
         self._data = dict()
 
@@ -18,31 +20,35 @@ class MakeVarsBase(object):
             self.getvars([k])
         return self._data[k]
 
-    def get(self, k, defval = None):
+    def get(self, k, defval=None):
         if k not in self._data:
             self.getvars([k])
         return self._data.get(k) or defval
 
+
 class MakeVars(MakeVarsBase):
-    '''
+    """
     makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile
 
     This variant works by invoking make as a subprocess, i.e. Makefile must
     be valid and working.  (This is sometimes a problem if depfiles have not
     been generated.)
-    '''
+    """
+
     def getvars(self, varlist):
-        '''
+        """
         get a batch list of variables from make.  faster than individual calls.
-        '''
+        """
         rdfd, wrfd = os.pipe()
 
-        shvars = ['shvar-%s' % s for s in varlist]
-        make = subprocess.Popen(['make', '-s', 'VARFD=%d' % wrfd] + shvars, pass_fds = [wrfd])
+        shvars = ["shvar-%s" % s for s in varlist]
+        make = subprocess.Popen(
+            ["make", "-s", "VARFD=%d" % wrfd] + shvars, pass_fds=[wrfd]
+        )
         os.close(wrfd)
-        data = b''
+        data = b""
 
-        rdf = os.fdopen(rdfd, 'rb')
+        rdf = os.fdopen(rdfd, "rb")
         while True:
             rdata = rdf.read()
             if len(rdata) == 0:
@@ -52,30 +58,34 @@ class MakeVars(MakeVarsBase):
         del rdf
         make.wait()
 
-        data = data.decode('US-ASCII').strip().split('\n')
+        data = data.decode("US-ASCII").strip().split("\n")
         for row in data:
-            k, v = row.split('=', 1)
+            k, v = row.split("=", 1)
             v = v[1:-1]
             self._data[k] = v
 
+
 class MakeReVars(MakeVarsBase):
-    '''
+    """
     makevars['FOO_CFLAGS'] gets you "FOO_CFLAGS" from Makefile
 
     This variant works by regexing through Makefile.  This means the Makefile
     does not need to be fully working, but on the other hand it doesn't support
     fancy complicated make expressions.
-    '''
-    var_re = re.compile(r'^([^=#\n\s]+)[ \t]*=[ \t]*([^#\n]*)(?:#.*)?$', flags=re.MULTILINE)
-    repl_re = re.compile(r'\$(?:([A-Za-z])|\(([^\)]+)\))')
+    """
+
+    var_re = re.compile(
+        r"^([^=#\n\s]+)[ \t]*=[ \t]*([^#\n]*)(?:#.*)?$", flags=re.MULTILINE
+    )
+    repl_re = re.compile(r"\$(?:([A-Za-z])|\(([^\)]+)\))")
 
     def __init__(self, maketext):
         super(MakeReVars, self).__init__()
-        self._vars = dict(self.var_re.findall(maketext.replace('\\\n', '')))
+        self._vars = dict(self.var_re.findall(maketext.replace("\\\n", "")))
 
     def replacevar(self, match):
         varname = match.group(1) or match.group(2)
-        return self._vars.get(varname, '')
+        return self._vars.get(varname, "")
 
     def getvars(self, varlist):
         for varname in varlist:
index bd0d5b27f4857925b7168aa8e040e7e73914e46d..e72d2e3f36264729af55ff3a39ea9fca4465da6f 100644 (file)
@@ -25,7 +25,6 @@
 %{!?with_pbrd:          %global  with_pbrd          1 }
 %{!?with_pimd:          %global  with_pimd          1 }
 %{!?with_vrrpd:         %global  with_vrrpd         1 }
-%{!?with_rpki:          %global  with_rpki          0 }
 %{!?with_rtadv:         %global  with_rtadv         1 }
 %{!?with_watchfrr:      %global  with_watchfrr      1 }
 
@@ -192,9 +191,6 @@ Requires:       initscripts
 %if %{with_pam}
 BuildRequires:  pam-devel
 %endif
-%if %{with_rpki}
-BuildRequires:  librtr-devel >= 0.5
-%endif
 %if "%{initsystem}" == "systemd"
 BuildRequires:      systemd
 BuildRequires:      systemd-devel
@@ -261,6 +257,32 @@ The frr-devel package contains the header and object files neccessary for
 developing OSPF-API and frr applications.
 
 
+%package rpki-rtrlib
+Summary: BGP RPKI support (rtrlib)
+Group: System Environment/Daemons
+BuildRequires:  librtr-devel >= 0.5
+Requires: %{name} = %{version}-%{release}
+
+%description rpki-rtrlib
+Adds RPKI support to FRR's bgpd, allowing validation of BGP routes
+against cryptographic information stored in WHOIS databases.  This is
+used to prevent hijacking of networks on the wider internet.  It is only
+relevant to internet service providers using their own autonomous system
+number.
+
+
+%package snmp
+Summary: SNMP support
+Group: System Environment/Daemons
+BuildRequires: net-snmp-devel
+Requires: %{name} = %{version}-%{release}
+
+%description snmp
+Adds SNMP support to FRR's daemons by attaching to net-snmp's snmpd
+through the AgentX protocol.  Provides read-only access to current
+routing state through standard SNMP MIBs.
+
+
 %prep
 %setup -q -n frr-%{frrversion}
 
@@ -370,16 +392,13 @@ developing OSPF-API and frr applications.
 %if "%{initsystem}" == "systemd"
     --enable-systemd \
 %endif
-%if %{with_rpki}
     --enable-rpki \
-%else
-    --disable-rpki \
-%endif
 %if %{with_bfdd}
     --enable-bfdd \
 %else
     --disable-bfdd \
 %endif
+    --enable-snmp
     # end
 
 make %{?_smp_mflags} MAKEINFO="makeinfo --no-split"
@@ -425,10 +444,6 @@ ln -s %{_sbindir}/frrinit.sh %{buildroot}%{_initddir}/frr
 %endif
 
 install %{zeb_src}/tools/etc/frr/daemons %{buildroot}%{_sysconfdir}/frr
-# add rpki module to daemon
-%if %{with_rpki}
-    sed -i -e 's/^\(bgpd_options=\)\(.*\)\(".*\)/\1\2 -M rpki\3/' %{buildroot}%{_sysconfdir}/frr/daemons
-%endif
 install -m644 %{zeb_rh_src}/frr.pam %{buildroot}%{_sysconfdir}/pam.d/frr
 install -m644 %{zeb_rh_src}/frr.logrotate %{buildroot}%{_sysconfdir}/logrotate.d/frr
 install -d -m750 %{buildroot}%{rundir}
@@ -666,14 +681,12 @@ fi
 %if %{with_bfdd}
     %{_sbindir}/bfdd
 %endif
-%{_libdir}/lib*.so.0
-%{_libdir}/lib*.so.0.*
+%{_libdir}/libfrr.so*
+%{_libdir}/libfrrcares*
+%{_libdir}/libfrrospf*
 %if %{with_fpm}
     %{_libdir}/frr/modules/zebra_fpm.so
 %endif
-%if %{with_rpki}
-    %{_libdir}/frr/modules/bgpd_rpki.so
-%endif
 %{_libdir}/frr/modules/zebra_cumulus_mlag.so
 %{_libdir}/frr/modules/dplane_fpm_nl.so
 %{_libdir}/frr/modules/zebra_irdp.so
@@ -706,12 +719,28 @@ fi
 %else
 %{_sbindir}/generate_support_bundle.pyc
 %{_sbindir}/generate_support_bundle.pyo
-%{_sbindir}/frr-reload.py
 %{_sbindir}/frr-reload.pyc
 %{_sbindir}/frr-reload.pyo
 %endif
 
 
+%post rpki-rtrlib
+# add rpki module to daemons
+sed -i -e 's/^\(bgpd_options=\)\(.*\)\(".*\)/\1\2 -M rpki\3/' %{_sysconfdir}/frr/daemons
+
+%postun rpki-rtrlib
+# remove rpki module from daemons
+sed -i 's/ -M rpki//' %{_sysconfdir}/frr/daemons
+
+%files rpki-rtrlib
+%{_libdir}/frr/modules/bgpd_rpki.so
+
+
+%files snmp
+%{_libdir}/libfrrsnmp.so*
+%{_libdir}/frr/modules/*snmp.so
+
+
 %files devel
 %{_libdir}/lib*.so
 %dir %{_includedir}/%{name}
@@ -729,10 +758,288 @@ fi
 
 
 %changelog
+* Fri Oct 30 2020 Martin Winter <mwinter@opensourcerouting.org> - %{version}
+- Moved RPKI to subpackage
+- Added SNMP subpackage
+
+* Tue Jun 30 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.4
+- BGPd
+-    Use sequence numbers for community lists
+-    Fixes to nexthop groups
+-    Add feature to limit outgoing number of routes
+-    Per Neighbor Graceful Restart
+-    Multiple Graceful Restart fixes
+-    Support sub-Type-4 and sub-Type-5 for the VPNv4 SRv6 backend
+-    rfc7606 support: treat certain malformed routes as withdraw
+-    allow origin override for route aggregates
+-    rfc6608 support: Subcodes for BGP Finite State Machine Error
+-    rfc7607 support: Codification of AS 0 Processing
+-    rfc6286 support: Autonomous-System-Wide Unique BGP Identifier for BGP-4
+-    Unequal cost multipath (a.ka. weighted ECMP) with BGP link-bandwidth
+-    Enable rfc8212 by default except datacenter profile
+- staticd
+-    Add debug support
+- vtysh
+-    Add copy command to copy config from file into running config
+- LDPd
+-    adding support for LDP ordered label distribution control
+- ISISd
+-    IS-IS Segment Routing support
+- SHARPd
+-    add initial support to add/remove lsps
+- Zebra
+-    fix broadcast address in IPv4 networks with /31 mask
+-    Add Graceful Restart support for Protocol Daemon restarts
+- lib
+-    migrate route-maps to use northbound interface
+- plus countless bug fixes and other improvements
+
+* Wed May 06 2020 David Lamparter <equinox@opensourcerouting.org> - 7.3.1
+- upstream 7.3.1
+
+* Fri Feb 14 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.3
+- BGPd
+-    EVPN PIP Support
+-    Route Aggregation code speed ups
+-    BGP Vector I/O speed ups
+-    New CLI: `set distance XXX`
+-    New CLI: `aggregate-address A.B.C.D/M route-map WORD`
+-    New CLI: `bgp reject-as-sets`
+-    New CLI: `advertise pip ...`
+-    New CLI: `match evpn rd ASN:NN_OR_IP-ADDRESS:NN`
+-    New CLI: `show bgp l2vpn evpn community|large-community X`
+-    New CLI: `show bgp l2vpn evpn A.B.C.D`
+-    Auto-completion for clear bgp command
+-    Add ability to set tcp socket buffer size
+- OSPFd
+-    Partial MPLS TE support
+- PBRd
+-    New CLI: `set vrf unchanged|NAME`
+- BFDd
+-    VRF Support
+-    New CLI: 'show bfd peers brief'
+-    New CLI: 'clear bfd peer ...'
+- PIMd
+-    Significant Speedups in accessing Internal Data for higher scale
+-    Support for joining any-source Multicast
+-    Updated CLI: 'show ip pim upstream-join-desired'
+-    New CLI: 'show ip pim channel'
+-    Debug Cleanup
+-    MLAG experimental support
+- VRRPd
+-    VRF Support
+-    Northbound Conversion- NHRPd
+- LDPd
+- vtysh
+-    New CLI: `banner motd line LINE...`
+- yang
+-    New CLI: `show yang operational-data XPATH`
+-    New CLI: `debug northbound`
+- Zebra
+-    Nexthop Group support
+-    New CLI: 'debug zebra nexthop [detail]'
+-    New CLI: 'show router-id'
+-    MLAG experimental support
+- watchfrr
+-    Additional status messages of system state to systemd
+-    New CLI: `watchfrr ignore DAEMON`
+- Others
+-    As always all daemons have received too many bug fixes to fully list
+-    There has been a significant focus on increasing test coverage
+- Change in Behavior:
+-    ISISd
+-       All areas created default automatically to level-1-2
+-    Zebra
+-       Nexthop Group Installation in Kernel is turned on by default
+        if the kernel supports-    New CLI: 'show nexthop-group rib [singleton]'
+-    Man Pages
+-       Renamed to frr-* to remove collision with other packages
+
+* Fri Jan 17 2020 Martin Winter <mwinter@opensourcerouting.org> - 7.2.1
+- BGPd
+-   Fix Addpath issue
+-   Do not apply eBGP policy for iBGP peers
+-   Show `ip` and `fqdn` in json output for `show [ip] bgp <route> json`
+-   Fix large route-distinguisher's format
+-   Fix `no bgp listen range ...` configuration command
+-   Autocomplete neighbor for clear bgp
+-   Reflect the distance in RIB when it is changed for an arbitrary afi/safi
+-   Notify "Peer De-configured" after entering 'no neighbor <neighbor> cmd
+-   Fix per afi/safi addpath peer counting
+-   Rework BGP dampening to be per AFI/SAFI
+-   Do not send next-hop as :: in MP_REACH_NLRI if no link-local exists
+-   Override peer's TTL only if peer-group is configured with TTL
+-   Remove error message for unkown afi/safi combination
+-   Keep the session down if maximum-prefix is reached
+- OSPFd
+-   Fix BFD down not tearing down OSPF adjacency for point-to-point net
+- BFDd
+-   Fix multiple VRF handling
+-   VRF security improvement
+- PIMd
+-   Fix rp crash
+- NHRPd
+-   Make sure `no ip nhrp map <something>` works as expected
+- LDPd
+-   Add missing sanity check in the parsing of label messages
+- Zebra
+-   Use correct state when installing evpn macs
+-   Capture dplane plugin flags
+- lib
+-   Fix interface config when vrf changes
+-   Fix Interface Infinite Loop Walk (for special interfaces such as bond)
+- snapcraft
+-   fix missing vrrpd daemon
+- Others
+-   Rename man pages (to avoid conflicts with other packages)
+-   Various other fixes for code cleanup and memory leaks
+
 * Fri Dec 27 2019 Donatas Abraitis <donatas.abraitis@gmail.com>
 - Add CentOS 8 support
 
-* Mon May 28 2018 Rafael Zalamena <rzalamena@opensourcerouting.org> - %{version}
+* Tue Oct 15 2019 Martin Winter <mwinter@opensourcerouting.org> - 7.2
+- ALL Daemons
+-   -N <namespace> to allow for config file locating when running FRR inside
+     of a namespace
+-   Impoved Testing across all daemons
+- BFD
+-   VRF Support
+-   Conversion to Northbound interface
+- BGP
+-   Aggregate-address add route-map support
+-   BMP Support
+-   Improved JSON output for many commands
+-   `show bgp afi safi summary failed` command
+-   `clear bop *` clears all peers
+-   Show FQDN for `show bgp ipv4 uni` commands
+-   Display BestPath selection reason as part of show commands
+- EIGRP
+-   Infrastructure changes to allow VRF's
+-   SIGHUP signals the config reload
+-   Conversion to Northbound interface
+- ISIS
+-   BFD Support
+-   Support for circuits with MTU > 8192
+- PBRD
+-   fwmark support as part of match criteria
+-   autocompletion of PBRMAPS
+-   Improved Nexthop Support
+- PIMD
+-   PIM-BSM receive support
+-   Improved debugging support
+-   Store ECMP paths that are not currently legal for use
+-   Disallow igmp query from a non-connected source
+-   Many new cli improvements and changes
+- VRRPD
+-   Add Support for RFC 3768 and RFC 5798
+- Route-Maps
+-   Add sequence numbers to access-lists
+-   Add `match ip next-hop type blackhole`
+-   Improved ability to notice dependency changes
+- SHARPD
+-   `sharp watch [import|nexthop]` you can now specify a prefix instead
+    of assuming a /32
+- STATICD
+-   Significantly Improved NHT
+- ZEBRA
+-   Many dataplane improvements for routes, neighbor table and EVPN
+-   NHT cli can now be specified per VRF and improved ability to control
+    NHT data being shown
+-   Removed duplicate processing of routes
+-   Improved debugablility
+-   RMAC and VxLan support for the FPM
+- LIB
+-   RCU support
+-   Nexthop Group Improvements
+-   `log-filter WORD` added
+- Building
+-   openssl support
+-   libcap should be used as part of build or significant slowdowns
+    will be experienced
+-   Lua builds have been fixed
+-   Improved Cross building
+
+* Mon Jun 17 2019 David Lamparter <equinox@opensourcerouting.org> - 7.1
+- gRPC northbound plugin
+- "table NNN" removed from zebra
+- more dataplane MT work
+- EVPN in non-default VRFs
+- RFC 8212 (default deny policy for eBGP)
+- RFC 8106 (IPv6 RA DNS options)
+
+* Wed May  8 2019 Martin Winter <mwinter@opensourcerouting.org> - 7.0.1
+- bgp:
+-   Don't send Updates with BGP Max-Prefix Overflow
+-   Make sure `next-hop-self all` backward compatible with force
+-   Fix as-path validation in "show bgp regexp"
+-   Fix interface-based peers to override peergroups
+-   Fix removing private AS numbers if local-as is used
+-   Fix show bgp labeled_unicast
+-   Add command to lookup prefixes in rpki table
+-   Fix peer count in "show bgp ipv6 summary"
+-   Add missing ipv6 only peer flag action
+-   Fix address family output in "show bgp [ipv4|ipv6] neighbors"
+-   Add missing checks for vpnv6 nexthops
+-   Fix nexthop for ipv6 vpn case
+- rip: Fix removal of passive interfaces
+- ospf:
+-   Fix json timer output
+-   Fix milliseconds in json output
+- bfd:
+-   Fix source port according RFC 5881, Sec 4
+-   Fix IPv6 link-local peer removal
+-   Fix interface clean up when deleting interface
+- pim: Fix interface clean up when deleting interface
+- nhrp: Fix interface clean up when deleting interface
+- lib:
+-   Workaround to get FRR building with libyang 0.x and 1.x
+-   Fix in priv handling
+-   Make priv elevation thread-safe
+- zebra:
+-   Pseudowire event recovery
+-   Fix race condition in label manager
+-   Fix system routes selection and next-hop tracking
+-   Set connected route metric based on devaddr metric
+-   Display metric for connected routes
+-   Add selected fib details to json output
+-   Always use replace if installing new route
+- watchfrr: Silently ignore declare failures (for backward compatibility)
+- RPM packages: Switch to new init script
+
+* Thu Feb 28 2019 Martin Winter <mwinter@opensourcerouting.org> - 7.0
+- Added libyang dependency: New work for northbound interface based on libyang
+- Fabricd: New Daemon based on https://datatracker.ietf.org/doc/draft-white-openfabric/
+- various bug fixes and other enhancements
+
+* Sun Oct  7 2018 Martin Winter <mwinter@opensourcerouting.org> - 6.0
+- Staticd: New daemon responsible for management of static routes
+- ISISd: Implement dst-src routing as per draft-ietf-isis-ipv6-dst-src-routing
+- BFDd: new daemon for BFD (Bidrectional Forwarding Detection). Responsible
+  for notifying link changes to make routing protocols converge faster.
+- various bug fixes
+
+* Thu Jul  5 2018 Martin Winter <mwinter@opensourcerouting.org> - 5.0.1
+- Support Automake 1.16.1
+- BGPd: Support for flowspec ICMP, DSCP, packet length, fragment and tcp flags
+- BGPd: fix rpki validation for ipv6
+- VRF: Workaround for kernel bug on Linux 4.14 and newer
+- Zebra: Fix interface based routes from zebra not marked up
+- Zebra: Fix large zebra memory usage when redistribute between protocols
+- Zebra: Allow route-maps to match on source instance
+- BGPd: Backport peer-attr overrides, peer-level enforce-first-as and filtered-routes fix
+- BGPd: fix for crash during display of filtered-routes
+- BGPd: Actually display labeled unicast routes received
+- Label Manager: Fix to work correctly behind a label manager proxy
+
+* Thu Jun  7 2018 Martin Winter <mwinter@opensourcerouting.org> - 5.0
+- PIM: Add a Multicast Trace Command draft-ietf-idmr-traceroute-ipm-05
+- IS-IS: Implement Three-Way Handshake as per RFC5303
+- BGPD: Implement VPN-VRF route leaking per RFC4364.
+- BGPD: Implement VRF with NETNS backend
+- BGPD: Flowspec
+- PBRD: Add a new Policy Based Routing Daemon
+
+* Mon May 28 2018 Rafael Zalamena <rzalamena@opensourcerouting.org>
 - Add BFDd support
 
 * Sun May 20 2018 Martin Winter <mwinter@opensourcerouting.org>
index 5e64b7afdb5a36d25c45674f00827d2b544a736c..87098ece64574442219f51cd1ad19a1d0c15a22a 100644 (file)
@@ -1012,7 +1012,7 @@ DEFPY_YANG (clear_ip_rip,
                listnode_add(input, yang_vrf);
        }
 
-       ret = nb_cli_rpc("/frr-ripd:clear-rip-route", input, NULL);
+       ret = nb_cli_rpc(vty, "/frr-ripd:clear-rip-route", input, NULL);
 
        list_delete(&input);
 
index aab756aee924b49db1033d44f6e3723a61e34f65..c601ab404737a8470bf125a5eaf36c75f6cc34c4 100644 (file)
@@ -172,8 +172,8 @@ static void rip_request_interface_send(struct interface *ifp, uint8_t version)
                                continue;
 
                        if (IS_RIP_DEBUG_EVENT)
-                               zlog_debug("SEND request to %s",
-                                          inet_ntoa(to.sin_addr));
+                               zlog_debug("SEND request to %pI4",
+                                          &to.sin_addr);
 
                        rip_request_send(&to, ifp, version, connected);
                }
@@ -468,10 +468,7 @@ static void rip_interface_clean(struct rip_interface *ri)
        ri->enable_interface = 0;
        ri->running = 0;
 
-       if (ri->t_wakeup) {
-               thread_cancel(ri->t_wakeup);
-               ri->t_wakeup = NULL;
-       }
+       thread_cancel(&ri->t_wakeup);
 }
 
 void rip_interfaces_clean(struct rip *rip)
@@ -603,8 +600,7 @@ int rip_interface_address_add(ZAPI_CALLBACK_ARGS)
 
        if (p->family == AF_INET) {
                if (IS_RIP_DEBUG_ZEBRA)
-                       zlog_debug("connected address %s/%d is added",
-                                  inet_ntoa(p->u.prefix4), p->prefixlen);
+                       zlog_debug("connected address %pFX is added", p);
 
                rip_enable_apply(ifc->ifp);
                /* Check if this prefix needs to be redistributed */
@@ -653,9 +649,8 @@ int rip_interface_address_delete(ZAPI_CALLBACK_ARGS)
                p = ifc->address;
                if (p->family == AF_INET) {
                        if (IS_RIP_DEBUG_ZEBRA)
-                               zlog_debug("connected address %s/%d is deleted",
-                                          inet_ntoa(p->u.prefix4),
-                                          p->prefixlen);
+                               zlog_debug("connected address %pFX is deleted",
+                                          p);
 
                        hook_call(rip_ifaddr_del, ifc);
 
@@ -1176,9 +1171,7 @@ int rip_show_network_config(struct vty *vty, struct rip *rip)
        for (node = route_top(rip->enable_network); node;
             node = route_next(node))
                if (node->info)
-                       vty_out(vty, "    %s/%u\n",
-                               inet_ntoa(node->p.u.prefix4),
-                               node->p.prefixlen);
+                       vty_out(vty, "    %pFX\n", &node->p);
 
        /* Interface name RIP enable statement. */
        for (i = 0; i < vector_active(rip->enable_interface); i++)
@@ -1188,7 +1181,7 @@ int rip_show_network_config(struct vty *vty, struct rip *rip)
        /* RIP neighbors listing. */
        for (node = route_top(rip->neighbor); node; node = route_next(node))
                if (node->info)
-                       vty_out(vty, "    %s\n", inet_ntoa(node->p.u.prefix4));
+                       vty_out(vty, "    %pI4\n", &node->p.u.prefix4);
 
        return 0;
 }
index 77c73ab398f12c65cfcf756b76ddd96d0c876a06..23599f08779019435a3eeeaa5a2e5a73968f4d75 100644 (file)
@@ -86,8 +86,7 @@ static struct rip_peer *rip_peer_get(struct rip *rip, struct in_addr *addr)
        peer = rip_peer_lookup(rip, addr);
 
        if (peer) {
-               if (peer->t_timeout)
-                       thread_cancel(peer->t_timeout);
+               thread_cancel(&peer->t_timeout);
        } else {
                peer = rip_peer_new();
                peer->rip = rip;
@@ -155,8 +154,8 @@ void rip_peer_display(struct vty *vty, struct rip *rip)
        char timebuf[RIP_UPTIME_LEN];
 
        for (ALL_LIST_ELEMENTS(rip->peer_list, node, nnode, peer)) {
-               vty_out(vty, "    %-16s %9d %9d %9d   %s\n",
-                       inet_ntoa(peer->addr), peer->recv_badpackets,
+               vty_out(vty, "    %-16pI4 %9d %9d %9d   %s\n",
+                       &peer->addr, peer->recv_badpackets,
                        peer->recv_badroutes, ZEBRA_RIP_DISTANCE_DEFAULT,
                        rip_peer_uptime(peer, timebuf, RIP_UPTIME_LEN));
        }
index e07d218860b522f0c03a97931fac5c20110f09ba..074370dc26fd3a77d441f80aaf7795c44edb973b 100644 (file)
@@ -88,18 +88,16 @@ static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp,
 
        if (IS_RIP_DEBUG_ZEBRA) {
                if (rip->ecmp)
-                       zlog_debug("%s: %s/%d nexthops %d",
+                       zlog_debug("%s: %pFX nexthops %d",
                                   (cmd == ZEBRA_ROUTE_ADD)
                                           ? "Install into zebra"
                                           : "Delete from zebra",
-                                  inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen,
-                                  count);
+                                  &rp->p, count);
                else
-                       zlog_debug("%s: %s/%d",
+                       zlog_debug("%s: %pFX",
                                   (cmd == ZEBRA_ROUTE_ADD)
                                           ? "Install into zebra"
-                                          : "Delete from zebra",
-                                  inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen);
+                                          : "Delete from zebra", &rp->p);
        }
 
        rip->counters.route_changes++;
index bcf73e8f8908e8c0a52c942df37cd414ac3c3c7e..059a0e2efd2c361daaa77b4f32987f8cdbd4c8b6 100644 (file)
@@ -45,6 +45,7 @@
 #include "lib_errors.h"
 #include "northbound_cli.h"
 #include "network.h"
+#include "lib/printfrr.h"
 
 #include "ripd/ripd.h"
 #include "ripd/rip_nb.h"
@@ -337,8 +338,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
                                      (struct prefix *)p)
                    == FILTER_DENY) {
                        if (IS_RIP_DEBUG_PACKET)
-                               zlog_debug("%s/%d filtered by distribute %s",
-                                          inet_ntoa(p->prefix), p->prefixlen,
+                               zlog_debug("%pFX filtered by distribute %s", p,
                                           inout);
                        return -1;
                }
@@ -348,8 +348,7 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
                                      (struct prefix *)p)
                    == PREFIX_DENY) {
                        if (IS_RIP_DEBUG_PACKET)
-                               zlog_debug("%s/%d filtered by prefix-list %s",
-                                          inet_ntoa(p->prefix), p->prefixlen,
+                               zlog_debug("%pFX filtered by prefix-list %s", p,
                                           inout);
                        return -1;
                }
@@ -367,9 +366,8 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
                                    == FILTER_DENY) {
                                        if (IS_RIP_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "%s/%d filtered by distribute %s",
-                                                       inet_ntoa(p->prefix),
-                                                       p->prefixlen, inout);
+                                                       "%pFX filtered by distribute %s",
+                                                       p, inout);
                                        return -1;
                                }
                        }
@@ -383,9 +381,8 @@ static int rip_filter(int rip_distribute, struct prefix_ipv4 *p,
                                    == PREFIX_DENY) {
                                        if (IS_RIP_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "%s/%d filtered by prefix-list %s",
-                                                       inet_ntoa(p->prefix),
-                                                       p->prefixlen, inout);
+                                                       "%pFX filtered by prefix-list %s",
+                                                       p, inout);
                                        return -1;
                                }
                        }
@@ -470,8 +467,8 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
                if (ret == RMAP_DENYMATCH) {
                        if (IS_RIP_DEBUG_PACKET)
                                zlog_debug(
-                                       "RIP %s/%d is filtered by route-map in",
-                                       inet_ntoa(p.prefix), p.prefixlen);
+                                       "RIP %pFX is filtered by route-map in",
+                                       &p);
                        return;
                }
 
@@ -506,8 +503,8 @@ static void rip_rte_process(struct rte *rte, struct sockaddr_in *from,
        /* Check if nexthop address is myself, then do nothing. */
        if (rip_nexthop_check(rip, nexthop) < 0) {
                if (IS_RIP_DEBUG_PACKET)
-                       zlog_debug("Nexthop address %s is myself",
-                                  inet_ntoa(*nexthop));
+                       zlog_debug("Nexthop address %pI4 is myself",
+                                  nexthop);
                return;
        }
 
@@ -834,8 +831,8 @@ static int rip_auth_simple_password(struct rte *rte, struct sockaddr_in *from,
        }
 
        if (IS_RIP_DEBUG_EVENT)
-               zlog_debug("RIPv2 simple password authentication from %s",
-                          inet_ntoa(from->sin_addr));
+               zlog_debug("RIPv2 simple password authentication from %pI4",
+                          &from->sin_addr);
 
        ri = ifp->info;
 
@@ -882,8 +879,8 @@ static int rip_auth_md5(struct rip_packet *packet, struct sockaddr_in *from,
        char auth_str[RIP_AUTH_MD5_SIZE] = {};
 
        if (IS_RIP_DEBUG_EVENT)
-               zlog_debug("RIPv2 MD5 authentication from %s",
-                          inet_ntoa(from->sin_addr));
+               zlog_debug("RIPv2 MD5 authentication from %pI4",
+                          &from->sin_addr);
 
        ri = ifp->info;
        md5 = (struct rip_md5_info *)&packet->rte;
@@ -1164,8 +1161,8 @@ static void rip_response_process(struct rip_packet *packet, int size,
                              rip->vrf->vrf_id)
            == NULL) {
                zlog_info(
-                       "This datagram doesn't came from a valid neighbor: %s",
-                       inet_ntoa(from->sin_addr));
+                       "This datagram doesn't come from a valid neighbor: %pI4",
+                       &from->sin_addr);
                rip_peer_bad_packet(rip, from);
                return;
        }
@@ -1194,9 +1191,9 @@ static void rip_response_process(struct rip_packet *packet, int size,
 
                if (rte->family != htons(AF_INET)) {
                        /* Address family check.  RIP only supports AF_INET. */
-                       zlog_info("Unsupported family %d from %s.",
+                       zlog_info("Unsupported family %d from %pI4",
                                  ntohs(rte->family),
-                                 inet_ntoa(from->sin_addr));
+                                 &from->sin_addr);
                        continue;
                }
 
@@ -1222,8 +1219,8 @@ static void rip_response_process(struct rip_packet *packet, int size,
                /* RIPv1 does not have nexthop value. */
                if (packet->version == RIPv1
                    && rte->nexthop.s_addr != INADDR_ANY) {
-                       zlog_info("RIPv1 packet with nexthop value %s",
-                                 inet_ntoa(rte->nexthop));
+                       zlog_info("RIPv1 packet with nexthop value %pI4",
+                                 &rte->nexthop);
                        rip_peer_bad_route(rip, from);
                        continue;
                }
@@ -1240,8 +1237,8 @@ static void rip_response_process(struct rip_packet *packet, int size,
                        addrval = ntohl(rte->nexthop.s_addr);
                        if (IN_CLASSD(addrval)) {
                                zlog_info(
-                                       "Nexthop %s is multicast address, skip this rte",
-                                       inet_ntoa(rte->nexthop));
+                                       "Nexthop %pI4 is multicast address, skip this rte",
+                                       &rte->nexthop);
                                continue;
                        }
 
@@ -1261,16 +1258,14 @@ static void rip_response_process(struct rip_packet *packet, int size,
                                                       == RIP_ROUTE_RTE) {
                                                if (IS_RIP_DEBUG_EVENT)
                                                        zlog_debug(
-                                                               "Next hop %s is on RIP network.  Set nexthop to the packet's originator",
-                                                               inet_ntoa(
-                                                                       rte->nexthop));
+                                                               "Next hop %pI4 is on RIP network.  Set nexthop to the packet's originator",
+                                                               &rte->nexthop);
                                                rte->nexthop = rinfo->from;
                                        } else {
                                                if (IS_RIP_DEBUG_EVENT)
                                                        zlog_debug(
-                                                               "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
-                                                               inet_ntoa(
-                                                                       rte->nexthop));
+                                                               "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0",
+                                                               &rte->nexthop);
                                                rte->nexthop.s_addr =
                                                        INADDR_ANY;
                                        }
@@ -1279,9 +1274,8 @@ static void rip_response_process(struct rip_packet *packet, int size,
                                } else {
                                        if (IS_RIP_DEBUG_EVENT)
                                                zlog_debug(
-                                                       "Next hop %s is not directly reachable. Treat it as 0.0.0.0",
-                                                       inet_ntoa(
-                                                               rte->nexthop));
+                                                       "Next hop %pI4 is not directly reachable. Treat it as 0.0.0.0",
+                                                       &rte->nexthop);
                                        rte->nexthop.s_addr = INADDR_ANY;
                                }
                        }
@@ -1335,8 +1329,8 @@ static void rip_response_process(struct rip_packet *packet, int size,
                                    != rte->prefix.s_addr)
                                        masklen2ip(32, &rte->mask);
                                if (IS_RIP_DEBUG_EVENT)
-                                       zlog_debug("Subnetted route %s",
-                                                  inet_ntoa(rte->prefix));
+                                       zlog_debug("Subnetted route %pI4",
+                                                  &rte->prefix);
                        } else {
                                if ((rte->prefix.s_addr & rte->mask.s_addr)
                                    != rte->prefix.s_addr)
@@ -1344,10 +1338,10 @@ static void rip_response_process(struct rip_packet *packet, int size,
                        }
 
                        if (IS_RIP_DEBUG_EVENT) {
-                               zlog_debug("Resultant route %s",
-                                          inet_ntoa(rte->prefix));
-                               zlog_debug("Resultant mask %s",
-                                          inet_ntoa(rte->mask));
+                               zlog_debug("Resultant route %pI4",
+                                          &rte->prefix);
+                               zlog_debug("Resultant mask %pI4",
+                                          &rte->mask);
                        }
                }
 
@@ -1358,8 +1352,8 @@ static void rip_response_process(struct rip_packet *packet, int size,
                    && ((rte->prefix.s_addr & rte->mask.s_addr)
                        != rte->prefix.s_addr)) {
                        zlog_warn(
-                               "RIPv2 address %s is not mask /%d applied one",
-                               inet_ntoa(rte->prefix), ip_masklen(rte->mask));
+                               "RIPv2 address %pI4 is not mask /%d applied one",
+                               &rte->prefix, ip_masklen(rte->mask));
                        rip_peer_bad_route(rip, from);
                        continue;
                }
@@ -1422,8 +1416,8 @@ int rip_create_socket(struct vrf *vrf)
        frr_with_privs(&ripd_privs) {
                if ((ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr)))
                    < 0) {
-                       zlog_err("%s: Can't bind socket %d to %s port %d: %s",
-                                __func__, sock, inet_ntoa(addr.sin_addr),
+                       zlog_err("%s: Can't bind socket %d to %pI4 port %d: %s",
+                                __func__, sock, &addr.sin_addr,
                                 (int)ntohs(addr.sin_port),
                                 safe_strerror(errno));
 
@@ -1463,14 +1457,14 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to,
                char dst[ADDRESS_SIZE];
 
                if (to) {
-                       strlcpy(dst, inet_ntoa(to->sin_addr), sizeof(dst));
+                       inet_ntop(AF_INET, &to->sin_addr, dst, sizeof(dst));
                } else {
                        sin.sin_addr.s_addr = htonl(INADDR_RIP_GROUP);
-                       strlcpy(dst, inet_ntoa(sin.sin_addr), sizeof(dst));
+                       inet_ntop(AF_INET, &sin.sin_addr, dst, sizeof(dst));
                }
 #undef ADDRESS_SIZE
-               zlog_debug("rip_send_packet %s > %s (%s)",
-                          inet_ntoa(ifc->address->u.prefix4), dst,
+               zlog_debug("rip_send_packet %pI4 > %s (%s)",
+                          &ifc->address->u.prefix4, dst,
                           ifc->ifp->name);
        }
 
@@ -1537,7 +1531,7 @@ static int rip_send_packet(uint8_t *buf, int size, struct sockaddr_in *to,
        ret = sendmsg(rip->sock, &msg, 0);
 
        if (IS_RIP_DEBUG_EVENT)
-               zlog_debug("SEND to  %s.%d", inet_ntoa(sin.sin_addr),
+               zlog_debug("SEND to  %pI4%d", &sin.sin_addr,
                           ntohs(sin.sin_port));
 
        if (ret < 0)
@@ -1603,8 +1597,7 @@ void rip_redistribute_add(struct rip *rip, int type, int sub_type,
                (void)rip_ecmp_add(rip, &newinfo);
 
        if (IS_RIP_DEBUG_EVENT) {
-               zlog_debug("Redistribute new prefix %s/%d",
-                          inet_ntoa(p->prefix), p->prefixlen);
+               zlog_debug("Redistribute new prefix %pFX", p);
        }
 
        rip_event(rip, RIP_TRIGGERED_UPDATE, 0);
@@ -1641,9 +1634,8 @@ void rip_redistribute_delete(struct rip *rip, int type, int sub_type,
 
                                if (IS_RIP_DEBUG_EVENT)
                                        zlog_debug(
-                                               "Poison %s/%d on the interface %s with an infinity metric [delete]",
-                                               inet_ntoa(p->prefix),
-                                               p->prefixlen,
+                                               "Poison %pFX on the interface %s with an infinity metric [delete]",
+                                               p,
                                                ifindex2ifname(
                                                        ifindex,
                                                        rip->vrf->vrf_id));
@@ -1788,15 +1780,15 @@ static int rip_read(struct thread *t)
 
        /* RIP packet received */
        if (IS_RIP_DEBUG_EVENT)
-               zlog_debug("RECV packet from %s port %d on %s (VRF %s)",
-                          inet_ntoa(from.sin_addr), ntohs(from.sin_port),
+               zlog_debug("RECV packet from %pI4 port %d on %s (VRF %s)",
+                          &from.sin_addr, ntohs(from.sin_port),
                           ifp ? ifp->name : "unknown", rip->vrf_name);
 
        /* If this packet come from unknown interface, ignore it. */
        if (ifp == NULL) {
                zlog_info(
-                       "rip_read: cannot find interface for packet from %s port %d (VRF %s)",
-                       inet_ntoa(from.sin_addr), ntohs(from.sin_port),
+                       "rip_read: cannot find interface for packet from %pI4 port %d (VRF %s)",
+                       &from.sin_addr, ntohs(from.sin_port),
                        rip->vrf_name);
                return -1;
        }
@@ -1809,8 +1801,8 @@ static int rip_read(struct thread *t)
 
        if (ifc == NULL) {
                zlog_info(
-                       "rip_read: cannot find connected address for packet from %s port %d on interface %s (VRF %s)",
-                       inet_ntoa(from.sin_addr), ntohs(from.sin_port),
+                       "rip_read: cannot find connected address for packet from %pI4 port %d on interface %s (VRF %s)",
+                       &from.sin_addr, ntohs(from.sin_port),
                        ifp->name, rip->vrf_name);
                return -1;
        }
@@ -2083,8 +2075,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
        /* Logging output event. */
        if (IS_RIP_DEBUG_EVENT) {
                if (to)
-                       zlog_debug("update routes to neighbor %s",
-                                  inet_ntoa(to->sin_addr));
+                       zlog_debug("update routes to neighbor %pI4",
+                                  &to->sin_addr);
                else
                        zlog_debug("update routes on interface %s ifindex %d",
                                   ifc->ifp->name, ifc->ifp->ifindex);
@@ -2149,9 +2141,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
 
                                if (IS_RIP_DEBUG_PACKET)
                                        zlog_debug(
-                                               "RIPv1 mask check, %s/%d considered for output",
-                                               inet_ntoa(rp->p.u.prefix4),
-                                               rp->p.prefixlen);
+                                               "RIPv1 mask check, %pFX considered for output",
+                                               &rp->p);
 
                                if (subnetted
                                    && prefix_match(
@@ -2172,9 +2163,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
                                }
                                if (IS_RIP_DEBUG_PACKET)
                                        zlog_debug(
-                                               "RIPv1 mask check, %s/%d made it through",
-                                               inet_ntoa(rp->p.u.prefix4),
-                                               rp->p.prefixlen);
+                                               "RIPv1 mask check, %pFX made it through",
+                                               &rp->p);
                        } else
                                p = (struct prefix_ipv4 *)&rp->p;
 
@@ -2266,9 +2256,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
                                if (ret == RMAP_DENYMATCH) {
                                        if (IS_RIP_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "RIP %s/%d is filtered by route-map out",
-                                                       inet_ntoa(p->prefix),
-                                                       p->prefixlen);
+                                                       "RIP %pFX is filtered by route-map out",
+                                                       p);
                                        continue;
                                }
                        }
@@ -2283,9 +2272,8 @@ void rip_output_process(struct connected *ifc, struct sockaddr_in *to,
                                if (ret == RMAP_DENYMATCH) {
                                        if (IS_RIP_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "%s/%d is filtered by route-map",
-                                                       inet_ntoa(p->prefix),
-                                                       p->prefixlen);
+                                                       "%pFX is filtered by route-map",
+                                                       p);
                                        continue;
                                }
                        }
@@ -2460,10 +2448,10 @@ static void rip_update_interface(struct connected *ifc, uint8_t version,
                        to.sin_port = htons(RIP_PORT_DEFAULT);
 
                        if (IS_RIP_DEBUG_EVENT)
-                               zlog_debug("%s announce to %s on %s",
+                               zlog_debug("%s announce to %pI4 on %s",
                                           CONNECTED_PEER(ifc) ? "unicast"
                                                               : "broadcast",
-                                          inet_ntoa(to.sin_addr), ifp->name);
+                                          &to.sin_addr, ifp->name);
 
                        rip_output_process(ifc, &to, route_type, version);
                }
@@ -2538,8 +2526,8 @@ static void rip_update_process(struct rip *rip, int route_type)
                                                      rip->vrf->vrf_id);
                        if (!connected) {
                                zlog_warn(
-                                       "Neighbor %s doesn't have connected interface!",
-                                       inet_ntoa(p->u.prefix4));
+                                       "Neighbor %pI4 doesn't have connected interface!",
+                                       &p->u.prefix4);
                                continue;
                        }
 
@@ -2674,9 +2662,8 @@ void rip_redistribute_withdraw(struct rip *rip, int type)
                                                (struct prefix_ipv4 *)&rp->p;
 
                                        zlog_debug(
-                                               "Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
-                                               inet_ntoa(p->prefix),
-                                               p->prefixlen,
+                                               "Poisone %pFX on the interface %s with an infinity metric [withdraw]",
+                                               p,
                                                ifindex2ifname(
                                                        rinfo->nh.ifindex,
                                                        rip->vrf->vrf_id));
@@ -2966,8 +2953,7 @@ static void rip_distance_show(struct vty *vty, struct rip *rip)
                                        "    Address           Distance  List\n");
                                header = 0;
                        }
-                       snprintf(buf, sizeof(buf), "%s/%d",
-                                inet_ntoa(rn->p.u.prefix4), rn->p.prefixlen);
+                       snprintfrr(buf, sizeof(buf), "%pFX", &rn->p);
                        vty_out(vty, "    %-20s  %4d  %s\n", buf,
                                rdistance->distance,
                                rdistance->access_list ? rdistance->access_list
@@ -3094,12 +3080,11 @@ DEFUN (show_ip_rip,
                                int len;
 
                                len = vty_out(
-                                       vty, "%c(%s) %s/%d",
+                                       vty, "%c(%s) %pFX",
                                        /* np->lock, For debugging. */
                                        zebra_route_char(rinfo->type),
                                        rip_route_type_print(rinfo->sub_type),
-                                       inet_ntoa(np->p.u.prefix4),
-                                       np->p.prefixlen);
+                                       &np->p);
 
                                len = 24 - len;
 
@@ -3109,8 +3094,8 @@ DEFUN (show_ip_rip,
                                switch (rinfo->nh.type) {
                                case NEXTHOP_TYPE_IPV4:
                                case NEXTHOP_TYPE_IPV4_IFINDEX:
-                                       vty_out(vty, "%-20s %2d ",
-                                               inet_ntoa(rinfo->nh.gate.ipv4),
+                                       vty_out(vty, "%-20pI4 %2d ",
+                                               &rinfo->nh.gate.ipv4,
                                                rinfo->metric);
                                        break;
                                case NEXTHOP_TYPE_IFINDEX:
@@ -3134,8 +3119,8 @@ DEFUN (show_ip_rip,
                                /* Route which exist in kernel routing table. */
                                if ((rinfo->type == ZEBRA_ROUTE_RIP)
                                    && (rinfo->sub_type == RIP_ROUTE_RTE)) {
-                                       vty_out(vty, "%-15s ",
-                                               inet_ntoa(rinfo->from));
+                                       vty_out(vty, "%-15pI4 ",
+                                               &rinfo->from);
                                        vty_out(vty, "%3" ROUTE_TAG_PRI " ",
                                                (route_tag_t)rinfo->tag);
                                        rip_vty_out_uptime(vty, rinfo);
@@ -3422,6 +3407,8 @@ static void rip_distribute_update_all_wrapper(struct access_list *notused)
 /* Delete all added rip route. */
 void rip_clean(struct rip *rip)
 {
+       rip_interfaces_clean(rip);
+
        if (rip->enabled)
                rip_instance_disable(rip);
 
@@ -3443,7 +3430,6 @@ void rip_clean(struct rip *rip)
        route_table_finish(rip->enable_network);
        vector_free(rip->passive_nondefault);
        list_delete(&rip->offset_list_master);
-       rip_interfaces_clean(rip);
        route_table_finish(rip->distance_table);
 
        RB_REMOVE(rip_instance_head, &rip_instances, rip);
@@ -3610,7 +3596,7 @@ static void rip_instance_disable(struct rip *rip)
        RIP_TIMER_OFF(rip->t_triggered_interval);
 
        /* Cancel read thread. */
-       THREAD_READ_OFF(rip->t_read);
+       thread_cancel(&rip->t_read);
 
        /* Close RIP socket. */
        close(rip->sock);
index 417bd5b3b16732ed91a2509e940eb1ea8113c13c..99718f7b9e464074bb176f5eecc61ade8c79e073 100644 (file)
@@ -405,7 +405,7 @@ enum rip_event {
 #define RIP_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
 
 /* Macro for timer turn off. */
-#define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
+#define RIP_TIMER_OFF(X) thread_cancel(&(X))
 
 #define RIP_OFFSET_LIST_IN  0
 #define RIP_OFFSET_LIST_OUT 1
index f66de175fa0a837180e75f2dd3db98ab4affb4aa..365082f8067d69374085fae117aafce8f9f77303 100644 (file)
@@ -496,7 +496,7 @@ DEFPY_YANG (clear_ipv6_rip,
                listnode_add(input, yang_vrf);
        }
 
-       ret = nb_cli_rpc("/frr-ripngd:clear-ripng-route", input, NULL);
+       ret = nb_cli_rpc(vty, "/frr-ripngd:clear-ripng-route", input, NULL);
 
        list_delete(&input);
 
index 54edb17eccc2246682939a396d20e4fccb73c27b..539c01b3ecda67121de09e6307440e780e4ab2dc 100644 (file)
@@ -218,7 +218,7 @@ void ripng_debug_init(void)
 
        install_node(&debug_node);
 
-       install_element(VIEW_NODE, &show_debugging_ripng_cmd);
+       install_element(ENABLE_NODE, &show_debugging_ripng_cmd);
 
        install_element(ENABLE_NODE, &debug_ripng_events_cmd);
        install_element(ENABLE_NODE, &debug_ripng_packet_cmd);
index 03c93668b9df67aa99357fc0b8f262f43057fc9c..115d7a6b993f94ff0d86dd416bb1e79afa158392 100644 (file)
@@ -321,10 +321,7 @@ void ripng_interface_clean(struct ripng *ripng)
                ri->enable_interface = 0;
                ri->running = 0;
 
-               if (ri->t_wakeup) {
-                       thread_cancel(ri->t_wakeup);
-                       ri->t_wakeup = NULL;
-               }
+               thread_cancel(&ri->t_wakeup);
        }
 }
 
@@ -375,8 +372,7 @@ int ripng_interface_address_add(ZAPI_CALLBACK_ARGS)
                struct ripng_interface *ri = c->ifp->info;
 
                if (IS_RIPNG_DEBUG_ZEBRA)
-                       zlog_debug("RIPng connected address %s/%d add",
-                                  inet6_ntoa(p->u.prefix6), p->prefixlen);
+                       zlog_debug("RIPng connected address %pFX add", p);
 
                /* Check is this prefix needs to be redistributed. */
                ripng_apply_address_add(c);
@@ -428,7 +424,6 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS)
 {
        struct connected *ifc;
        struct prefix *p;
-       char buf[INET6_ADDRSTRLEN];
 
        ifc = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE,
                                           zclient->ibuf, vrf_id);
@@ -439,10 +434,8 @@ int ripng_interface_address_delete(ZAPI_CALLBACK_ARGS)
                if (p->family == AF_INET6) {
                        if (IS_RIPNG_DEBUG_ZEBRA)
                                zlog_debug(
-                                       "RIPng connected address %s/%d delete",
-                                       inet_ntop(AF_INET6, &p->u.prefix6, buf,
-                                                 INET6_ADDRSTRLEN),
-                                       p->prefixlen);
+                                       "RIPng connected address %pFX delete",
+                                       p);
 
                        /* Check wether this prefix needs to be removed. */
                        ripng_apply_address_del(ifc);
index 85f378bc9ebbcb1f1af2ad37f39d1951d6062fa5..25bf65f7aa0f11017b86c0b2f79daa27309649ad 100644 (file)
@@ -163,7 +163,7 @@ int ripngd_instance_default_information_originate_modify(
        ripng = nb_running_get_entry(args->dnode, NULL, true);
        default_information = yang_dnode_get_bool(args->dnode, NULL);
 
-       str2prefix_ipv6("::/0", &p);
+       (void)str2prefix_ipv6("::/0", &p);
        if (default_information) {
                ripng_redistribute_add(ripng, ZEBRA_ROUTE_RIPNG,
                                       RIPNG_ROUTE_DEFAULT, &p, 0, NULL, 0);
index e6ff58dd0c39f7a1c6898e177860e64037409972..0ac489c67ee2232ab88b00ceac02e5dfc83c7596 100644 (file)
@@ -95,8 +95,7 @@ static struct ripng_peer *ripng_peer_get(struct ripng *ripng,
        peer = ripng_peer_lookup(ripng, addr);
 
        if (peer) {
-               if (peer->t_timeout)
-                       thread_cancel(peer->t_timeout);
+               thread_cancel(&peer->t_timeout);
        } else {
                peer = ripng_peer_new();
                peer->ripng = ripng;
@@ -105,7 +104,6 @@ static struct ripng_peer *ripng_peer_get(struct ripng *ripng,
        }
 
        /* Update timeout thread. */
-       peer->t_timeout = NULL;
        thread_add_timer(master, ripng_peer_timeout, peer,
                         RIPNG_PEER_TIMER_DEFAULT, &peer->t_timeout);
 
index 8a7950daf4f8fc325a6c4ccb26aeca27c03160f4..8d9249e4ae2b15aa7bfa4f03bce98e10684bdbd1 100644 (file)
@@ -643,8 +643,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p,
                                      (struct prefix *)p)
                    == FILTER_DENY) {
                        if (IS_RIPNG_DEBUG_PACKET)
-                               zlog_debug("%s/%d filtered by distribute %s",
-                                          inet6_ntoa(p->prefix), p->prefixlen,
+                               zlog_debug("%pFX filtered by distribute %s", p,
                                           inout);
                        return -1;
                }
@@ -654,8 +653,7 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p,
                                      (struct prefix *)p)
                    == PREFIX_DENY) {
                        if (IS_RIPNG_DEBUG_PACKET)
-                               zlog_debug("%s/%d filtered by prefix-list %s",
-                                          inet6_ntoa(p->prefix), p->prefixlen,
+                               zlog_debug("%pFX filtered by prefix-list %s", p,
                                           inout);
                        return -1;
                }
@@ -673,9 +671,8 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p,
                                    == FILTER_DENY) {
                                        if (IS_RIPNG_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "%s/%d filtered by distribute %s",
-                                                       inet6_ntoa(p->prefix),
-                                                       p->prefixlen, inout);
+                                                       "%pFX filtered by distribute %s",
+                                                       p, inout);
                                        return -1;
                                }
                        }
@@ -689,9 +686,8 @@ static int ripng_filter(int ripng_distribute, struct prefix_ipv6 *p,
                                    == PREFIX_DENY) {
                                        if (IS_RIPNG_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "%s/%d filtered by prefix-list %s",
-                                                       inet6_ntoa(p->prefix),
-                                                       p->prefixlen, inout);
+                                                       "%pFX filtered by prefix-list %s",
+                                                       p, inout);
                                        return -1;
                                }
                        }
@@ -997,14 +993,12 @@ void ripng_redistribute_add(struct ripng *ripng, int type, int sub_type,
        if (IS_RIPNG_DEBUG_EVENT) {
                if (!nexthop)
                        zlog_debug(
-                               "Redistribute new prefix %s/%d on the interface %s",
-                               inet6_ntoa(p->prefix), p->prefixlen,
-                               ifindex2ifname(ifindex, ripng->vrf->vrf_id));
+                               "Redistribute new prefix %pFX on the interface %s",
+                               p, ifindex2ifname(ifindex, ripng->vrf->vrf_id));
                else
                        zlog_debug(
-                               "Redistribute new prefix %s/%d with nexthop %s on the interface %s",
-                               inet6_ntoa(p->prefix), p->prefixlen,
-                               inet6_ntoa(*nexthop),
+                               "Redistribute new prefix %pFX with nexthop %s on the interface %s",
+                               p, inet6_ntoa(*nexthop),
                                ifindex2ifname(ifindex, ripng->vrf->vrf_id));
        }
 
@@ -1047,9 +1041,8 @@ void ripng_redistribute_delete(struct ripng *ripng, int type, int sub_type,
 
                                if (IS_RIPNG_DEBUG_EVENT)
                                        zlog_debug(
-                                               "Poisone %s/%d on the interface %s with an infinity metric [delete]",
-                                               inet6_ntoa(p->prefix),
-                                               p->prefixlen,
+                                               "Poisone %pFX on the interface %s with an infinity metric [delete]",
+                                               p,
                                                ifindex2ifname(
                                                        ifindex,
                                                        ripng->vrf->vrf_id));
@@ -1091,9 +1084,8 @@ void ripng_redistribute_withdraw(struct ripng *ripng, int type)
                                                        agg_node_get_prefix(rp);
 
                                        zlog_debug(
-                                               "Poisone %s/%d on the interface %s [withdraw]",
-                                               inet6_ntoa(p->prefix),
-                                               p->prefixlen,
+                                               "Poisone %pFX on the interface %s [withdraw]",
+                                               p,
                                                ifindex2ifname(
                                                        rinfo->ifindex,
                                                        ripng->vrf->vrf_id));
@@ -1471,10 +1463,7 @@ static int ripng_update(struct thread *t)
 
        /* Triggered updates may be suppressed if a regular update is due by
           the time the triggered update would be sent. */
-       if (ripng->t_triggered_interval) {
-               thread_cancel(ripng->t_triggered_interval);
-               ripng->t_triggered_interval = NULL;
-       }
+       thread_cancel(&ripng->t_triggered_interval);
        ripng->trigger = 0;
 
        /* Reset flush event. */
@@ -1508,10 +1497,7 @@ int ripng_triggered_update(struct thread *t)
        ripng->t_triggered_update = NULL;
 
        /* Cancel interval timer. */
-       if (ripng->t_triggered_interval) {
-               thread_cancel(ripng->t_triggered_interval);
-               ripng->t_triggered_interval = NULL;
-       }
+       thread_cancel(&ripng->t_triggered_interval);
        ripng->trigger = 0;
 
        /* Logging triggered update. */
@@ -1680,9 +1666,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
                                if (ret == RMAP_DENYMATCH) {
                                        if (IS_RIPNG_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "RIPng %s/%d is filtered by route-map out",
-                                                       inet6_ntoa(p->prefix),
-                                                       p->prefixlen);
+                                                       "RIPng %pFX is filtered by route-map out",
+                                                       p);
                                        continue;
                                }
                        }
@@ -1697,9 +1682,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
                                if (ret == RMAP_DENYMATCH) {
                                        if (IS_RIPNG_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "RIPng %s/%d is filtered by route-map",
-                                                       inet6_ntoa(p->prefix),
-                                                       p->prefixlen);
+                                                       "RIPng %pFX is filtered by route-map",
+                                                       p);
                                        continue;
                                }
                        }
@@ -1795,9 +1779,8 @@ void ripng_output_process(struct interface *ifp, struct sockaddr_in6 *to,
                                if (ret == RMAP_DENYMATCH) {
                                        if (IS_RIPNG_DEBUG_PACKET)
                                                zlog_debug(
-                                                       "RIPng %s/%d is filtered by route-map out",
-                                                       inet6_ntoa(p->prefix),
-                                                       p->prefixlen);
+                                                       "RIPng %pFX is filtered by route-map out",
+                                                       p);
                                        continue;
                                }
 
@@ -1963,10 +1946,8 @@ void ripng_event(struct ripng *ripng, enum ripng_event event, int sock)
                                &ripng->t_read);
                break;
        case RIPNG_UPDATE_EVENT:
-               if (ripng->t_update) {
-                       thread_cancel(ripng->t_update);
-                       ripng->t_update = NULL;
-               }
+               thread_cancel(&ripng->t_update);
+
                /* Update timer jitter. */
                jitter = ripng_update_jitter(ripng->update_time);
 
@@ -2533,6 +2514,8 @@ static void ripng_distribute_update_all_wrapper(struct access_list *notused)
 /* delete all the added ripng routes. */
 void ripng_clean(struct ripng *ripng)
 {
+       ripng_interface_clean(ripng);
+
        if (ripng->enabled)
                ripng_instance_disable(ripng);
 
@@ -2554,7 +2537,6 @@ void ripng_clean(struct ripng *ripng)
        agg_table_finish(ripng->enable_network);
        vector_free(ripng->passive_interface);
        list_delete(&ripng->offset_list_master);
-       ripng_interface_clean(ripng);
 
        RB_REMOVE(ripng_instance_head, &ripng_instances, ripng);
        XFREE(MTYPE_RIPNG_VRF_NAME, ripng->vrf_name);
@@ -2729,10 +2711,7 @@ static void ripng_instance_disable(struct ripng *ripng)
        RIPNG_TIMER_OFF(ripng->t_triggered_interval);
 
        /* Cancel the read thread */
-       if (ripng->t_read) {
-               thread_cancel(ripng->t_read);
-               ripng->t_read = NULL;
-       }
+       thread_cancel(&ripng->t_read);
 
        /* Close the RIPng socket */
        if (ripng->sock >= 0) {
index 70508d5cb04ada785caf02cec9c241a42e1ff0eb..a42c32ebb7a91d5a578354efc4771c3ac99b6b2b 100644 (file)
@@ -351,13 +351,7 @@ enum ripng_event {
 /* RIPng timer on/off macro. */
 #define RIPNG_TIMER_ON(T,F,V) thread_add_timer (master, (F), rinfo, (V), &(T))
 
-#define RIPNG_TIMER_OFF(T)                                                     \
-       do {                                                                   \
-               if (T) {                                                       \
-                       thread_cancel(T);                                      \
-                       (T) = NULL;                                            \
-               }                                                              \
-       } while (0)
+#define RIPNG_TIMER_OFF(T)  thread_cancel(&(T))
 
 #define RIPNG_OFFSET_LIST_IN  0
 #define RIPNG_OFFSET_LIST_OUT 1
index 7484dd3b068837f29ebeaf83b9007a7be709f6b0..bed0ebfa27cd1fe66b6fb29912b5d13736738365 100644 (file)
@@ -60,14 +60,9 @@ void sharp_nh_tracker_dump(struct vty *vty)
        struct listnode *node;
        struct sharp_nh_tracker *nht;
 
-       for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht)) {
-               char buf[PREFIX_STRLEN];
-
-               vty_out(vty, "%s: Nexthops: %u Updates: %u\n",
-                       prefix2str(&nht->p, buf, sizeof(buf)),
-                       nht->nhop_num,
-                       nht->updates);
-       }
+       for (ALL_LIST_ELEMENTS_RO(sg.nhs, node, nht))
+               vty_out(vty, "%pFX: Nexthops: %u Updates: %u\n", &nht->p,
+                       nht->nhop_num, nht->updates);
 }
 
 PREDECL_RBTREE_UNIQ(sharp_nhg_rb);
@@ -77,7 +72,8 @@ struct sharp_nhg {
 
        uint32_t id;
 
-       char name[256];
+#define NHG_NAME_LEN 256
+       char name[NHG_NAME_LEN];
 
        bool installed;
 };
@@ -95,7 +91,7 @@ struct sharp_nhg_rb_head nhg_head;
 static int sharp_nhg_compare_func(const struct sharp_nhg *a,
                                  const struct sharp_nhg *b)
 {
-       return strncmp(a->name, b->name, strlen(a->name));
+       return strncmp(a->name, b->name, NHG_NAME_LEN);
 }
 
 DECLARE_RBTREE_UNIQ(sharp_nhg_rb, struct sharp_nhg, mylistitem,
index d062f027ab67e26fe4eff237146f8107f29c1910..45c0799fa77700a606611efd3c0dafeeb2797831 100644 (file)
@@ -146,16 +146,12 @@ DEFPY (install_routes_data_dump,
        "Data about what is going on\n"
        "Route Install/Removal Information\n")
 {
-       char buf[PREFIX_STRLEN];
        struct timeval r;
 
        timersub(&sg.r.t_end, &sg.r.t_start, &r);
-       vty_out(vty, "Prefix: %s Total: %u %u %u Time: %jd.%ld\n",
-               prefix2str(&sg.r.orig_prefix, buf, sizeof(buf)),
-               sg.r.total_routes,
-               sg.r.installed_routes,
-               sg.r.removed_routes,
-               (intmax_t)r.tv_sec, (long)r.tv_usec);
+       vty_out(vty, "Prefix: %pFX Total: %u %u %u Time: %jd.%ld\n",
+               &sg.r.orig_prefix, sg.r.total_routes, sg.r.installed_routes,
+               sg.r.removed_routes, (intmax_t)r.tv_sec, (long)r.tv_usec);
 
        return CMD_SUCCESS;
 }
@@ -716,7 +712,7 @@ void sharp_vty_init(void)
        install_element(ENABLE_NODE, &send_opaque_reg_cmd);
        install_element(ENABLE_NODE, &neigh_discover_cmd);
 
-       install_element(VIEW_NODE, &show_debugging_sharpd_cmd);
+       install_element(ENABLE_NODE, &show_debugging_sharpd_cmd);
 
        return;
 }
index d6aab296c950f52346a25dbbbbd75b87b22f1ac7..d105b2123f31ad9216acfe6a5626b6f37ce068a2 100644 (file)
@@ -283,6 +283,7 @@ static_add_nexthop(struct route_node *rn, struct static_path *pn, safi_t safi,
 
                break;
        case STATIC_BLACKHOLE:
+               nh->bh_type = STATIC_BLACKHOLE_NULL;
                break;
        case STATIC_IFNAME:
                ifp = if_lookup_by_name(ifname, nh_svrf->vrf->vrf_id);
index f5bc9df649e98d55de12dedaad64e57791049b32..c3c453f42d524cc516290658226196eb28153ffc 100644 (file)
@@ -365,8 +365,7 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi,
 
                                switch (nh->type) {
                                case STATIC_IPV4_GATEWAY:
-                                       vty_out(vty, " %s",
-                                               inet_ntoa(nh->addr.ipv4));
+                                       vty_out(vty, " %pI4", &nh->addr.ipv4);
                                        break;
                                case STATIC_IPV6_GATEWAY:
                                        vty_out(vty, " %s",
@@ -500,12 +499,6 @@ DEFPY_YANG(ip_route_blackhole,
       "Table to configure\n"
       "The table number to configure\n")
 {
-       if (table_str && vrf && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
        return static_route(vty, AFI_IP, SAFI_UNICAST, no, prefix,
                            mask_str, NULL, NULL, NULL, flag, tag_str,
                            distance_str, vrf, label, table_str);
@@ -819,12 +812,6 @@ DEFPY_YANG(ipv6_route_blackhole,
       "Table to configure\n"
       "The table number to configure\n")
 {
-       if (table_str && vrf && !vrf_is_backend_netns()) {
-               vty_out(vty,
-                       "%% table param only available when running on netns-based vrfs\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
        return static_route(vty, AFI_IP6, SAFI_UNICAST, no, prefix_str,
                            NULL, from_str, NULL, NULL, flag, tag_str,
                            distance_str, vrf, label, table_str);
@@ -1167,7 +1154,7 @@ void static_vty_init(void)
        install_element(CONFIG_NODE, &ipv6_route_cmd);
        install_element(VRF_NODE, &ipv6_route_vrf_cmd);
 
-       install_element(VIEW_NODE, &show_debugging_static_cmd);
-       install_element(VIEW_NODE, &debug_staticd_cmd);
+       install_element(ENABLE_NODE, &show_debugging_static_cmd);
+       install_element(ENABLE_NODE, &debug_staticd_cmd);
        install_element(CONFIG_NODE, &debug_staticd_cmd);
 }
index efde3babd1957429a4c201fd6c24be69cf93a3f3..a9b570de8360c70ab1b6e4d5cb74cb8045cf528b 100644 (file)
@@ -109,24 +109,21 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS)
        struct prefix p;
        enum zapi_route_notify_owner note;
        uint32_t table_id;
-       char buf[PREFIX_STRLEN];
 
        if (!zapi_route_notify_decode(zclient->ibuf, &p, &table_id, &note))
                return -1;
 
-       prefix2str(&p, buf, sizeof(buf));
-
        switch (note) {
        case ZAPI_ROUTE_FAIL_INSTALL:
                static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
-               zlog_warn("%s: Route %s failed to install for table: %u",
-                         __func__, buf, table_id);
+               zlog_warn("%s: Route %pFX failed to install for table: %u",
+                         __func__, &p, table_id);
                break;
        case ZAPI_ROUTE_BETTER_ADMIN_WON:
                static_nht_mark_state(&p, vrf_id, STATIC_NOT_INSTALLED);
                zlog_warn(
-                       "%s: Route %s over-ridden by better route for table: %u",
-                       __func__, buf, table_id);
+                       "%s: Route %pFX over-ridden by better route for table: %u",
+                       __func__, &p, table_id);
                break;
        case ZAPI_ROUTE_INSTALLED:
                static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED);
@@ -136,8 +133,8 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS)
                break;
        case ZAPI_ROUTE_REMOVE_FAIL:
                static_nht_mark_state(&p, vrf_id, STATIC_INSTALLED);
-               zlog_warn("%s: Route %s failure to remove for table: %u",
-                         __func__, buf, table_id);
+               zlog_warn("%s: Route %pFX failure to remove for table: %u",
+                         __func__, &p, table_id);
                break;
        }
 
index 5fa1f116291bf05b4a78d31b4fa91b69cdd18303..88579ad3e45daa93aa5205f949e5b358f87443ad 100644 (file)
@@ -1,14 +1,16 @@
 import frrtest
 import re
 
-re_okfail = re.compile(r'^(?:\x1b\[3[12]m)?(?P<ret>OK|failed)'.encode('utf8'),
-                       re.MULTILINE)
+re_okfail = re.compile(
+    r"^(?:\x1b\[3[12]m)?(?P<ret>OK|failed)".encode("utf8"), re.MULTILINE
+)
+
 
 class TestAspath(frrtest.TestMultiOut):
-    program = './test_aspath'
+    program = "./test_aspath"
 
     def _parsertest(self, line):
-        if not hasattr(self, 'parserno'):
+        if not hasattr(self, "parserno"):
             self.parserno = -1
         self.parserno += 1
 
@@ -17,13 +19,14 @@ class TestAspath(frrtest.TestMultiOut):
         self._okfail("empty prepend %s:" % line, okfail=re_okfail)
 
     def _attrtest(self, line):
-        if not hasattr(self, 'attrno'):
+        if not hasattr(self, "attrno"):
             self.attrno = -1
         self.attrno += 1
 
         self._onesimple("aspath_attr test %d" % self.attrno)
         self._okfail(line, okfail=re_okfail)
 
+
 TestAspath.parsertest("seq1")
 TestAspath.parsertest("seq2")
 TestAspath.parsertest("seq3")
index 4eb132df55903fa548fdc79601486785227b05e8..e899e5b359e166eeedaa398f5ae36db0af1fd343 100644 (file)
@@ -109,10 +109,7 @@ static void check_lookup_result(struct bgp_dest *match, va_list arglist)
 
                if (bgp_dest_has_bgp_path_info_data(dest)
                    && !prefix_in_array(dest_p, prefixes, prefix_count)) {
-                       char buf[PREFIX2STR_BUFFER];
-
-                       prefix2str(dest_p, buf, PREFIX2STR_BUFFER);
-                       printf("prefix %s was not expected!\n", buf);
+                       printf("prefix %pFX was not expected!\n", dest_p);
                        assert(0);
                }
        }
index 53bd37233a0718238ea6a28d527b4d7ca7dcda5e..8f0544249c98f941305bc6bde7fd2cf5cccfd0cd 100644 (file)
@@ -1,7 +1,9 @@
 import frrtest
 
+
 class TestTable(frrtest.TestMultiOut):
-    program = './test_bgp_table'
+    program = "./test_bgp_table"
+
 
 for i in range(7):
-    TestTable.onesimple('Checks successfull')
+    TestTable.onesimple("Checks successfull")
index 872fcb6d122384fa7ad69b6d030ad933c78bec6f..e2751955371a6fb2f3c3023a6612e6dfb7ac6a20 100644 (file)
@@ -1,7 +1,9 @@
 import frrtest
 
+
 class TestCapability(frrtest.TestMultiOut):
-    program = './test_capability'
+    program = "./test_capability"
+
 
 TestCapability.okfail("MP4: MP IP/Uni")
 TestCapability.okfail("MPv6: MP IPv6/Uni")
@@ -43,5 +45,9 @@ TestCapability.okfail("AS4real2: AS4 capability, in series of capabilities")
 TestCapability.okfail("DynCap: Dynamic Capability Message, IP/Multicast")
 TestCapability.okfail("DynCapLong: Dynamic Capability Message, IP/Multicast, truncated")
 TestCapability.okfail("DynCapPadded: Dynamic Capability Message, IP/Multicast, padded")
-TestCapability.okfail("DynCapMPCpadded: Dynamic Capability Message, IP/Multicast, cap data padded")
-TestCapability.okfail("DynCapMPCoverflow: Dynamic Capability Message, IP/Multicast, cap data != length")
+TestCapability.okfail(
+    "DynCapMPCpadded: Dynamic Capability Message, IP/Multicast, cap data padded"
+)
+TestCapability.okfail(
+    "DynCapMPCoverflow: Dynamic Capability Message, IP/Multicast, cap data != length"
+)
index 3a17ec9e31894b0d6a872bbe26602224bc589e97..1499294f7ba55a218a7dee35a988c7ebd4d892ba 100644 (file)
@@ -1,9 +1,11 @@
 import frrtest
 
+
 class TestEcommunity(frrtest.TestMultiOut):
-    program = './test_ecommunity'
+    program = "./test_ecommunity"
+
 
-TestEcommunity.okfail('ipaddr')
-TestEcommunity.okfail('ipaddr-so')
-TestEcommunity.okfail('asn')
-TestEcommunity.okfail('asn4')
+TestEcommunity.okfail("ipaddr")
+TestEcommunity.okfail("ipaddr-so")
+TestEcommunity.okfail("asn")
+TestEcommunity.okfail("asn4")
index 46d0c424023a0d264075672514deeadac8a3ddd4..d9612bb8d34b2cd8685d66e31a881e27004c42b7 100644 (file)
@@ -1,7 +1,9 @@
 import frrtest
 
+
 class TestMpAttr(frrtest.TestMultiOut):
-    program = './test_mp_attr'
+    program = "./test_mp_attr"
+
 
 TestMpAttr.okfail("IPv6: IPV6 MP Reach, global nexthop, 1 NLRI")
 TestMpAttr.okfail("IPv6-2: IPV6 MP Reach, global nexthop, 2 NLRIs")
@@ -16,13 +18,27 @@ TestMpAttr.okfail("IPv4: IPv4 MP Reach, 2 NLRIs + default")
 TestMpAttr.okfail("IPv4-nhlen: IPv4 MP Reach, nexthop lenth overflow")
 TestMpAttr.okfail("IPv4-nlrilen: IPv4 MP Reach, nlri lenth overflow")
 TestMpAttr.okfail("IPv4-VPNv4: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs")
-TestMpAttr.okfail("IPv4-VPNv4-bogus-plen: IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len")
-TestMpAttr.okfail("IPv4-VPNv4-plen1-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short")
-TestMpAttr.okfail("IPv4-VPNv4-plen1-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long")
-TestMpAttr.okfail("IPv4-VPNv4-plenn-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long")
-TestMpAttr.okfail("IPv4-VPNv4-plenn-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short")
-TestMpAttr.okfail("IPv4-VPNv4-bogus-rd-type: IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)")
-TestMpAttr.okfail("IPv4-VPNv4-0-nlri: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus")
+TestMpAttr.okfail(
+    "IPv4-VPNv4-bogus-plen: IPv4/MPLS-labeled VPN MP Reach, RD, Nexthop, NLRI / bogus p'len"
+)
+TestMpAttr.okfail(
+    "IPv4-VPNv4-plen1-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen short"
+)
+TestMpAttr.okfail(
+    "IPv4-VPNv4-plen1-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, 1st plen long"
+)
+TestMpAttr.okfail(
+    "IPv4-VPNv4-plenn-long: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRIs, last plen long"
+)
+TestMpAttr.okfail(
+    "IPv4-VPNv4-plenn-short: IPv4/VPNv4 MP Reach, RD, Nexthop, 2 NLRIs, last plen short"
+)
+TestMpAttr.okfail(
+    "IPv4-VPNv4-bogus-rd-type: IPv4/VPNv4 MP Reach, RD, NH, 2 NLRI, unknown RD in 1st (log, but parse)"
+)
+TestMpAttr.okfail(
+    "IPv4-VPNv4-0-nlri: IPv4/VPNv4 MP Reach, RD, Nexthop, 3 NLRI, 3rd 0 bogus"
+)
 TestMpAttr.okfail("IPv6-bug: IPv6, global nexthop, 1 default NLRI")
 TestMpAttr.okfail("IPv6-unreach: IPV6 MP Unreach, 1 NLRI")
 TestMpAttr.okfail("IPv6-unreach2: IPV6 MP Unreach, 2 NLRIs")
index ce34ff84364de0d58e29e6e280bfb5f4c0424e71..582fd25c20240505129c93d2f1524e629bafebba 100644 (file)
@@ -1,9 +1,10 @@
 import frrtest
 
+
 class TestMpath(frrtest.TestMultiOut):
-    program = './test_mpath'
+    program = "./test_mpath"
+
 
 TestMpath.okfail("bgp maximum-paths config")
 TestMpath.okfail("bgp_mp_list")
 TestMpath.okfail("bgp_path_info_mpath_update")
-
index 0979622eb3650236018b48dd434b60dd561557a1..0a15886c108858faf35d8bf1328c363e2bc59a8b 100644 (file)
@@ -30,6 +30,8 @@
 #include "bgpd/bgp_vty.h"
 #include "bgpd/bgp_zebra.h"
 #include "bgpd/bgp_network.h"
+#include "lib/routing_nb.h"
+#include "bgpd/bgp_nb.h"
 
 #ifdef ENABLE_BGP_VNC
 #include "bgpd/rfapi/rfapi_backend.h"
@@ -932,7 +934,7 @@ static struct test *test_new(const char *desc, bool use_ibgp,
 
        test->vty = vty_new();
        test->vty->type = VTY_TERM;
-       test->vty->node = CONFIG_NODE;
+       vty_config_enter(test->vty, true, false);
 
        test_initialize(test);
 
@@ -1378,6 +1380,15 @@ static void test_peer_attr(struct test *test, struct test_peer_attr *pa)
        test_process(test, pa, p, g->conf, true, false);
 }
 
+static const struct frr_yang_module_info *const bgpd_yang_modules[] = {
+       &frr_bgp_info,
+       &frr_filter_info,
+       &frr_interface_info,
+       &frr_route_map_info,
+       &frr_routing_info,
+       &frr_vrf_info,
+};
+
 static void bgp_startup(void)
 {
        cmd_init(1);
@@ -1387,7 +1398,7 @@ static void bgp_startup(void)
 
        master = thread_master_create(NULL);
        yang_init(true);
-       nb_init(master, NULL, 0, false);
+       nb_init(master, bgpd_yang_modules, array_size(bgpd_yang_modules), false);
        bgp_master_init(master, BGP_SOCKET_SNDBUF_SIZE);
        bgp_option_set(BGP_OPT_NO_LISTEN);
        vrf_init(NULL, NULL, NULL, NULL, NULL);
index 44068605eee8a0a178cf799084340f699a965eb2..16b441b25de6623f5fbf4f22c6b3aae11d140804 100644 (file)
 import frrtest
 
+
 class TestFlag(frrtest.TestMultiOut):
-    program = './test_peer_attr'
+    program = "./test_peer_attr"
+
 
 # List of tests can be generated by executing:
 # $> ./test_peer_attr 2>&1 | sed -n 's/\\/\\\\/g; s/\S\+ \[test\] \(.\+\)/TestFlag.okfail(\x27\1\x27)/pg'
 #
-TestFlag.okfail('peer\\advertisement-interval')
-TestFlag.okfail('peer\\capability dynamic')
-TestFlag.okfail('peer\\capability extended-nexthop')
-#TestFlag.okfail('peer\\capability extended-nexthop')
-TestFlag.okfail('peer\\description')
-TestFlag.okfail('peer\\disable-connected-check')
-TestFlag.okfail('peer\\dont-capability-negotiate')
-TestFlag.okfail('peer\\enforce-first-as')
-TestFlag.okfail('peer\\local-as')
-TestFlag.okfail('peer\\local-as 1 no-prepend')
-TestFlag.okfail('peer\\local-as 1 no-prepend replace-as')
-TestFlag.okfail('peer\\override-capability')
-TestFlag.okfail('peer\\passive')
-TestFlag.okfail('peer\\password')
-TestFlag.okfail('peer\\shutdown')
-TestFlag.okfail('peer\\strict-capability-match')
-TestFlag.okfail('peer\\timers')
-TestFlag.okfail('peer\\timers connect')
-TestFlag.okfail('peer\\update-source')
-TestFlag.okfail('peer\\update-source')
-TestFlag.okfail('peer\\ipv4-unicast\\addpath')
-TestFlag.okfail('peer\\ipv4-multicast\\addpath')
-TestFlag.okfail('peer\\ipv6-unicast\\addpath')
-TestFlag.okfail('peer\\ipv6-multicast\\addpath')
-TestFlag.okfail('peer\\ipv4-unicast\\allowas-in')
-TestFlag.okfail('peer\\ipv4-multicast\\allowas-in')
-TestFlag.okfail('peer\\ipv6-unicast\\allowas-in')
-TestFlag.okfail('peer\\ipv6-multicast\\allowas-in')
-TestFlag.okfail('peer\\ipv4-unicast\\allowas-in origin')
-TestFlag.okfail('peer\\ipv4-multicast\\allowas-in origin')
-TestFlag.okfail('peer\\ipv6-unicast\\allowas-in origin')
-TestFlag.okfail('peer\\ipv6-multicast\\allowas-in origin')
-TestFlag.okfail('peer\\ipv4-unicast\\as-override')
-TestFlag.okfail('peer\\ipv4-multicast\\as-override')
-TestFlag.okfail('peer\\ipv6-unicast\\as-override')
-TestFlag.okfail('peer\\ipv6-multicast\\as-override')
-TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path')
-TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path')
-TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path')
-TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path')
-TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged next-hop')
-TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged next-hop')
-TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged next-hop')
-TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged next-hop')
-TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged med')
-TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged med')
-TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged med')
-TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged med')
-TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path next-hop')
-TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path next-hop')
-TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path next-hop')
-TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path next-hop')
-TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path med')
-TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path med')
-TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path med')
-TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path med')
-TestFlag.okfail('peer\\ipv4-unicast\\attribute-unchanged as-path next-hop med')
-TestFlag.okfail('peer\\ipv4-multicast\\attribute-unchanged as-path next-hop med')
-TestFlag.okfail('peer\\ipv6-unicast\\attribute-unchanged as-path next-hop med')
-TestFlag.okfail('peer\\ipv6-multicast\\attribute-unchanged as-path next-hop med')
-TestFlag.okfail('peer\\ipv4-unicast\\capability orf prefix-list send')
-TestFlag.okfail('peer\\ipv4-multicast\\capability orf prefix-list send')
-TestFlag.okfail('peer\\ipv6-unicast\\capability orf prefix-list send')
-TestFlag.okfail('peer\\ipv6-multicast\\capability orf prefix-list send')
-TestFlag.okfail('peer\\ipv4-unicast\\capability orf prefix-list receive')
-TestFlag.okfail('peer\\ipv4-multicast\\capability orf prefix-list receive')
-TestFlag.okfail('peer\\ipv6-unicast\\capability orf prefix-list receive')
-TestFlag.okfail('peer\\ipv6-multicast\\capability orf prefix-list receive')
-TestFlag.okfail('peer\\ipv4-unicast\\capability orf prefix-list both')
-TestFlag.okfail('peer\\ipv4-multicast\\capability orf prefix-list both')
-TestFlag.okfail('peer\\ipv6-unicast\\capability orf prefix-list both')
-TestFlag.okfail('peer\\ipv6-multicast\\capability orf prefix-list both')
-TestFlag.okfail('peer\\ipv4-unicast\\default-originate')
-TestFlag.okfail('peer\\ipv4-multicast\\default-originate')
-TestFlag.okfail('peer\\ipv6-unicast\\default-originate')
-TestFlag.okfail('peer\\ipv6-multicast\\default-originate')
-TestFlag.okfail('peer\\ipv4-unicast\\default-originate route-map')
-TestFlag.okfail('peer\\ipv4-multicast\\default-originate route-map')
-TestFlag.okfail('peer\\ipv6-unicast\\default-originate route-map')
-TestFlag.okfail('peer\\ipv6-multicast\\default-originate route-map')
-TestFlag.okfail('peer\\ipv4-unicast\\distribute-list')
-TestFlag.okfail('peer\\ipv4-multicast\\distribute-list')
-TestFlag.okfail('peer\\ipv6-unicast\\distribute-list')
-TestFlag.okfail('peer\\ipv6-multicast\\distribute-list')
-TestFlag.okfail('peer\\ipv4-unicast\\distribute-list')
-TestFlag.okfail('peer\\ipv4-multicast\\distribute-list')
-TestFlag.okfail('peer\\ipv6-unicast\\distribute-list')
-TestFlag.okfail('peer\\ipv6-multicast\\distribute-list')
-TestFlag.okfail('peer\\ipv4-unicast\\filter-list')
-TestFlag.okfail('peer\\ipv4-multicast\\filter-list')
-TestFlag.okfail('peer\\ipv6-unicast\\filter-list')
-TestFlag.okfail('peer\\ipv6-multicast\\filter-list')
-TestFlag.okfail('peer\\ipv4-unicast\\filter-list')
-TestFlag.okfail('peer\\ipv4-multicast\\filter-list')
-TestFlag.okfail('peer\\ipv6-unicast\\filter-list')
-TestFlag.okfail('peer\\ipv6-multicast\\filter-list')
-TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-unicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv6-multicast\\maximum-prefix')
-TestFlag.okfail('peer\\ipv4-unicast\\next-hop-self')
-TestFlag.okfail('peer\\ipv4-multicast\\next-hop-self')
-TestFlag.okfail('peer\\ipv6-unicast\\next-hop-self')
-TestFlag.okfail('peer\\ipv6-multicast\\next-hop-self')
-TestFlag.okfail('peer\\ipv4-unicast\\next-hop-self force')
-TestFlag.okfail('peer\\ipv4-multicast\\next-hop-self force')
-TestFlag.okfail('peer\\ipv6-unicast\\next-hop-self force')
-TestFlag.okfail('peer\\ipv6-multicast\\next-hop-self force')
-TestFlag.okfail('peer\\ipv4-unicast\\prefix-list')
-TestFlag.okfail('peer\\ipv4-multicast\\prefix-list')
-TestFlag.okfail('peer\\ipv6-unicast\\prefix-list')
-TestFlag.okfail('peer\\ipv6-multicast\\prefix-list')
-TestFlag.okfail('peer\\ipv4-unicast\\prefix-list')
-TestFlag.okfail('peer\\ipv4-multicast\\prefix-list')
-TestFlag.okfail('peer\\ipv6-unicast\\prefix-list')
-TestFlag.okfail('peer\\ipv6-multicast\\prefix-list')
-TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS')
-TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS')
-TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS')
-TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS')
-TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS all')
-TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS all')
-TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS all')
-TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS all')
-TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS replace-AS')
-TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS replace-AS')
-TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS replace-AS')
-TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS replace-AS')
-TestFlag.okfail('peer\\ipv4-unicast\\remove-private-AS all replace-AS')
-TestFlag.okfail('peer\\ipv4-multicast\\remove-private-AS all replace-AS')
-TestFlag.okfail('peer\\ipv6-unicast\\remove-private-AS all replace-AS')
-TestFlag.okfail('peer\\ipv6-multicast\\remove-private-AS all replace-AS')
-TestFlag.okfail('peer\\ipv4-unicast\\route-map')
-TestFlag.okfail('peer\\ipv4-multicast\\route-map')
-TestFlag.okfail('peer\\ipv6-unicast\\route-map')
-TestFlag.okfail('peer\\ipv6-multicast\\route-map')
-TestFlag.okfail('peer\\ipv4-unicast\\route-map')
-TestFlag.okfail('peer\\ipv4-multicast\\route-map')
-TestFlag.okfail('peer\\ipv6-unicast\\route-map')
-TestFlag.okfail('peer\\ipv6-multicast\\route-map')
-TestFlag.okfail('peer\\ipv4-unicast\\route-reflector-client')
-TestFlag.okfail('peer\\ipv4-multicast\\route-reflector-client')
-TestFlag.okfail('peer\\ipv6-unicast\\route-reflector-client')
-TestFlag.okfail('peer\\ipv6-multicast\\route-reflector-client')
-TestFlag.okfail('peer\\ipv4-unicast\\route-server-client')
-TestFlag.okfail('peer\\ipv4-multicast\\route-server-client')
-TestFlag.okfail('peer\\ipv6-unicast\\route-server-client')
-TestFlag.okfail('peer\\ipv6-multicast\\route-server-client')
-TestFlag.okfail('peer\\ipv4-unicast\\send-community')
-TestFlag.okfail('peer\\ipv4-multicast\\send-community')
-TestFlag.okfail('peer\\ipv6-unicast\\send-community')
-TestFlag.okfail('peer\\ipv6-multicast\\send-community')
-TestFlag.okfail('peer\\ipv4-unicast\\send-community extended')
-TestFlag.okfail('peer\\ipv4-multicast\\send-community extended')
-TestFlag.okfail('peer\\ipv6-unicast\\send-community extended')
-TestFlag.okfail('peer\\ipv6-multicast\\send-community extended')
-TestFlag.okfail('peer\\ipv4-unicast\\send-community large')
-TestFlag.okfail('peer\\ipv4-multicast\\send-community large')
-TestFlag.okfail('peer\\ipv6-unicast\\send-community large')
-TestFlag.okfail('peer\\ipv6-multicast\\send-community large')
-TestFlag.okfail('peer\\ipv4-unicast\\soft-reconfiguration inbound')
-TestFlag.okfail('peer\\ipv4-multicast\\soft-reconfiguration inbound')
-TestFlag.okfail('peer\\ipv6-unicast\\soft-reconfiguration inbound')
-TestFlag.okfail('peer\\ipv6-multicast\\soft-reconfiguration inbound')
-TestFlag.okfail('peer\\ipv4-unicast\\unsuppress-map')
-TestFlag.okfail('peer\\ipv4-multicast\\unsuppress-map')
-TestFlag.okfail('peer\\ipv6-unicast\\unsuppress-map')
-TestFlag.okfail('peer\\ipv6-multicast\\unsuppress-map')
-TestFlag.okfail('peer\\ipv4-unicast\\weight')
-TestFlag.okfail('peer\\ipv4-multicast\\weight')
-TestFlag.okfail('peer\\ipv6-unicast\\weight')
-TestFlag.okfail('peer\\ipv6-multicast\\weight')
+TestFlag.okfail("peer\\advertisement-interval")
+TestFlag.okfail("peer\\capability dynamic")
+TestFlag.okfail("peer\\capability extended-nexthop")
+# TestFlag.okfail('peer\\capability extended-nexthop')
+TestFlag.okfail("peer\\description")
+TestFlag.okfail("peer\\disable-connected-check")
+TestFlag.okfail("peer\\dont-capability-negotiate")
+TestFlag.okfail("peer\\enforce-first-as")
+TestFlag.okfail("peer\\local-as")
+TestFlag.okfail("peer\\local-as 1 no-prepend")
+TestFlag.okfail("peer\\local-as 1 no-prepend replace-as")
+TestFlag.okfail("peer\\override-capability")
+TestFlag.okfail("peer\\passive")
+TestFlag.okfail("peer\\password")
+TestFlag.okfail("peer\\shutdown")
+TestFlag.okfail("peer\\strict-capability-match")
+TestFlag.okfail("peer\\timers")
+TestFlag.okfail("peer\\timers connect")
+TestFlag.okfail("peer\\update-source")
+TestFlag.okfail("peer\\update-source")
+TestFlag.okfail("peer\\ipv4-unicast\\addpath")
+TestFlag.okfail("peer\\ipv4-multicast\\addpath")
+TestFlag.okfail("peer\\ipv6-unicast\\addpath")
+TestFlag.okfail("peer\\ipv6-multicast\\addpath")
+TestFlag.okfail("peer\\ipv4-unicast\\allowas-in")
+TestFlag.okfail("peer\\ipv4-multicast\\allowas-in")
+TestFlag.okfail("peer\\ipv6-unicast\\allowas-in")
+TestFlag.okfail("peer\\ipv6-multicast\\allowas-in")
+TestFlag.okfail("peer\\ipv4-unicast\\allowas-in origin")
+TestFlag.okfail("peer\\ipv4-multicast\\allowas-in origin")
+TestFlag.okfail("peer\\ipv6-unicast\\allowas-in origin")
+TestFlag.okfail("peer\\ipv6-multicast\\allowas-in origin")
+TestFlag.okfail("peer\\ipv4-unicast\\as-override")
+TestFlag.okfail("peer\\ipv4-multicast\\as-override")
+TestFlag.okfail("peer\\ipv6-unicast\\as-override")
+TestFlag.okfail("peer\\ipv6-multicast\\as-override")
+TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path")
+TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path")
+TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path")
+TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path")
+TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged next-hop")
+TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged next-hop")
+TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged next-hop")
+TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged next-hop")
+TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged med")
+TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged med")
+TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged med")
+TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged med")
+TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path next-hop")
+TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path next-hop")
+TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path next-hop")
+TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path next-hop")
+TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path med")
+TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path med")
+TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path med")
+TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path med")
+TestFlag.okfail("peer\\ipv4-unicast\\attribute-unchanged as-path next-hop med")
+TestFlag.okfail("peer\\ipv4-multicast\\attribute-unchanged as-path next-hop med")
+TestFlag.okfail("peer\\ipv6-unicast\\attribute-unchanged as-path next-hop med")
+TestFlag.okfail("peer\\ipv6-multicast\\attribute-unchanged as-path next-hop med")
+TestFlag.okfail("peer\\ipv4-unicast\\capability orf prefix-list send")
+TestFlag.okfail("peer\\ipv4-multicast\\capability orf prefix-list send")
+TestFlag.okfail("peer\\ipv6-unicast\\capability orf prefix-list send")
+TestFlag.okfail("peer\\ipv6-multicast\\capability orf prefix-list send")
+TestFlag.okfail("peer\\ipv4-unicast\\capability orf prefix-list receive")
+TestFlag.okfail("peer\\ipv4-multicast\\capability orf prefix-list receive")
+TestFlag.okfail("peer\\ipv6-unicast\\capability orf prefix-list receive")
+TestFlag.okfail("peer\\ipv6-multicast\\capability orf prefix-list receive")
+TestFlag.okfail("peer\\ipv4-unicast\\capability orf prefix-list both")
+TestFlag.okfail("peer\\ipv4-multicast\\capability orf prefix-list both")
+TestFlag.okfail("peer\\ipv6-unicast\\capability orf prefix-list both")
+TestFlag.okfail("peer\\ipv6-multicast\\capability orf prefix-list both")
+TestFlag.okfail("peer\\ipv4-unicast\\default-originate")
+TestFlag.okfail("peer\\ipv4-multicast\\default-originate")
+TestFlag.okfail("peer\\ipv6-unicast\\default-originate")
+TestFlag.okfail("peer\\ipv6-multicast\\default-originate")
+TestFlag.okfail("peer\\ipv4-unicast\\default-originate route-map")
+TestFlag.okfail("peer\\ipv4-multicast\\default-originate route-map")
+TestFlag.okfail("peer\\ipv6-unicast\\default-originate route-map")
+TestFlag.okfail("peer\\ipv6-multicast\\default-originate route-map")
+TestFlag.okfail("peer\\ipv4-unicast\\distribute-list")
+TestFlag.okfail("peer\\ipv4-multicast\\distribute-list")
+TestFlag.okfail("peer\\ipv6-unicast\\distribute-list")
+TestFlag.okfail("peer\\ipv6-multicast\\distribute-list")
+TestFlag.okfail("peer\\ipv4-unicast\\distribute-list")
+TestFlag.okfail("peer\\ipv4-multicast\\distribute-list")
+TestFlag.okfail("peer\\ipv6-unicast\\distribute-list")
+TestFlag.okfail("peer\\ipv6-multicast\\distribute-list")
+TestFlag.okfail("peer\\ipv4-unicast\\filter-list")
+TestFlag.okfail("peer\\ipv4-multicast\\filter-list")
+TestFlag.okfail("peer\\ipv6-unicast\\filter-list")
+TestFlag.okfail("peer\\ipv6-multicast\\filter-list")
+TestFlag.okfail("peer\\ipv4-unicast\\filter-list")
+TestFlag.okfail("peer\\ipv4-multicast\\filter-list")
+TestFlag.okfail("peer\\ipv6-unicast\\filter-list")
+TestFlag.okfail("peer\\ipv6-multicast\\filter-list")
+TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-unicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv6-multicast\\maximum-prefix")
+TestFlag.okfail("peer\\ipv4-unicast\\next-hop-self")
+TestFlag.okfail("peer\\ipv4-multicast\\next-hop-self")
+TestFlag.okfail("peer\\ipv6-unicast\\next-hop-self")
+TestFlag.okfail("peer\\ipv6-multicast\\next-hop-self")
+TestFlag.okfail("peer\\ipv4-unicast\\next-hop-self force")
+TestFlag.okfail("peer\\ipv4-multicast\\next-hop-self force")
+TestFlag.okfail("peer\\ipv6-unicast\\next-hop-self force")
+TestFlag.okfail("peer\\ipv6-multicast\\next-hop-self force")
+TestFlag.okfail("peer\\ipv4-unicast\\prefix-list")
+TestFlag.okfail("peer\\ipv4-multicast\\prefix-list")
+TestFlag.okfail("peer\\ipv6-unicast\\prefix-list")
+TestFlag.okfail("peer\\ipv6-multicast\\prefix-list")
+TestFlag.okfail("peer\\ipv4-unicast\\prefix-list")
+TestFlag.okfail("peer\\ipv4-multicast\\prefix-list")
+TestFlag.okfail("peer\\ipv6-unicast\\prefix-list")
+TestFlag.okfail("peer\\ipv6-multicast\\prefix-list")
+TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS")
+TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS")
+TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS")
+TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS")
+TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS all")
+TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS all")
+TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS all")
+TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS all")
+TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS replace-AS")
+TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS replace-AS")
+TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS replace-AS")
+TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS replace-AS")
+TestFlag.okfail("peer\\ipv4-unicast\\remove-private-AS all replace-AS")
+TestFlag.okfail("peer\\ipv4-multicast\\remove-private-AS all replace-AS")
+TestFlag.okfail("peer\\ipv6-unicast\\remove-private-AS all replace-AS")
+TestFlag.okfail("peer\\ipv6-multicast\\remove-private-AS all replace-AS")
+TestFlag.okfail("peer\\ipv4-unicast\\route-map")
+TestFlag.okfail("peer\\ipv4-multicast\\route-map")
+TestFlag.okfail("peer\\ipv6-unicast\\route-map")
+TestFlag.okfail("peer\\ipv6-multicast\\route-map")
+TestFlag.okfail("peer\\ipv4-unicast\\route-map")
+TestFlag.okfail("peer\\ipv4-multicast\\route-map")
+TestFlag.okfail("peer\\ipv6-unicast\\route-map")
+TestFlag.okfail("peer\\ipv6-multicast\\route-map")
+TestFlag.okfail("peer\\ipv4-unicast\\route-reflector-client")
+TestFlag.okfail("peer\\ipv4-multicast\\route-reflector-client")
+TestFlag.okfail("peer\\ipv6-unicast\\route-reflector-client")
+TestFlag.okfail("peer\\ipv6-multicast\\route-reflector-client")
+TestFlag.okfail("peer\\ipv4-unicast\\route-server-client")
+TestFlag.okfail("peer\\ipv4-multicast\\route-server-client")
+TestFlag.okfail("peer\\ipv6-unicast\\route-server-client")
+TestFlag.okfail("peer\\ipv6-multicast\\route-server-client")
+TestFlag.okfail("peer\\ipv4-unicast\\send-community")
+TestFlag.okfail("peer\\ipv4-multicast\\send-community")
+TestFlag.okfail("peer\\ipv6-unicast\\send-community")
+TestFlag.okfail("peer\\ipv6-multicast\\send-community")
+TestFlag.okfail("peer\\ipv4-unicast\\send-community extended")
+TestFlag.okfail("peer\\ipv4-multicast\\send-community extended")
+TestFlag.okfail("peer\\ipv6-unicast\\send-community extended")
+TestFlag.okfail("peer\\ipv6-multicast\\send-community extended")
+TestFlag.okfail("peer\\ipv4-unicast\\send-community large")
+TestFlag.okfail("peer\\ipv4-multicast\\send-community large")
+TestFlag.okfail("peer\\ipv6-unicast\\send-community large")
+TestFlag.okfail("peer\\ipv6-multicast\\send-community large")
+TestFlag.okfail("peer\\ipv4-unicast\\soft-reconfiguration inbound")
+TestFlag.okfail("peer\\ipv4-multicast\\soft-reconfiguration inbound")
+TestFlag.okfail("peer\\ipv6-unicast\\soft-reconfiguration inbound")
+TestFlag.okfail("peer\\ipv6-multicast\\soft-reconfiguration inbound")
+TestFlag.okfail("peer\\ipv4-unicast\\unsuppress-map")
+TestFlag.okfail("peer\\ipv4-multicast\\unsuppress-map")
+TestFlag.okfail("peer\\ipv6-unicast\\unsuppress-map")
+TestFlag.okfail("peer\\ipv6-multicast\\unsuppress-map")
+TestFlag.okfail("peer\\ipv4-unicast\\weight")
+TestFlag.okfail("peer\\ipv4-multicast\\weight")
+TestFlag.okfail("peer\\ipv6-unicast\\weight")
+TestFlag.okfail("peer\\ipv6-multicast\\weight")
index 91714f0c6757e6aada36182262ead61e43318afa..df737d92ef521dfe620219c6326daed791153142 100644 (file)
@@ -29,24 +29,29 @@ import sys
 PY2 = sys.version_info[0] == 2
 PY3 = sys.version_info[0] == 3
 
+
 def add_metaclass(metaclass):
     """Class decorator for creating a class with a metaclass."""
+
     def wrapper(cls):
         orig_vars = cls.__dict__.copy()
-        slots = orig_vars.get('__slots__')
+        slots = orig_vars.get("__slots__")
         if slots is not None:
             if isinstance(slots, str):
                 slots = [slots]
             for slots_var in slots:
                 orig_vars.pop(slots_var)
-        orig_vars.pop('__dict__', None)
-        orig_vars.pop('__weakref__', None)
+        orig_vars.pop("__dict__", None)
+        orig_vars.pop("__weakref__", None)
         return metaclass(cls.__name__, cls.__bases__, orig_vars)
+
     return wrapper
 
+
 if PY3:
     import builtins
-    exec_ = getattr(builtins,'exec')
+
+    exec_ = getattr(builtins, "exec")
 
     def reraise(tp, value, tb=None):
         try:
@@ -59,7 +64,9 @@ if PY3:
             value = None
             tb = None
 
+
 else:
+
     def exec_(_code_, _globs_=None, _locs_=None):
         """Execute code in a namespace."""
         if _globs_ is None:
@@ -72,9 +79,11 @@ else:
             _locs_ = _globs_
         exec("""exec _code_ in _globs_, _locs_""")
 
-    exec_("""def reraise(tp, value, tb=None):
+    exec_(
+        """def reraise(tp, value, tb=None):
     try:
         raise tp, value, tb
     finally:
         tb = None
-""")
+"""
+    )
index 60bee5c88c710a458cb02b8f81184e9a2beaf0e7..0ac54fd90067730da4bdbaf42f33d6d2b676fa51 100644 (file)
@@ -39,35 +39,41 @@ import frrsix
 srcbase = os.path.abspath(inspect.getsourcefile(frrsix))
 for i in range(0, 3):
     srcbase = os.path.dirname(srcbase)
+
+
 def binpath(srcpath):
     return os.path.relpath(os.path.abspath(srcpath), srcbase)
 
+
 class MultiTestFailure(Exception):
     pass
 
+
 class MetaTestMultiOut(type):
     def __getattr__(cls, name):
-        if name.startswith('_'):
+        if name.startswith("_"):
             raise AttributeError
 
-        internal_name = '_{}'.format(name)
+        internal_name = "_{}".format(name)
         if internal_name not in dir(cls):
             raise AttributeError
 
         def registrar(*args, **kwargs):
-            cls._add_test(getattr(cls,internal_name), *args, **kwargs)
+            cls._add_test(getattr(cls, internal_name), *args, **kwargs)
+
         return registrar
 
+
 @frrsix.add_metaclass(MetaTestMultiOut)
 class _TestMultiOut(object):
     def _run_tests(self):
-        if 'tests_run' in dir(self.__class__) and self.tests_run:
+        if "tests_run" in dir(self.__class__) and self.tests_run:
             return
         self.__class__.tests_run = True
         basedir = os.path.dirname(inspect.getsourcefile(type(self)))
         program = os.path.join(basedir, self.program)
         proc = subprocess.Popen([binpath(program)], stdout=subprocess.PIPE)
-        self.output,_ = proc.communicate('')
+        self.output, _ = proc.communicate("")
         self.exitcode = proc.wait()
 
         self.__class__.testresults = {}
@@ -85,13 +91,14 @@ class _TestMultiOut(object):
 
     @classmethod
     def _add_test(cls, method, *args, **kwargs):
-        if 'tests' not in dir(cls):
-            setattr(cls,'tests',[])
+        if "tests" not in dir(cls):
+            setattr(cls, "tests", [])
             if method is not cls._exit_cleanly:
                 cls._add_test(cls._exit_cleanly)
 
         def matchfunction(self):
             method(self, *args, **kwargs)
+
         cls.tests.append(matchfunction)
 
         def testfunction(self):
@@ -100,17 +107,18 @@ class _TestMultiOut(object):
             if result is not None:
                 frrsix.reraise(*result)
 
-        testname = re.sub(r'[^A-Za-z0-9]', '_', '%r%r' % (args, kwargs))
-        testname = re.sub(r'__*', '_', testname)
-        testname = testname.strip('_')
+        testname = re.sub(r"[^A-Za-z0-9]", "_", "%r%r" % (args, kwargs))
+        testname = re.sub(r"__*", "_", testname)
+        testname = testname.strip("_")
         if not testname:
-            testname = method.__name__.strip('_')
+            testname = method.__name__.strip("_")
         if "test_%s" % testname in dir(cls):
             index = 2
-            while "test_%s_%d" % (testname,index) in dir(cls):
+            while "test_%s_%d" % (testname, index) in dir(cls):
                 index += 1
             testname = "%s_%d" % (testname, index)
-        setattr(cls,"test_%s" % testname, testfunction)
+        setattr(cls, "test_%s" % testname, testfunction)
+
 
 #
 # This class houses the actual TestMultiOut tests types.
@@ -127,15 +135,16 @@ class _TestMultiOut(object):
 # modified according to consumed content.
 #
 
-re_okfail = re.compile(r'(?:[3[12]m|^)?(?P<ret>OK|failed)'.encode('utf8'),
-                       re.MULTILINE)
+re_okfail = re.compile(r"(?:[3[12]m|^)?(?P<ret>OK|failed)".encode("utf8"), re.MULTILINE)
+
+
 class TestMultiOut(_TestMultiOut):
     def _onesimple(self, line):
         if type(line) is str:
-            line = line.encode('utf8')
+            line = line.encode("utf8")
         idx = self.output.find(line)
         if idx != -1:
-            self.output = self.output[idx+len(line):]
+            self.output = self.output[idx + len(line) :]
         else:
             raise MultiTestFailure("%r could not be found" % line)
 
@@ -144,58 +153,67 @@ class TestMultiOut(_TestMultiOut):
 
         m = okfail.search(self.output)
         if m is None:
-            raise MultiTestFailure('OK/fail not found')
-        self.output = self.output[m.end():]
+            raise MultiTestFailure("OK/fail not found")
+        self.output = self.output[m.end() :]
+
+        if m.group("ret") != "OK".encode("utf8"):
+            raise MultiTestFailure("Test output indicates failure")
 
-        if m.group('ret') != 'OK'.encode('utf8'):
-            raise MultiTestFailure('Test output indicates failure')
 
 #
 # This class implements a test comparing the output of a program against
 # an existing reference output
 #
 
+
 class TestRefMismatch(Exception):
     def __init__(self, _test, outtext, reftext):
-        self.outtext = outtext.decode('utf8') if type(outtext) is bytes else outtext
-        self.reftext = reftext.decode('utf8') if type(reftext) is bytes else reftext
+        self.outtext = outtext.decode("utf8") if type(outtext) is bytes else outtext
+        self.reftext = reftext.decode("utf8") if type(reftext) is bytes else reftext
 
     def __str__(self):
-        rv = 'Expected output and actual output differ:\n'
-        rv += '\n'.join(difflib.unified_diff(self.reftext.splitlines(),
-                                             self.outtext.splitlines(),
-                                             'outtext', 'reftext',
-                                             lineterm=''))
+        rv = "Expected output and actual output differ:\n"
+        rv += "\n".join(
+            difflib.unified_diff(
+                self.reftext.splitlines(),
+                self.outtext.splitlines(),
+                "outtext",
+                "reftext",
+                lineterm="",
+            )
+        )
         return rv
 
+
 class TestExitNonzero(Exception):
     pass
 
+
 class TestRefOut(object):
     def test_refout(self):
         basedir = os.path.dirname(inspect.getsourcefile(type(self)))
         program = os.path.join(basedir, self.program)
 
-        if getattr(self, 'built_refin', False):
-            refin = binpath(program) + '.in'
+        if getattr(self, "built_refin", False):
+            refin = binpath(program) + ".in"
         else:
-            refin = program + '.in'
-        if getattr(self, 'built_refout', False):
-            refout = binpath(program) + '.refout'
+            refin = program + ".in"
+        if getattr(self, "built_refout", False):
+            refout = binpath(program) + ".refout"
         else:
-            refout = program + '.refout'
+            refout = program + ".refout"
 
-        intext = ''
+        intext = ""
         if os.path.exists(refin):
-            with open(refin, 'rb') as f:
+            with open(refin, "rb") as f:
                 intext = f.read()
-        with open(refout, 'rb') as f:
+        with open(refout, "rb") as f:
             reftext = f.read()
 
-        proc = subprocess.Popen([binpath(program)],
-                                stdin=subprocess.PIPE,
-                                stdout=subprocess.PIPE)
-        outtext,_ = proc.communicate(intext)
+        proc = subprocess.Popen(
+            [binpath(program)], stdin=subprocess.PIPE, stdout=subprocess.PIPE
+        )
+        outtext, _ = proc.communicate(intext)
         if outtext != reftext:
             raise TestRefMismatch(self, outtext, reftext)
         if proc.wait() != 0:
index 536847a1da97baba36fa3f20e921ef812e98576e..5fa604c7499c2be8ff90f8d6d23d1fffc32a2212 100644 (file)
@@ -106,6 +106,7 @@ static void lsp_add_ip_reach(struct isis_lsp *lsp,
                pcfg.sid = *next_sid_index;
                *next_sid_index = *next_sid_index + 1;
                pcfg.sid_type = SR_SID_VALUE_TYPE_INDEX;
+               pcfg.node_sid = true;
                pcfg.last_hop_behavior = SR_LAST_HOP_BEHAVIOR_PHP;
        }
 
index d96e3c4feee4540e778e4543d6705f76ffcb27c6..8fd20aabd1bd0b0605e9b1e6aebc6063f2f3aba1 100644 (file)
@@ -9,18 +9,24 @@ import socket
 # on musl, ntop compresses a single :0: -> :: which is against RFC
 ##
 def inet_ntop_broken():
-    addr = '1:2:3:4:0:6:7:8'
-    return socket.inet_ntop(socket.AF_INET6,
-                            socket.inet_pton(socket.AF_INET6, addr)) != addr
+    addr = "1:2:3:4:0:6:7:8"
+    return (
+        socket.inet_ntop(socket.AF_INET6, socket.inet_pton(socket.AF_INET6, addr))
+        != addr
+    )
 
 
-if platform.uname()[0] == 'SunOS' or inet_ntop_broken():
+if platform.uname()[0] == "SunOS" or inet_ntop_broken():
+
     class TestFuzzIsisTLV:
-        @pytest.mark.skipif(True, reason='Test unsupported')
+        @pytest.mark.skipif(True, reason="Test unsupported")
         def test_exit_cleanly(self):
             pass
+
+
 else:
+
     class TestFuzzIsisTLV(frrtest.TestMultiOut):
-        program = './test_fuzz_isis_tlv'
+        program = "./test_fuzz_isis_tlv"
 
     TestFuzzIsisTLV.exit_cleanly()
index cd0b5345c77c71cdca211a4cc62cf3d7fb1cdbb6..280ed1c3289c50f5e57915d365df13db8cfdf93e 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestIsisLSPDB(frrtest.TestMultiOut):
-    program = './test_isis_lspdb'
+    program = "./test_isis_lspdb"
+
 
 TestIsisLSPDB.exit_cleanly()
index 73bb531dc0827028c0d60786753ccf5d42fcbfb4..4c89a5be0a267663b79ef741a6fb5f513999e765 100644 (file)
@@ -39,6 +39,7 @@
 enum test_type {
        TEST_SPF = 1,
        TEST_REVERSE_SPF,
+       TEST_TI_LFA,
 };
 
 #define F_DISPLAY_LSPDB 0x01
@@ -65,17 +66,78 @@ static void test_run_spf(struct vty *vty, const struct isis_topology *topology,
 
        /* Print the SPT and the corresponding routing table. */
        isis_print_spftree(vty, spftree);
-       isis_print_routes(vty, spftree);
+       isis_print_routes(vty, spftree, false, false);
 
        /* Cleanup SPF tree. */
        isis_spftree_del(spftree);
 }
 
+static void test_run_ti_lfa(struct vty *vty,
+                           const struct isis_topology *topology,
+                           const struct isis_test_node *root,
+                           struct isis_area *area, struct lspdb_head *lspdb,
+                           int level, int tree,
+                           struct lfa_protected_resource *protected_resource)
+{
+       struct isis_spftree *spftree_self;
+       struct isis_spftree *spftree_reverse;
+       struct isis_spftree *spftree_pc;
+       struct isis_spf_node *spf_node, *node;
+       uint8_t flags;
+
+       /* Run forward SPF in the root node. */
+       flags = F_SPFTREE_NO_ADJACENCIES;
+       spftree_self = isis_spftree_new(area, lspdb, root->sysid, level, tree,
+                                       SPF_TYPE_FORWARD, flags);
+       isis_run_spf(spftree_self);
+
+       /* Run reverse SPF in the root node. */
+       spftree_reverse = isis_spf_reverse_run(spftree_self);
+
+       /* Run forward SPF on all adjacent routers. */
+       isis_spf_run_neighbors(spftree_self);
+
+       /* Compute the TI-LFA repair paths. */
+       spftree_pc = isis_tilfa_compute(area, spftree_self, spftree_reverse,
+                                       protected_resource);
+
+       /* Print the extended P-space and Q-space. */
+       vty_out(vty, "P-space (self):\n");
+       RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.p_space)
+               vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
+       vty_out(vty, "\n");
+       RB_FOREACH (spf_node, isis_spf_nodes, &spftree_self->adj_nodes) {
+               if (RB_EMPTY(isis_spf_nodes, &spf_node->lfa.p_space))
+                       continue;
+               vty_out(vty, "P-space (%s):\n",
+                       print_sys_hostname(spf_node->sysid));
+               RB_FOREACH (node, isis_spf_nodes, &spf_node->lfa.p_space)
+                       vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
+               vty_out(vty, "\n");
+       }
+       vty_out(vty, "Q-space:\n");
+       RB_FOREACH (node, isis_spf_nodes, &spftree_pc->lfa.q_space)
+               vty_out(vty, " %s\n", print_sys_hostname(node->sysid));
+       vty_out(vty, "\n");
+
+       /* Print the post-convergence SPT and the correspoding routing table. */
+       isis_print_spftree(vty, spftree_pc);
+       isis_print_routes(vty, spftree_self, false, true);
+
+       /* Cleanup everything. */
+       isis_spftree_del(spftree_self);
+       isis_spftree_del(spftree_reverse);
+       isis_spftree_del(spftree_pc);
+}
+
 static int test_run(struct vty *vty, const struct isis_topology *topology,
                    const struct isis_test_node *root, enum test_type test_type,
-                   uint8_t flags)
+                   uint8_t flags, enum lfa_protection_type protection_type,
+                   const char *fail_sysid_str, uint8_t fail_pseudonode_id)
 {
        struct isis_area *area;
+       struct lfa_protected_resource protected_resource = {};
+       uint8_t fail_id[ISIS_SYS_ID_LEN] = {};
 
        /* Init topology. */
        memcpy(isis->sysid, root->sysid, sizeof(isis->sysid));
@@ -87,6 +149,26 @@ static int test_run(struct vty *vty, const struct isis_topology *topology,
                return CMD_WARNING;
        }
 
+       /* Parse failed link/node. */
+       if (fail_sysid_str) {
+               if (sysid2buff(fail_id, fail_sysid_str) == 0) {
+                       struct isis_dynhn *dynhn;
+
+                       dynhn = dynhn_find_by_name(fail_sysid_str);
+                       if (dynhn == NULL) {
+                               vty_out(vty, "Invalid system id %s\n",
+                                       fail_sysid_str);
+                               return CMD_WARNING;
+                       }
+                       memcpy(fail_id, dynhn->id, ISIS_SYS_ID_LEN);
+               }
+
+               protected_resource.type = protection_type;
+               memcpy(protected_resource.adjacency, fail_id, ISIS_SYS_ID_LEN);
+               LSP_PSEUDO_ID(protected_resource.adjacency) =
+                       fail_pseudonode_id;
+       }
+
        for (int level = IS_LEVEL_1; level <= IS_LEVEL_2; level++) {
                if (level == IS_LEVEL_1 && CHECK_FLAG(flags, F_LEVEL2_ONLY))
                        continue;
@@ -120,6 +202,11 @@ static int test_run(struct vty *vty, const struct isis_topology *topology,
                                             &area->lspdb[level - 1], level,
                                             tree, true);
                                break;
+                       case TEST_TI_LFA:
+                               test_run_ti_lfa(vty, topology, root, area,
+                                               &area->lspdb[level - 1], level,
+                                               tree, &protected_resource);
+                               break;
                        }
                }
        }
@@ -138,6 +225,7 @@ DEFUN(test_isis, test_isis_cmd,
          <\
           spf\
           |reverse-spf\
+          |ti-lfa system-id WORD [pseudonode-id <1-255>] [node-protection]\
         >\
         [display-lspdb] [<ipv4-only|ipv6-only>] [<level-1-only|level-2-only>]",
       "Test command\n"
@@ -148,6 +236,12 @@ DEFUN(test_isis, test_isis_cmd,
       "SPF root hostname\n"
       "Normal Shortest Path First\n"
       "Reverse Shortest Path First\n"
+      "Topology Independent LFA\n"
+      "System ID\n"
+      "System ID\n"
+      "Pseudonode-ID\n"
+      "Pseudonode-ID\n"
+      "Node protection\n"
       "Display the LSPDB\n"
       "Do IPv4 processing only\n"
       "Do IPv6 processing only\n"
@@ -158,6 +252,9 @@ DEFUN(test_isis, test_isis_cmd,
        const struct isis_topology *topology;
        const struct isis_test_node *root;
        enum test_type test_type;
+       enum lfa_protection_type protection_type = 0;
+       const char *fail_sysid_str = NULL;
+       uint8_t fail_pseudonode_id = 0;
        uint8_t flags = 0;
        int idx = 0;
 
@@ -184,7 +281,18 @@ DEFUN(test_isis, test_isis_cmd,
                test_type = TEST_SPF;
        else if (argv_find(argv, argc, "reverse-spf", &idx))
                test_type = TEST_REVERSE_SPF;
-       else
+       else if (argv_find(argv, argc, "ti-lfa", &idx)) {
+               test_type = TEST_TI_LFA;
+
+               fail_sysid_str = argv[idx + 2]->arg;
+               if (argv_find(argv, argc, "pseudonode-id", &idx))
+                       fail_pseudonode_id =
+                               strtoul(argv[idx + 1]->arg, NULL, 10);
+               if (argv_find(argv, argc, "node-protection", &idx))
+                       protection_type = LFA_NODE_PROTECTION;
+               else
+                       protection_type = LFA_LINK_PROTECTION;
+       } else
                return CMD_WARNING;
 
        /* Parse control flags. */
@@ -199,7 +307,8 @@ DEFUN(test_isis, test_isis_cmd,
        else if (argv_find(argv, argc, "level-2-only", &idx))
                SET_FLAG(flags, F_LEVEL2_ONLY);
 
-       return test_run(vty, topology, root, test_type, flags);
+       return test_run(vty, topology, root, test_type, flags, protection_type,
+                       fail_sysid_str, fail_pseudonode_id);
 }
 
 static void vty_do_exit(int isexit)
@@ -295,6 +404,7 @@ int main(int argc, char **argv)
        listnode_add(im->isis, isis);
        SET_FLAG(im->options, F_ISIS_UNIT_TEST);
        debug_spf_events |= DEBUG_SPF_EVENTS;
+       debug_tilfa |= DEBUG_TILFA;
        debug_events |= DEBUG_EVENTS;
        debug_rte_events |= DEBUG_RTE_EVENTS;
 
index d9a61782e99551d5d21d682b19852f0f72c0d622..6bc5442f1e927003d8d7084cffb3f9f969e9e75a 100644 (file)
@@ -14,3 +14,27 @@ test isis topology 13 root rt1 spf ipv4-only
 
 test isis topology 4 root rt1 reverse-spf ipv4-only
 test isis topology 11 root rt1 reverse-spf
+
+test isis topology 1 root rt1 ti-lfa system-id rt2
+test isis topology 2 root rt1 ti-lfa system-id rt3
+test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1
+test isis topology 2 root rt5 ti-lfa system-id rt1 pseudonode-id 1
+test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only
+test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only
+test isis topology 4 root rt1 ti-lfa system-id rt2 ipv4-only
+test isis topology 4 root rt4 ti-lfa system-id rt6 ipv4-only
+test isis topology 5 root rt1 ti-lfa system-id rt2 ipv4-only
+test isis topology 6 root rt4 ti-lfa system-id rt3 ipv4-only
+test isis topology 7 root rt11 ti-lfa system-id rt8 ipv4-only
+test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only
+test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only
+test isis topology 8 root rt2 ti-lfa system-id rt5 ipv4-only
+test isis topology 9 root rt1 ti-lfa system-id rt3
+test isis topology 9 root rt1 ti-lfa system-id rt2
+test isis topology 9 root rt9 ti-lfa system-id rt5
+test isis topology 9 root rt9 ti-lfa system-id rt8
+test isis topology 10 root rt1 ti-lfa system-id rt2
+test isis topology 10 root rt1 ti-lfa system-id rt4
+test isis topology 11 root rt2 ti-lfa system-id rt4
+test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only
+test isis topology 13 root rt1 ti-lfa system-id rt3 ipv4-only
index 21e7ef62695e761f2793caf5c617e4e436f8fef6..f44fa70d6bf00d05c61753fd73f9c121f6f7fe99 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestIsisSPF(frrtest.TestRefOut):
-    program = './test_isis_spf'
+    program = "./test_isis_spf"
index ed0569947cc056ad189ddc24bceccfe76c22aa01..d24176a097e08f3c98b04eda169dcc1dc8266fd9 100644 (file)
@@ -18,14 +18,15 @@ rt6                  TE-IS        30     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
-                        -          rt3      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
+                        -          rt3      16060          \r
 \r
 IS-IS paths to level-1 routers that speak IPv6\r
 Vertex               Type         Metric Next-Hop             Interface Parent\r
@@ -46,14 +47,15 @@ rt6                  TE-IS        30     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::2/128  20      -          rt2      -         \r
- 2001:db8::3/128  20      -          rt3      -         \r
- 2001:db8::4/128  30      -          rt2      -         \r
- 2001:db8::5/128  30      -          rt3      -         \r
- 2001:db8::6/128  40      -          rt2      -         \r
-                          -          rt3      -         \r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  0       -          -        -              \r
+ 2001:db8::2/128  20      -          rt2      implicit-null  \r
+ 2001:db8::3/128  20      -          rt3      implicit-null  \r
+ 2001:db8::4/128  30      -          rt2      16041          \r
+ 2001:db8::5/128  30      -          rt3      16051          \r
+ 2001:db8::6/128  40      -          rt2      16061          \r
+                          -          rt3      16061          \r
 \r
 test# test isis topology 2 root rt1 spf\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -76,14 +78,15 @@ rt3                  TE-IS        30     rt3                  -         rt1(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  25      -          rt2      -         \r
- 10.0.255.3/32  40      -          rt3      -         \r
- 10.0.255.4/32  20      -          rt4      -         \r
- 10.0.255.5/32  20      -          rt5      -         \r
- 10.0.255.6/32  30      -          rt4      -         \r
-                        -          rt5      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  25      -          rt2      implicit-null  \r
+ 10.0.255.3/32  40      -          rt3      implicit-null  \r
+ 10.0.255.4/32  20      -          rt4      implicit-null  \r
+ 10.0.255.5/32  20      -          rt5      implicit-null  \r
+ 10.0.255.6/32  30      -          rt4      16060          \r
+                        -          rt5      16060          \r
 \r
 IS-IS paths to level-1 routers that speak IPv6\r
 Vertex               Type         Metric Next-Hop             Interface Parent\r
@@ -105,14 +108,15 @@ rt3                  TE-IS        30     rt3                  -         rt1(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::2/128  25      -          rt2      -         \r
- 2001:db8::3/128  40      -          rt3      -         \r
- 2001:db8::4/128  20      -          rt4      -         \r
- 2001:db8::5/128  20      -          rt5      -         \r
- 2001:db8::6/128  30      -          rt4      -         \r
-                          -          rt5      -         \r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  0       -          -        -              \r
+ 2001:db8::2/128  25      -          rt2      implicit-null  \r
+ 2001:db8::3/128  40      -          rt3      implicit-null  \r
+ 2001:db8::4/128  20      -          rt4      implicit-null  \r
+ 2001:db8::5/128  20      -          rt5      implicit-null  \r
+ 2001:db8::6/128  30      -          rt4      16061          \r
+                          -          rt5      16061          \r
 \r
 test# test isis topology 3 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -132,13 +136,14 @@ rt6                  TE-IS        30     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  40      -          rt2      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  40      -          rt2      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
 \r
 test# test isis topology 4 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -162,15 +167,16 @@ rt8                  TE-IS        40     rt2                  -         rt6(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
- 10.0.255.7/32  40      -          rt3      -         \r
- 10.0.255.8/32  50      -          rt2      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
+ 10.0.255.7/32  40      -          rt3      16070          \r
+ 10.0.255.8/32  50      -          rt2      16080          \r
 \r
 test# test isis topology 5 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -196,16 +202,17 @@ rt8                  TE-IS        40     rt2                  -         rt6(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
- 10.0.255.7/32  40      -          rt3      -         \r
- 10.0.255.8/32  50      -          rt2      -         \r
-                        -          rt3      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
+ 10.0.255.7/32  40      -          rt3      16070          \r
+ 10.0.255.8/32  50      -          rt2      16080          \r
+                        -          rt3      16080          \r
 \r
 test# test isis topology 6 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -239,20 +246,21 @@ rt7                  TE-IS        50     rt2                  -         rt5(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
-                        -          rt3      -         \r
- 10.0.255.5/32  50      -          rt2      -         \r
-                        -          rt3      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
-                        -          rt3      -         \r
- 10.0.255.7/32  60      -          rt2      -         \r
-                        -          rt3      -         \r
- 10.0.255.8/32  50      -          rt2      -         \r
-                        -          rt3      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+                        -          rt3      16040          \r
+ 10.0.255.5/32  50      -          rt2      16050          \r
+                        -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
+                        -          rt3      16060          \r
+ 10.0.255.7/32  60      -          rt2      16070          \r
+                        -          rt3      16070          \r
+ 10.0.255.8/32  50      -          rt2      16080          \r
+                        -          rt3      16080          \r
 \r
 test# test isis topology 7 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -287,19 +295,20 @@ rt12                 TE-IS        50     rt4                  -         rt9(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix          Metric  Interface  Nexthop  Label(s)  \r
- ------------------------------------------------------\r
- 10.0.255.2/32   40      -          rt4      -         \r
- 10.0.255.3/32   50      -          rt4      -         \r
- 10.0.255.4/32   20      -          rt4      -         \r
- 10.0.255.5/32   30      -          rt4      -         \r
- 10.0.255.6/32   40      -          rt4      -         \r
- 10.0.255.7/32   30      -          rt4      -         \r
- 10.0.255.8/32   40      -          rt4      -         \r
- 10.0.255.9/32   50      -          rt4      -         \r
- 10.0.255.10/32  50      -          rt4      -         \r
- 10.0.255.11/32  50      -          rt4      -         \r
- 10.0.255.12/32  60      -          rt4      -         \r
+ Prefix          Metric  Interface  Nexthop  Label(s)       \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32   0       -          -        -              \r
+ 10.0.255.2/32   40      -          rt4      16020          \r
+ 10.0.255.3/32   50      -          rt4      16030          \r
+ 10.0.255.4/32   20      -          rt4      implicit-null  \r
+ 10.0.255.5/32   30      -          rt4      16050          \r
+ 10.0.255.6/32   40      -          rt4      16060          \r
+ 10.0.255.7/32   30      -          rt4      16070          \r
+ 10.0.255.8/32   40      -          rt4      16080          \r
+ 10.0.255.9/32   50      -          rt4      16090          \r
+ 10.0.255.10/32  50      -          rt4      16100          \r
+ 10.0.255.11/32  50      -          rt4      16110          \r
+ 10.0.255.12/32  60      -          rt4      16120          \r
 \r
 test# test isis topology 8 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -333,19 +342,20 @@ rt12                 TE-IS        50     rt2                  -         rt9(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix          Metric  Interface  Nexthop  Label(s)  \r
- ------------------------------------------------------\r
- 10.0.255.2/32   20      -          rt2      -         \r
- 10.0.255.3/32   30      -          rt2      -         \r
- 10.0.255.4/32   20      -          rt4      -         \r
- 10.0.255.5/32   30      -          rt2      -         \r
- 10.0.255.6/32   40      -          rt2      -         \r
- 10.0.255.7/32   30      -          rt4      -         \r
- 10.0.255.8/32   40      -          rt2      -         \r
- 10.0.255.9/32   50      -          rt2      -         \r
- 10.0.255.10/32  40      -          rt4      -         \r
- 10.0.255.11/32  50      -          rt2      -         \r
- 10.0.255.12/32  60      -          rt2      -         \r
+ Prefix          Metric  Interface  Nexthop  Label(s)       \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32   0       -          -        -              \r
+ 10.0.255.2/32   20      -          rt2      implicit-null  \r
+ 10.0.255.3/32   30      -          rt2      16030          \r
+ 10.0.255.4/32   20      -          rt4      implicit-null  \r
+ 10.0.255.5/32   30      -          rt2      16050          \r
+ 10.0.255.6/32   40      -          rt2      16060          \r
+ 10.0.255.7/32   30      -          rt4      16070          \r
+ 10.0.255.8/32   40      -          rt2      16080          \r
+ 10.0.255.9/32   50      -          rt2      16090          \r
+ 10.0.255.10/32  40      -          rt4      16100          \r
+ 10.0.255.11/32  50      -          rt2      16110          \r
+ 10.0.255.12/32  60      -          rt2      16120          \r
 \r
 test# test isis topology 9 root rt1 spf\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -374,16 +384,17 @@ rt8                  TE-IS        50     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  40      -          rt2      -         \r
- 10.0.255.6/32  60      -          rt2      -         \r
- 10.0.255.7/32  60      -          rt2      -         \r
- 10.0.255.8/32  60      -          rt2      -         \r
- 10.0.255.9/32  50      -          rt2      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  40      -          rt2      16050          \r
+ 10.0.255.6/32  60      -          rt2      16060          \r
+ 10.0.255.7/32  60      -          rt2      16070          \r
+ 10.0.255.8/32  60      -          rt2      16080          \r
+ 10.0.255.9/32  50      -          rt2      16090          \r
 \r
 IS-IS paths to level-1 routers that speak IPv6\r
 Vertex               Type         Metric Next-Hop             Interface Parent\r
@@ -411,16 +422,17 @@ rt8                  TE-IS        50     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::2/128  20      -          rt2      -         \r
- 2001:db8::3/128  20      -          rt3      -         \r
- 2001:db8::4/128  30      -          rt2      -         \r
- 2001:db8::5/128  40      -          rt2      -         \r
- 2001:db8::6/128  60      -          rt2      -         \r
- 2001:db8::7/128  60      -          rt2      -         \r
- 2001:db8::8/128  60      -          rt2      -         \r
- 2001:db8::9/128  50      -          rt2      -         \r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  0       -          -        -              \r
+ 2001:db8::2/128  20      -          rt2      implicit-null  \r
+ 2001:db8::3/128  20      -          rt3      implicit-null  \r
+ 2001:db8::4/128  30      -          rt2      16041          \r
+ 2001:db8::5/128  40      -          rt2      16051          \r
+ 2001:db8::6/128  60      -          rt2      16061          \r
+ 2001:db8::7/128  60      -          rt2      16071          \r
+ 2001:db8::8/128  60      -          rt2      16081          \r
+ 2001:db8::9/128  50      -          rt2      16091          \r
 \r
 test# test isis topology 10 root rt1 spf\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -444,15 +456,16 @@ rt8                  TE-IS        30     rt2                  -         rt5(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  30      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt4      -         \r
- 10.0.255.5/32  30      -          rt2      -         \r
- 10.0.255.6/32  40      -          rt3      -         \r
- 10.0.255.7/32  40      -          rt4      -         \r
- 10.0.255.8/32  40      -          rt2      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  30      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt4      implicit-null  \r
+ 10.0.255.5/32  30      -          rt2      16050          \r
+ 10.0.255.6/32  40      -          rt3      20060          \r
+ 10.0.255.7/32  40      -          rt4      16070          \r
+ 10.0.255.8/32  40      -          rt2      16080          \r
 \r
 IS-IS paths to level-1 routers that speak IPv6\r
 Vertex               Type         Metric Next-Hop             Interface Parent\r
@@ -475,15 +488,16 @@ rt8                  TE-IS        30     rt2                  -         rt5(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::2/128  20      -          rt2      -         \r
- 2001:db8::3/128  30      -          rt3      -         \r
- 2001:db8::4/128  30      -          rt4      -         \r
- 2001:db8::5/128  30      -          rt2      -         \r
- 2001:db8::6/128  40      -          rt3      -         \r
- 2001:db8::7/128  40      -          rt4      -         \r
- 2001:db8::8/128  40      -          rt2      -         \r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  0       -          -        -              \r
+ 2001:db8::2/128  20      -          rt2      implicit-null  \r
+ 2001:db8::3/128  30      -          rt3      implicit-null  \r
+ 2001:db8::4/128  30      -          rt4      implicit-null  \r
+ 2001:db8::5/128  30      -          rt2      16051          \r
+ 2001:db8::6/128  40      -          rt3      20061          \r
+ 2001:db8::7/128  40      -          rt4      16071          \r
+ 2001:db8::8/128  40      -          rt2      16081          \r
 \r
 test# test isis topology 11 root rt1 spf\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -506,14 +520,15 @@ rt6                  TE-IS        30     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
-                        -          rt3      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
+                        -          rt3      16060          \r
 \r
 IS-IS paths to level-1 routers that speak IPv6\r
 Vertex               Type         Metric Next-Hop             Interface Parent\r
@@ -535,14 +550,15 @@ rt6                  TE-IS        30     rt2                  -         rt4(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::2/128  20      -          rt2      -         \r
- 2001:db8::3/128  20      -          rt3      -         \r
- 2001:db8::4/128  30      -          rt2      -         \r
- 2001:db8::5/128  30      -          rt3      -         \r
- 2001:db8::6/128  40      -          rt2      -         \r
-                          -          rt3      -         \r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  0       -          -        -              \r
+ 2001:db8::2/128  20      -          rt2      implicit-null  \r
+ 2001:db8::3/128  20      -          rt3      implicit-null  \r
+ 2001:db8::4/128  30      -          rt2      16041          \r
+ 2001:db8::5/128  30      -          rt3      16051          \r
+ 2001:db8::6/128  40      -          rt2      16061          \r
+                          -          rt3      16061          \r
 \r
 test# test isis topology 12 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -570,17 +586,18 @@ rt10                 TE-IS        50     rt2                  -         rt8(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix          Metric  Interface  Nexthop  Label(s)  \r
- ------------------------------------------------------\r
- 10.0.255.2/32   20      -          rt2      -         \r
- 10.0.255.3/32   20      -          rt3      -         \r
- 10.0.255.4/32   30      -          rt2      -         \r
- 10.0.255.5/32   30      -          rt3      -         \r
- 10.0.255.6/32   40      -          rt2      -         \r
- 10.0.255.7/32   40      -          rt3      -         \r
- 10.0.255.8/32   50      -          rt2      -         \r
- 10.0.255.9/32   50      -          rt3      -         \r
- 10.0.255.10/32  60      -          rt2      -         \r
+ Prefix          Metric  Interface  Nexthop  Label(s)       \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32   0       -          -        -              \r
+ 10.0.255.2/32   20      -          rt2      implicit-null  \r
+ 10.0.255.3/32   20      -          rt3      implicit-null  \r
+ 10.0.255.4/32   30      -          rt2      16040          \r
+ 10.0.255.5/32   30      -          rt3      16050          \r
+ 10.0.255.6/32   40      -          rt2      16060          \r
+ 10.0.255.7/32   40      -          rt3      16070          \r
+ 10.0.255.8/32   50      -          rt2      16080          \r
+ 10.0.255.9/32   50      -          rt3      16090          \r
+ 10.0.255.10/32  60      -          rt2      16100          \r
 \r
 test# test isis topology 13 root rt1 spf ipv4-only\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -605,15 +622,16 @@ rt7                  TE-IS        30     rt3                  -         rt5(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
-                        -          rt3      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  30      -          rt3      -         \r
- 10.0.255.7/32  40      -          rt3      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+                        -          rt3      16040          \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  30      -          rt3      16060          \r
+ 10.0.255.7/32  40      -          rt3      16070          \r
 \r
 test# \r
 test# test isis topology 4 root rt1 reverse-spf ipv4-only\r
@@ -638,15 +656,16 @@ rt8                  TE-IS        40     rt2                  -         rt6(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.2/32  20      -          rt2      -         \r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.4/32  30      -          rt2      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  40      -          rt2      -         \r
- 10.0.255.7/32  40      -          rt3      -         \r
- 10.0.255.8/32  50      -          rt2      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.2/32  20      -          rt2      implicit-null  \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.4/32  30      -          rt2      16040          \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt2      16060          \r
+ 10.0.255.7/32  40      -          rt3      16070          \r
+ 10.0.255.8/32  50      -          rt2      16080          \r
 \r
 test# test isis topology 11 root rt1 reverse-spf\r
 IS-IS paths to level-1 routers that speak IP\r
@@ -668,11 +687,12 @@ rt6                  TE-IS        30     rt3                  -         rt4(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.3/32  20      -          rt3      -         \r
- 10.0.255.5/32  30      -          rt3      -         \r
- 10.0.255.6/32  40      -          rt3      -         \r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  0       -          -        -              \r
+ 10.0.255.3/32  20      -          rt3      implicit-null  \r
+ 10.0.255.5/32  30      -          rt3      16050          \r
+ 10.0.255.6/32  40      -          rt3      16060          \r
 \r
 IS-IS paths to level-1 routers that speak IPv6\r
 Vertex               Type         Metric Next-Hop             Interface Parent\r
@@ -693,11 +713,1781 @@ rt6                  TE-IS        30     rt3                  -         rt4(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::3/128  20      -          rt3      -         \r
- 2001:db8::5/128  30      -          rt3      -         \r
- 2001:db8::6/128  40      -          rt3      -         \r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  0       -          -        -              \r
+ 2001:db8::3/128  20      -          rt3      implicit-null  \r
+ 2001:db8::5/128  30      -          rt3      16051          \r
+ 2001:db8::6/128  40      -          rt3      16061          \r
+\r
+test# \r
+test# test isis topology 1 root rt1 ti-lfa system-id rt2\r
+P-space (self):\r
+ rt3\r
+ rt5\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt5\r
+ rt6\r
+\r
+Q-space:\r
+ rt2\r
+ rt4\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt3                  TE-IS        10     rt3                  -         rt1(4)\r
+rt5                  TE-IS        20     rt3                  -         rt3(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+rt6                  TE-IS        30     rt3                  -         rt5(4)\r
+10.0.255.5/32        IP TE        30     rt3                  -         rt5(4)\r
+rt4                  TE-IS        40     rt3                  -         rt6(4)\r
+10.0.255.6/32        IP TE        40     rt3                  -         rt6(4)\r
+rt2                  TE-IS        50     rt3                  -         rt4(4)\r
+10.0.255.4/32        IP TE        50     rt3                  -         rt4(4)\r
+10.0.255.2/32        IP TE        60     rt3                  -         rt2(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)     \r
+ --------------------------------------------------------\r
+ 10.0.255.2/32  60      -          rt3      16060/16020  \r
+ 10.0.255.4/32  50      -          rt3      16060/16040  \r
+\r
+P-space (self):\r
+ rt3\r
+ rt5\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt5\r
+ rt6\r
+\r
+Q-space:\r
+ rt2\r
+ rt4\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt3                  TE-IS        10     rt3                  -         rt1(4)\r
+rt5                  TE-IS        20     rt3                  -         rt3(4)\r
+2001:db8::3/128      IP6 internal 20     rt3                  -         rt3(4)\r
+rt6                  TE-IS        30     rt3                  -         rt5(4)\r
+2001:db8::5/128      IP6 internal 30     rt3                  -         rt5(4)\r
+rt4                  TE-IS        40     rt3                  -         rt6(4)\r
+2001:db8::6/128      IP6 internal 40     rt3                  -         rt6(4)\r
+rt2                  TE-IS        50     rt3                  -         rt4(4)\r
+2001:db8::4/128      IP6 internal 50     rt3                  -         rt4(4)\r
+2001:db8::2/128      IP6 internal 60     rt3                  -         rt2(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)     \r
+ ----------------------------------------------------------\r
+ 2001:db8::2/128  60      -          rt3      16061/16021  \r
+ 2001:db8::4/128  50      -          rt3      16061/16041  \r
+\r
+test# test isis topology 2 root rt1 ti-lfa system-id rt3\r
+P-space (self):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+P-space (rt2):\r
+ rt2\r
+\r
+P-space (rt4):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+P-space (rt5):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+Q-space:\r
+ rt3\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt4                  TE-IS        10     rt4                  -         rt1(4)\r
+rt5                  TE-IS        10     rt5                  -         rt1(4)\r
+rt2                  TE-IS        15     rt2                  -         rt1(4)\r
+rt1                                                                   \r
+rt6                  TE-IS        20     rt4                  -         rt4(4)\r
+                                         rt5                  -         rt5(4)\r
+10.0.255.4/32        IP TE        20     rt4                  -         rt4(4)\r
+10.0.255.5/32        IP TE        20     rt5                  -         rt5(4)\r
+10.0.255.2/32        IP TE        25     rt2                  -         rt2(4)\r
+10.0.255.6/32        IP TE        30     rt4                  -         rt6(4)\r
+                                         rt5                  -         \r
+rt3                  TE-IS        50     rt5                  -         rt5(4)\r
+10.0.255.3/32        IP TE        60     rt5                  -         rt3(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.3/32  60      -          rt5      16050/18/16030  \r
+\r
+P-space (self):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+P-space (rt2):\r
+ rt2\r
+\r
+P-space (rt4):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+P-space (rt5):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+Q-space:\r
+ rt3\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt4                  TE-IS        10     rt4                  -         rt1(4)\r
+rt5                  TE-IS        10     rt5                  -         rt1(4)\r
+rt2                  TE-IS        15     rt2                  -         rt1(4)\r
+rt1                                                                   \r
+rt6                  TE-IS        20     rt4                  -         rt4(4)\r
+                                         rt5                  -         rt5(4)\r
+2001:db8::4/128      IP6 internal 20     rt4                  -         rt4(4)\r
+2001:db8::5/128      IP6 internal 20     rt5                  -         rt5(4)\r
+2001:db8::2/128      IP6 internal 25     rt2                  -         rt2(4)\r
+2001:db8::6/128      IP6 internal 30     rt4                  -         rt6(4)\r
+                                         rt5                  -         \r
+rt3                  TE-IS        50     rt5                  -         rt5(4)\r
+2001:db8::3/128      IP6 internal 60     rt5                  -         rt3(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::3/128  60      -          rt5      16051/19/16031  \r
+\r
+test# test isis topology 2 root rt1 ti-lfa system-id rt1 pseudonode-id 1\r
+P-space (self):\r
+ rt2\r
+ rt3\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt3\r
+\r
+P-space (rt3):\r
+ rt2\r
+ rt3\r
+\r
+Q-space:\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt2                  TE-IS        15     rt2                  -         rt1(4)\r
+10.0.255.2/32        IP TE        25     rt2                  -         rt2(4)\r
+rt3                  TE-IS        30     rt3                  -         rt1(4)\r
+10.0.255.3/32        IP TE        40     rt3                  -         rt3(4)\r
+rt4                  TE-IS        55     rt2                  -         rt2(4)\r
+rt1                                                                   \r
+rt6                  TE-IS        65     rt2                  -         rt4(4)\r
+rt5                  TE-IS        65     rt2                  -         rt1(2)\r
+10.0.255.4/32        IP TE        65     rt2                  -         rt4(4)\r
+10.0.255.6/32        IP TE        75     rt2                  -         rt6(4)\r
+10.0.255.5/32        IP TE        75     rt2                  -         rt5(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.4/32  65      -          rt2      16020/18/16040  \r
+ 10.0.255.5/32  75      -          rt2      16020/18/16050  \r
+ 10.0.255.6/32  75      -          rt2      16020/18/16060  \r
+\r
+P-space (self):\r
+ rt2\r
+ rt3\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt3\r
+\r
+P-space (rt3):\r
+ rt2\r
+ rt3\r
+\r
+Q-space:\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt2                  TE-IS        15     rt2                  -         rt1(4)\r
+2001:db8::2/128      IP6 internal 25     rt2                  -         rt2(4)\r
+rt3                  TE-IS        30     rt3                  -         rt1(4)\r
+2001:db8::3/128      IP6 internal 40     rt3                  -         rt3(4)\r
+rt4                  TE-IS        55     rt2                  -         rt2(4)\r
+rt1                                                                   \r
+rt6                  TE-IS        65     rt2                  -         rt4(4)\r
+rt5                  TE-IS        65     rt2                  -         rt1(2)\r
+2001:db8::4/128      IP6 internal 65     rt2                  -         rt4(4)\r
+2001:db8::6/128      IP6 internal 75     rt2                  -         rt6(4)\r
+2001:db8::5/128      IP6 internal 75     rt2                  -         rt5(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::4/128  65      -          rt2      16021/19/16041  \r
+ 2001:db8::5/128  75      -          rt2      16021/19/16051  \r
+ 2001:db8::6/128  75      -          rt2      16021/19/16061  \r
+\r
+test# test isis topology 2 root rt5 ti-lfa system-id rt1 pseudonode-id 1\r
+P-space (self):\r
+ rt6\r
+\r
+P-space (rt3):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+\r
+P-space (rt6):\r
+ rt4\r
+ rt6\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt5                                                                   \r
+10.0.255.5/32        IP internal  0                                     rt5(4)\r
+rt6                  TE-IS        10     rt6                  -         rt5(4)\r
+rt4                  TE-IS        20     rt6                  -         rt6(4)\r
+10.0.255.6/32        IP TE        20     rt6                  -         rt6(4)\r
+rt1                  pseudo_TE-IS 30     rt6                  -         rt4(4)\r
+rt1                  TE-IS        30     rt6                  -         rt1(2)\r
+10.0.255.4/32        IP TE        30     rt6                  -         rt4(4)\r
+rt3                  TE-IS        40     rt3                  -         rt5(4)\r
+10.0.255.1/32        IP TE        40     rt6                  -         rt1(4)\r
+rt2                  TE-IS        45     rt6                  -         rt1(4)\r
+10.0.255.3/32        IP TE        50     rt3                  -         rt3(4)\r
+10.0.255.2/32        IP TE        55     rt6                  -         rt2(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)     \r
+ --------------------------------------------------------\r
+ 10.0.255.1/32  40      -          rt6      16040/16010  \r
+ 10.0.255.2/32  55      -          rt6      16040/16020  \r
+ 10.0.255.4/32  30      -          rt6      16040        \r
+\r
+P-space (self):\r
+ rt6\r
+\r
+P-space (rt3):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+\r
+P-space (rt6):\r
+ rt4\r
+ rt6\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt5                                                                   \r
+2001:db8::5/128      IP6 internal 0                                     rt5(4)\r
+rt6                  TE-IS        10     rt6                  -         rt5(4)\r
+rt4                  TE-IS        20     rt6                  -         rt6(4)\r
+2001:db8::6/128      IP6 internal 20     rt6                  -         rt6(4)\r
+rt1                  pseudo_TE-IS 30     rt6                  -         rt4(4)\r
+rt1                  TE-IS        30     rt6                  -         rt1(2)\r
+2001:db8::4/128      IP6 internal 30     rt6                  -         rt4(4)\r
+rt3                  TE-IS        40     rt3                  -         rt5(4)\r
+2001:db8::1/128      IP6 internal 40     rt6                  -         rt1(4)\r
+rt2                  TE-IS        45     rt6                  -         rt1(4)\r
+2001:db8::3/128      IP6 internal 50     rt3                  -         rt3(4)\r
+2001:db8::2/128      IP6 internal 55     rt6                  -         rt2(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)     \r
+ ----------------------------------------------------------\r
+ 2001:db8::1/128  40      -          rt6      16041/16011  \r
+ 2001:db8::2/128  55      -          rt6      16041/16021  \r
+ 2001:db8::4/128  30      -          rt6      16041        \r
+\r
+test# test isis topology 3 root rt5 ti-lfa system-id rt4 ipv4-only\r
+P-space (self):\r
+ rt6\r
+\r
+P-space (rt3):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+P-space (rt6):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt5                                                                   \r
+10.0.255.5/32        IP internal  0                                     rt5(4)\r
+rt6                  TE-IS        10     rt6                  -         rt5(4)\r
+rt4                  TE-IS        20     rt6                  -         rt6(4)\r
+10.0.255.6/32        IP TE        20     rt6                  -         rt6(4)\r
+rt3                  TE-IS        30     rt3                  -         rt5(4)\r
+rt2                  TE-IS        30     rt6                  -         rt4(4)\r
+10.0.255.4/32        IP TE        30     rt6                  -         rt4(4)\r
+rt1                  TE-IS        40     rt3                  -         rt3(4)\r
+                                         rt6                  -         rt2(4)\r
+10.0.255.3/32        IP TE        40     rt3                  -         rt3(4)\r
+10.0.255.2/32        IP TE        40     rt6                  -         rt2(4)\r
+10.0.255.1/32        IP TE        50     rt3                  -         rt1(4)\r
+                                         rt6                  -         \r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)  \r
+ -----------------------------------------------------\r
+ 10.0.255.1/32  50      -          rt3      16010     \r
+                        -          rt6      16010     \r
+ 10.0.255.2/32  40      -          rt6      16020     \r
+ 10.0.255.4/32  30      -          rt6      16040     \r
+\r
+test# test isis topology 3 root rt5 ti-lfa system-id rt3 ipv4-only\r
+P-space (self):\r
+ rt1\r
+ rt2\r
+ rt4\r
+ rt6\r
+\r
+P-space (rt4):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+P-space (rt6):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt5                                                                   \r
+10.0.255.5/32        IP internal  0                                     rt5(4)\r
+rt4                  TE-IS        10     rt4                  -         rt5(4)\r
+rt6                  TE-IS        10     rt6                  -         rt5(4)\r
+rt2                  TE-IS        20     rt4                  -         rt4(4)\r
+10.0.255.4/32        IP TE        20     rt4                  -         rt4(4)\r
+10.0.255.6/32        IP TE        20     rt6                  -         rt6(4)\r
+rt1                  TE-IS        30     rt4                  -         rt2(4)\r
+rt3                  TE-IS        30     rt4                  -         rt2(4)\r
+10.0.255.2/32        IP TE        30     rt4                  -         rt2(4)\r
+10.0.255.1/32        IP TE        40     rt4                  -         rt1(4)\r
+10.0.255.3/32        IP TE        40     rt4                  -         rt3(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+test# test isis topology 4 root rt1 ti-lfa system-id rt2 ipv4-only\r
+P-space (self):\r
+ rt3\r
+ rt5\r
+ rt7\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt5\r
+ rt7\r
+\r
+Q-space:\r
+ rt2\r
+ rt4\r
+ rt6\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt3                  TE-IS        10     rt3                  -         rt1(4)\r
+rt5                  TE-IS        20     rt3                  -         rt3(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+rt7                  TE-IS        30     rt3                  -         rt5(4)\r
+10.0.255.5/32        IP TE        30     rt3                  -         rt5(4)\r
+10.0.255.7/32        IP TE        40     rt3                  -         rt7(4)\r
+rt6                  TE-IS        70     rt3                  -         rt5(4)\r
+rt4                  TE-IS        80     rt3                  -         rt6(4)\r
+rt8                  TE-IS        80     rt3                  -         rt6(4)\r
+10.0.255.6/32        IP TE        80     rt3                  -         rt6(4)\r
+rt2                  TE-IS        90     rt3                  -         rt4(4)\r
+10.0.255.4/32        IP TE        90     rt3                  -         rt4(4)\r
+10.0.255.8/32        IP TE        90     rt3                  -         rt8(4)\r
+10.0.255.2/32        IP TE        100    rt3                  -         rt2(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.2/32  100     -          rt3      16050/17/16020  \r
+ 10.0.255.4/32  90      -          rt3      16050/17/16040  \r
+ 10.0.255.6/32  80      -          rt3      16050/17/16060  \r
+ 10.0.255.8/32  90      -          rt3      16050/17/16080  \r
+\r
+test# test isis topology 4 root rt4 ti-lfa system-id rt6 ipv4-only\r
+P-space (self):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt5\r
+ rt7\r
+\r
+P-space (rt2):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt5\r
+ rt7\r
+\r
+Q-space:\r
+ rt6\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt4                                                                   \r
+10.0.255.4/32        IP internal  0                                     rt4(4)\r
+rt2                  TE-IS        10     rt2                  -         rt4(4)\r
+rt1                  TE-IS        20     rt2                  -         rt2(4)\r
+10.0.255.2/32        IP TE        20     rt2                  -         rt2(4)\r
+rt3                  TE-IS        30     rt2                  -         rt1(4)\r
+10.0.255.1/32        IP TE        30     rt2                  -         rt1(4)\r
+rt5                  TE-IS        40     rt2                  -         rt3(4)\r
+10.0.255.3/32        IP TE        40     rt2                  -         rt3(4)\r
+rt7                  TE-IS        50     rt2                  -         rt5(4)\r
+10.0.255.5/32        IP TE        50     rt2                  -         rt5(4)\r
+10.0.255.7/32        IP TE        60     rt2                  -         rt7(4)\r
+rt6                  TE-IS        90     rt2                  -         rt5(4)\r
+rt8                  TE-IS        100    rt2                  -         rt6(4)\r
+10.0.255.6/32        IP TE        100    rt2                  -         rt6(4)\r
+10.0.255.8/32        IP TE        110    rt2                  -         rt8(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.6/32  100     -          rt2      16050/17/16060  \r
+ 10.0.255.8/32  110     -          rt2      16050/17/16080  \r
+\r
+test# test isis topology 5 root rt1 ti-lfa system-id rt2 ipv4-only\r
+P-space (self):\r
+ rt3\r
+ rt5\r
+ rt7\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt5\r
+ rt7\r
+ rt8\r
+\r
+Q-space:\r
+ rt2\r
+ rt4\r
+ rt6\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt3                  TE-IS        10     rt3                  -         rt1(4)\r
+rt5                  TE-IS        20     rt3                  -         rt3(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+rt7                  TE-IS        30     rt3                  -         rt5(4)\r
+10.0.255.5/32        IP TE        30     rt3                  -         rt5(4)\r
+rt8                  TE-IS        40     rt3                  -         rt7(4)\r
+10.0.255.7/32        IP TE        40     rt3                  -         rt7(4)\r
+rt6                  TE-IS        50     rt3                  -         rt8(4)\r
+10.0.255.8/32        IP TE        50     rt3                  -         rt8(4)\r
+rt4                  TE-IS        60     rt3                  -         rt6(4)\r
+10.0.255.6/32        IP TE        60     rt3                  -         rt6(4)\r
+rt2                  TE-IS        70     rt3                  -         rt4(4)\r
+10.0.255.4/32        IP TE        70     rt3                  -         rt4(4)\r
+10.0.255.2/32        IP TE        80     rt3                  -         rt2(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)     \r
+ --------------------------------------------------------\r
+ 10.0.255.2/32  80      -          rt3      16080/16020  \r
+ 10.0.255.4/32  70      -          rt3      16080/16040  \r
+ 10.0.255.6/32  60      -          rt3      16080/16060  \r
+\r
+test# test isis topology 6 root rt4 ti-lfa system-id rt3 ipv4-only\r
+P-space (self):\r
+ rt2\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+\r
+P-space (rt2):\r
+ rt1\r
+ rt2\r
+\r
+P-space (rt6):\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+\r
+Q-space:\r
+ rt1\r
+ rt3\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt4                                                                   \r
+10.0.255.4/32        IP internal  0                                     rt4(4)\r
+rt2                  TE-IS        10     rt2                  -         rt4(4)\r
+rt6                  TE-IS        10     rt6                  -         rt4(4)\r
+rt1                  TE-IS        20     rt2                  -         rt2(4)\r
+rt5                  TE-IS        20     rt6                  -         rt6(4)\r
+rt8                  TE-IS        20     rt6                  -         rt6(4)\r
+10.0.255.2/32        IP TE        20     rt2                  -         rt2(4)\r
+10.0.255.6/32        IP TE        20     rt6                  -         rt6(4)\r
+rt3                  TE-IS        30     rt2                  -         rt1(4)\r
+rt7                  TE-IS        30     rt6                  -         rt5(4)\r
+                                                                        rt8(4)\r
+10.0.255.1/32        IP TE        30     rt2                  -         rt1(4)\r
+10.0.255.5/32        IP TE        30     rt6                  -         rt5(4)\r
+10.0.255.8/32        IP TE        30     rt6                  -         rt8(4)\r
+10.0.255.3/32        IP TE        40     rt2                  -         rt3(4)\r
+10.0.255.7/32        IP TE        40     rt6                  -         rt7(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)     \r
+ --------------------------------------------------------\r
+ 10.0.255.3/32  40      -          rt2      16010/16030  \r
+\r
+test# test isis topology 7 root rt11 ti-lfa system-id rt8 ipv4-only\r
+P-space (self):\r
+ rt10\r
+ rt12\r
+\r
+P-space (rt10):\r
+ rt1\r
+ rt4\r
+ rt7\r
+ rt10\r
+\r
+P-space (rt12):\r
+ rt9\r
+ rt12\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt11                                                                  \r
+10.0.255.11/32       IP internal  0                                     rt11(4)\r
+rt10                 TE-IS        10     rt10                 -         rt11(4)\r
+rt12                 TE-IS        10     rt12                 -         rt11(4)\r
+rt9                  TE-IS        20     rt12                 -         rt12(4)\r
+10.0.255.10/32       IP TE        20     rt10                 -         rt10(4)\r
+10.0.255.12/32       IP TE        20     rt12                 -         rt12(4)\r
+rt7                  TE-IS        30     rt10                 -         rt10(4)\r
+rt8                  TE-IS        30     rt12                 -         rt9(4)\r
+10.0.255.9/32        IP TE        30     rt12                 -         rt9(4)\r
+rt4                  TE-IS        40     rt10                 -         rt7(4)\r
+rt5                  TE-IS        40     rt12                 -         rt8(4)\r
+10.0.255.7/32        IP TE        40     rt10                 -         rt7(4)\r
+10.0.255.8/32        IP TE        40     rt12                 -         rt8(4)\r
+rt6                  TE-IS        50     rt12                 -         rt9(4)\r
+                                                                        rt5(4)\r
+rt1                  TE-IS        50     rt10                 -         rt4(4)\r
+rt2                  TE-IS        50     rt12                 -         rt5(4)\r
+10.0.255.4/32        IP TE        50     rt10                 -         rt4(4)\r
+10.0.255.5/32        IP TE        50     rt12                 -         rt5(4)\r
+rt3                  TE-IS        60     rt12                 -         rt6(4)\r
+                                                                        rt2(4)\r
+10.0.255.6/32        IP TE        60     rt12                 -         rt6(4)\r
+10.0.255.1/32        IP TE        60     rt10                 -         rt1(4)\r
+10.0.255.2/32        IP TE        60     rt12                 -         rt2(4)\r
+10.0.255.3/32        IP TE        70     rt12                 -         rt3(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)     \r
+ --------------------------------------------------------\r
+ 10.0.255.1/32  60      -          rt10     16010        \r
+ 10.0.255.2/32  60      -          rt12     16090/16020  \r
+ 10.0.255.3/32  70      -          rt12     16090/16030  \r
+ 10.0.255.4/32  50      -          rt10     16040        \r
+ 10.0.255.5/32  50      -          rt12     16090/16050  \r
+ 10.0.255.6/32  60      -          rt12     16090/16060  \r
+ 10.0.255.7/32  40      -          rt10     16070        \r
+ 10.0.255.8/32  40      -          rt12     16090/16080  \r
+\r
+test# test isis topology 7 root rt6 ti-lfa system-id rt5 ipv4-only\r
+P-space (self):\r
+ rt3\r
+\r
+P-space (rt3):\r
+ rt2\r
+ rt3\r
+\r
+P-space (rt9):\r
+ rt1\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt7\r
+ rt8\r
+ rt9\r
+ rt10\r
+ rt11\r
+ rt12\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt7\r
+ rt8\r
+ rt9\r
+ rt10\r
+ rt11\r
+ rt12\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt6                                                                   \r
+10.0.255.6/32        IP internal  0                                     rt6(4)\r
+rt3                  TE-IS        10     rt3                  -         rt6(4)\r
+rt2                  TE-IS        20     rt3                  -         rt3(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+rt9                  TE-IS        30     rt9                  -         rt6(4)\r
+rt5                  TE-IS        30     rt3                  -         rt2(4)\r
+10.0.255.2/32        IP TE        30     rt3                  -         rt2(4)\r
+rt8                  TE-IS        40     rt9                  -         rt9(4)\r
+                                         rt3                  -         rt5(4)\r
+rt12                 TE-IS        40     rt9                  -         rt9(4)\r
+rt4                  TE-IS        40     rt3                  -         rt5(4)\r
+10.0.255.9/32        IP TE        40     rt9                  -         rt9(4)\r
+10.0.255.5/32        IP TE        40     rt3                  -         rt5(4)\r
+rt7                  TE-IS        50     rt9                  -         rt8(4)\r
+                                         rt3                  -         rt4(4)\r
+rt11                 TE-IS        50     rt9                  -         rt8(4)\r
+                                         rt3                  -         rt12(4)\r
+rt1                  TE-IS        50     rt3                  -         rt4(4)\r
+10.0.255.8/32        IP TE        50     rt9                  -         rt8(4)\r
+                                         rt3                  -         \r
+10.0.255.12/32       IP TE        50     rt9                  -         rt12(4)\r
+10.0.255.4/32        IP TE        50     rt3                  -         rt4(4)\r
+rt10                 TE-IS        60     rt9                  -         rt11(4)\r
+                                         rt3                  -         \r
+10.0.255.7/32        IP TE        60     rt9                  -         rt7(4)\r
+                                         rt3                  -         \r
+10.0.255.11/32       IP TE        60     rt9                  -         rt11(4)\r
+                                         rt3                  -         \r
+10.0.255.1/32        IP TE        60     rt3                  -         rt1(4)\r
+10.0.255.10/32       IP TE        70     rt9                  -         rt10(4)\r
+                                         rt3                  -         \r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix          Metric  Interface  Nexthop  Label(s)     \r
+ ---------------------------------------------------------\r
+ 10.0.255.1/32   60      -          rt3      16020/16010  \r
+ 10.0.255.4/32   50      -          rt3      16020/16040  \r
+ 10.0.255.5/32   40      -          rt3      16020/16050  \r
+ 10.0.255.7/32   60      -          rt9      16070        \r
+                         -          rt3      16070        \r
+ 10.0.255.8/32   50      -          rt9      16080        \r
+                         -          rt3      16080        \r
+ 10.0.255.10/32  70      -          rt9      16100        \r
+                         -          rt3      16100        \r
+ 10.0.255.11/32  60      -          rt9      16110        \r
+                         -          rt3      16110        \r
+\r
+test# test isis topology 8 root rt2 ti-lfa system-id rt1 ipv4-only\r
+P-space (self):\r
+ rt3\r
+ rt5\r
+ rt6\r
+ rt8\r
+ rt9\r
+ rt11\r
+ rt12\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt6\r
+\r
+P-space (rt5):\r
+ rt5\r
+ rt6\r
+ rt8\r
+ rt9\r
+ rt11\r
+ rt12\r
+\r
+Q-space:\r
+ rt1\r
+ rt4\r
+ rt7\r
+ rt10\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt2                                                                   \r
+10.0.255.2/32        IP internal  0                                     rt2(4)\r
+rt3                  TE-IS        10     rt3                  -         rt2(4)\r
+rt5                  TE-IS        10     rt5                  -         rt2(4)\r
+rt6                  TE-IS        20     rt3                  -         rt3(4)\r
+                                         rt5                  -         rt5(4)\r
+rt8                  TE-IS        20     rt5                  -         rt5(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+10.0.255.5/32        IP TE        20     rt5                  -         rt5(4)\r
+rt9                  TE-IS        30     rt5                  -         rt8(4)\r
+rt11                 TE-IS        30     rt5                  -         rt8(4)\r
+10.0.255.6/32        IP TE        30     rt3                  -         rt6(4)\r
+                                         rt5                  -         \r
+10.0.255.8/32        IP TE        30     rt5                  -         rt8(4)\r
+rt12                 TE-IS        40     rt5                  -         rt9(4)\r
+                                                                        rt11(4)\r
+10.0.255.9/32        IP TE        40     rt5                  -         rt9(4)\r
+10.0.255.11/32       IP TE        40     rt5                  -         rt11(4)\r
+10.0.255.12/32       IP TE        50     rt5                  -         rt12(4)\r
+rt10                 TE-IS        60     rt5                  -         rt11(4)\r
+rt7                  TE-IS        70     rt5                  -         rt10(4)\r
+10.0.255.10/32       IP TE        70     rt5                  -         rt10(4)\r
+rt4                  TE-IS        80     rt5                  -         rt7(4)\r
+10.0.255.7/32        IP TE        80     rt5                  -         rt7(4)\r
+rt1                  TE-IS        90     rt5                  -         rt4(4)\r
+10.0.255.4/32        IP TE        90     rt5                  -         rt4(4)\r
+10.0.255.1/32        IP TE        100    rt5                  -         rt1(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix          Metric  Interface  Nexthop  Label(s)        \r
+ ------------------------------------------------------------\r
+ 10.0.255.1/32   100     -          rt5      16110/17/16010  \r
+ 10.0.255.4/32   90      -          rt5      16110/17/16040  \r
+ 10.0.255.7/32   80      -          rt5      16110/17/16070  \r
+ 10.0.255.10/32  70      -          rt5      16110/17/16100  \r
+\r
+test# test isis topology 8 root rt2 ti-lfa system-id rt5 ipv4-only\r
+P-space (self):\r
+ rt1\r
+ rt3\r
+ rt4\r
+ rt7\r
+ rt10\r
+\r
+P-space (rt1):\r
+ rt1\r
+ rt4\r
+ rt7\r
+ rt10\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt6\r
+\r
+Q-space:\r
+ rt5\r
+ rt6\r
+ rt8\r
+ rt9\r
+ rt11\r
+ rt12\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt2                                                                   \r
+10.0.255.2/32        IP internal  0                                     rt2(4)\r
+rt1                  TE-IS        10     rt1                  -         rt2(4)\r
+rt3                  TE-IS        10     rt3                  -         rt2(4)\r
+rt4                  TE-IS        20     rt1                  -         rt1(4)\r
+rt6                  TE-IS        20     rt3                  -         rt3(4)\r
+10.0.255.1/32        IP TE        20     rt1                  -         rt1(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+rt7                  TE-IS        30     rt1                  -         rt4(4)\r
+rt5                  TE-IS        30     rt3                  -         rt6(4)\r
+10.0.255.4/32        IP TE        30     rt1                  -         rt4(4)\r
+10.0.255.6/32        IP TE        30     rt3                  -         rt6(4)\r
+rt10                 TE-IS        40     rt1                  -         rt7(4)\r
+rt8                  TE-IS        40     rt3                  -         rt5(4)\r
+10.0.255.7/32        IP TE        40     rt1                  -         rt7(4)\r
+10.0.255.5/32        IP TE        40     rt3                  -         rt5(4)\r
+rt9                  TE-IS        50     rt3                  -         rt8(4)\r
+rt11                 TE-IS        50     rt3                  -         rt8(4)\r
+10.0.255.10/32       IP TE        50     rt1                  -         rt10(4)\r
+10.0.255.8/32        IP TE        50     rt3                  -         rt8(4)\r
+rt12                 TE-IS        60     rt3                  -         rt9(4)\r
+                                                                        rt11(4)\r
+10.0.255.9/32        IP TE        60     rt3                  -         rt9(4)\r
+10.0.255.11/32       IP TE        60     rt3                  -         rt11(4)\r
+10.0.255.12/32       IP TE        70     rt3                  -         rt12(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix          Metric  Interface  Nexthop  Label(s)     \r
+ ---------------------------------------------------------\r
+ 10.0.255.5/32   40      -          rt3      16060/16050  \r
+ 10.0.255.8/32   50      -          rt3      16060/16080  \r
+ 10.0.255.9/32   60      -          rt3      16060/16090  \r
+ 10.0.255.11/32  60      -          rt3      16060/16110  \r
+ 10.0.255.12/32  70      -          rt3      16060/16120  \r
+\r
+test# test isis topology 9 root rt1 ti-lfa system-id rt3\r
+P-space (self):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+Q-space:\r
+ rt3\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt2                  TE-IS        10     rt2                  -         rt1(4)\r
+rt4                  TE-IS        20     rt2                  -         rt2(4)\r
+10.0.255.2/32        IP TE        20     rt2                  -         rt2(4)\r
+rt5                  TE-IS        30     rt2                  -         rt4(4)\r
+10.0.255.4/32        IP TE        30     rt2                  -         rt4(4)\r
+rt9                  TE-IS        40     rt2                  -         rt5(4)\r
+10.0.255.5/32        IP TE        40     rt2                  -         rt5(4)\r
+rt6                  TE-IS        50     rt2                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt7                  TE-IS        50     rt2                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt8                  TE-IS        50     rt2                  -         rt4(4)\r
+                                                                        rt9(4)\r
+10.0.255.9/32        IP TE        50     rt2                  -         rt9(4)\r
+10.0.255.6/32        IP TE        60     rt2                  -         rt6(4)\r
+10.0.255.7/32        IP TE        60     rt2                  -         rt7(4)\r
+10.0.255.8/32        IP TE        60     rt2                  -         rt8(4)\r
+rt3                  TE-IS        120    rt2                  -         rt4(4)\r
+10.0.255.3/32        IP TE        130    rt2                  -         rt3(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.3/32  130     -          rt2      16040/18/16030  \r
+\r
+P-space (self):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+Q-space:\r
+ rt3\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt2                  TE-IS        10     rt2                  -         rt1(4)\r
+rt4                  TE-IS        20     rt2                  -         rt2(4)\r
+2001:db8::2/128      IP6 internal 20     rt2                  -         rt2(4)\r
+rt5                  TE-IS        30     rt2                  -         rt4(4)\r
+2001:db8::4/128      IP6 internal 30     rt2                  -         rt4(4)\r
+rt9                  TE-IS        40     rt2                  -         rt5(4)\r
+2001:db8::5/128      IP6 internal 40     rt2                  -         rt5(4)\r
+rt6                  TE-IS        50     rt2                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt7                  TE-IS        50     rt2                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt8                  TE-IS        50     rt2                  -         rt4(4)\r
+                                                                        rt9(4)\r
+2001:db8::9/128      IP6 internal 50     rt2                  -         rt9(4)\r
+2001:db8::6/128      IP6 internal 60     rt2                  -         rt6(4)\r
+2001:db8::7/128      IP6 internal 60     rt2                  -         rt7(4)\r
+2001:db8::8/128      IP6 internal 60     rt2                  -         rt8(4)\r
+rt3                  TE-IS        120    rt2                  -         rt4(4)\r
+2001:db8::3/128      IP6 internal 130    rt2                  -         rt3(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::3/128  130     -          rt2      16041/19/16031  \r
+\r
+test# test isis topology 9 root rt1 ti-lfa system-id rt2\r
+P-space (self):\r
+ rt3\r
+\r
+P-space (rt3):\r
+ rt3\r
+\r
+Q-space:\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt3                  TE-IS        10     rt3                  -         rt1(4)\r
+10.0.255.3/32        IP TE        20     rt3                  -         rt3(4)\r
+rt4                  TE-IS        110    rt3                  -         rt3(4)\r
+rt2                  TE-IS        120    rt3                  -         rt4(4)\r
+rt5                  TE-IS        120    rt3                  -         rt4(4)\r
+10.0.255.4/32        IP TE        120    rt3                  -         rt4(4)\r
+rt9                  TE-IS        130    rt3                  -         rt5(4)\r
+10.0.255.2/32        IP TE        130    rt3                  -         rt2(4)\r
+10.0.255.5/32        IP TE        130    rt3                  -         rt5(4)\r
+rt6                  TE-IS        140    rt3                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt7                  TE-IS        140    rt3                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt8                  TE-IS        140    rt3                  -         rt4(4)\r
+                                                                        rt9(4)\r
+10.0.255.9/32        IP TE        140    rt3                  -         rt9(4)\r
+10.0.255.6/32        IP TE        150    rt3                  -         rt6(4)\r
+10.0.255.7/32        IP TE        150    rt3                  -         rt7(4)\r
+10.0.255.8/32        IP TE        150    rt3                  -         rt8(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.2/32  130     -          rt3      16030/18/16020  \r
+ 10.0.255.4/32  120     -          rt3      16030/18/16040  \r
+ 10.0.255.5/32  130     -          rt3      16030/18/16050  \r
+ 10.0.255.6/32  150     -          rt3      16030/18/16060  \r
+ 10.0.255.7/32  150     -          rt3      16030/18/16070  \r
+ 10.0.255.8/32  150     -          rt3      16030/18/16080  \r
+ 10.0.255.9/32  140     -          rt3      16030/18/16090  \r
+\r
+P-space (self):\r
+ rt3\r
+\r
+P-space (rt3):\r
+ rt3\r
+\r
+Q-space:\r
+ rt2\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+ rt8\r
+ rt9\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt3                  TE-IS        10     rt3                  -         rt1(4)\r
+2001:db8::3/128      IP6 internal 20     rt3                  -         rt3(4)\r
+rt4                  TE-IS        110    rt3                  -         rt3(4)\r
+rt2                  TE-IS        120    rt3                  -         rt4(4)\r
+rt5                  TE-IS        120    rt3                  -         rt4(4)\r
+2001:db8::4/128      IP6 internal 120    rt3                  -         rt4(4)\r
+rt9                  TE-IS        130    rt3                  -         rt5(4)\r
+2001:db8::2/128      IP6 internal 130    rt3                  -         rt2(4)\r
+2001:db8::5/128      IP6 internal 130    rt3                  -         rt5(4)\r
+rt6                  TE-IS        140    rt3                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt7                  TE-IS        140    rt3                  -         rt4(4)\r
+                                                                        rt9(4)\r
+rt8                  TE-IS        140    rt3                  -         rt4(4)\r
+                                                                        rt9(4)\r
+2001:db8::9/128      IP6 internal 140    rt3                  -         rt9(4)\r
+2001:db8::6/128      IP6 internal 150    rt3                  -         rt6(4)\r
+2001:db8::7/128      IP6 internal 150    rt3                  -         rt7(4)\r
+2001:db8::8/128      IP6 internal 150    rt3                  -         rt8(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::2/128  130     -          rt3      16031/19/16021  \r
+ 2001:db8::4/128  120     -          rt3      16031/19/16041  \r
+ 2001:db8::5/128  130     -          rt3      16031/19/16051  \r
+ 2001:db8::6/128  150     -          rt3      16031/19/16061  \r
+ 2001:db8::7/128  150     -          rt3      16031/19/16071  \r
+ 2001:db8::8/128  150     -          rt3      16031/19/16081  \r
+ 2001:db8::9/128  140     -          rt3      16031/19/16091  \r
+\r
+test# test isis topology 9 root rt9 ti-lfa system-id rt5\r
+P-space (self):\r
+ rt6\r
+ rt7\r
+ rt8\r
+\r
+P-space (rt6):\r
+ rt6\r
+\r
+P-space (rt7):\r
+ rt7\r
+\r
+P-space (rt8):\r
+ rt8\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt9                                                                   \r
+10.0.255.9/32        IP internal  0                                     rt9(4)\r
+rt6                  TE-IS        10     rt6                  -         rt9(4)\r
+rt7                  TE-IS        10     rt7                  -         rt9(4)\r
+rt8                  TE-IS        10     rt8                  -         rt9(4)\r
+10.0.255.6/32        IP TE        20     rt6                  -         rt6(4)\r
+10.0.255.7/32        IP TE        20     rt7                  -         rt7(4)\r
+10.0.255.8/32        IP TE        20     rt8                  -         rt8(4)\r
+rt4                  TE-IS        40     rt6                  -         rt6(4)\r
+                                         rt7                  -         rt7(4)\r
+                                         rt8                  -         rt8(4)\r
+rt2                  TE-IS        50     rt6                  -         rt4(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+rt5                  TE-IS        50     rt6                  -         rt4(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+10.0.255.4/32        IP TE        50     rt6                  -         rt4(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+rt1                  TE-IS        60     rt6                  -         rt2(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+10.0.255.2/32        IP TE        60     rt6                  -         rt2(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+10.0.255.5/32        IP TE        60     rt6                  -         rt5(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+rt3                  TE-IS        70     rt6                  -         rt1(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+10.0.255.1/32        IP TE        70     rt6                  -         rt1(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+10.0.255.3/32        IP TE        80     rt6                  -         rt3(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.1/32  70      -          rt6      16060/16/16010  \r
+                        -          rt7      16070/16/16010  \r
+                        -          rt8      16080/16/16010  \r
+ 10.0.255.2/32  60      -          rt6      16060/16/16020  \r
+                        -          rt7      16070/16/16020  \r
+                        -          rt8      16080/16/16020  \r
+ 10.0.255.3/32  80      -          rt6      16060/16/16030  \r
+                        -          rt7      16070/16/16030  \r
+                        -          rt8      16080/16/16030  \r
+ 10.0.255.4/32  50      -          rt6      16060/16/16040  \r
+                        -          rt7      16070/16/16040  \r
+                        -          rt8      16080/16/16040  \r
+ 10.0.255.5/32  60      -          rt6      16060/16/16050  \r
+                        -          rt7      16070/16/16050  \r
+                        -          rt8      16080/16/16050  \r
+\r
+P-space (self):\r
+ rt6\r
+ rt7\r
+ rt8\r
+\r
+P-space (rt6):\r
+ rt6\r
+\r
+P-space (rt7):\r
+ rt7\r
+\r
+P-space (rt8):\r
+ rt8\r
+\r
+Q-space:\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt9                                                                   \r
+2001:db8::9/128      IP6 internal 0                                     rt9(4)\r
+rt6                  TE-IS        10     rt6                  -         rt9(4)\r
+rt7                  TE-IS        10     rt7                  -         rt9(4)\r
+rt8                  TE-IS        10     rt8                  -         rt9(4)\r
+2001:db8::6/128      IP6 internal 20     rt6                  -         rt6(4)\r
+2001:db8::7/128      IP6 internal 20     rt7                  -         rt7(4)\r
+2001:db8::8/128      IP6 internal 20     rt8                  -         rt8(4)\r
+rt4                  TE-IS        40     rt6                  -         rt6(4)\r
+                                         rt7                  -         rt7(4)\r
+                                         rt8                  -         rt8(4)\r
+rt2                  TE-IS        50     rt6                  -         rt4(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+rt5                  TE-IS        50     rt6                  -         rt4(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+2001:db8::4/128      IP6 internal 50     rt6                  -         rt4(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+rt1                  TE-IS        60     rt6                  -         rt2(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+2001:db8::2/128      IP6 internal 60     rt6                  -         rt2(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+2001:db8::5/128      IP6 internal 60     rt6                  -         rt5(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+rt3                  TE-IS        70     rt6                  -         rt1(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+2001:db8::1/128      IP6 internal 70     rt6                  -         rt1(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+2001:db8::3/128      IP6 internal 80     rt6                  -         rt3(4)\r
+                                         rt7                  -         \r
+                                         rt8                  -         \r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::1/128  70      -          rt6      16061/17/16011  \r
+                          -          rt7      16071/17/16011  \r
+                          -          rt8      16081/17/16011  \r
+ 2001:db8::2/128  60      -          rt6      16061/17/16021  \r
+                          -          rt7      16071/17/16021  \r
+                          -          rt8      16081/17/16021  \r
+ 2001:db8::3/128  80      -          rt6      16061/17/16031  \r
+                          -          rt7      16071/17/16031  \r
+                          -          rt8      16081/17/16031  \r
+ 2001:db8::4/128  50      -          rt6      16061/17/16041  \r
+                          -          rt7      16071/17/16041  \r
+                          -          rt8      16081/17/16041  \r
+ 2001:db8::5/128  60      -          rt6      16061/17/16051  \r
+                          -          rt7      16071/17/16051  \r
+                          -          rt8      16081/17/16051  \r
+\r
+test# test isis topology 9 root rt9 ti-lfa system-id rt8\r
+P-space (self):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+\r
+P-space (rt5):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+\r
+P-space (rt6):\r
+ rt6\r
+\r
+P-space (rt7):\r
+ rt7\r
+\r
+Q-space:\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt9                                                                   \r
+10.0.255.9/32        IP internal  0                                     rt9(4)\r
+rt5                  TE-IS        10     rt5                  -         rt9(4)\r
+rt6                  TE-IS        10     rt6                  -         rt9(4)\r
+rt7                  TE-IS        10     rt7                  -         rt9(4)\r
+rt4                  TE-IS        20     rt5                  -         rt5(4)\r
+10.0.255.5/32        IP TE        20     rt5                  -         rt5(4)\r
+10.0.255.6/32        IP TE        20     rt6                  -         rt6(4)\r
+10.0.255.7/32        IP TE        20     rt7                  -         rt7(4)\r
+rt2                  TE-IS        30     rt5                  -         rt4(4)\r
+10.0.255.4/32        IP TE        30     rt5                  -         rt4(4)\r
+rt1                  TE-IS        40     rt5                  -         rt2(4)\r
+10.0.255.2/32        IP TE        40     rt5                  -         rt2(4)\r
+rt8                  TE-IS        50     rt5                  -         rt4(4)\r
+rt3                  TE-IS        50     rt5                  -         rt1(4)\r
+10.0.255.1/32        IP TE        50     rt5                  -         rt1(4)\r
+10.0.255.8/32        IP TE        60     rt5                  -         rt8(4)\r
+10.0.255.3/32        IP TE        60     rt5                  -         rt3(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.8/32  60      -          rt5      16040/26/16080  \r
+\r
+P-space (self):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+\r
+P-space (rt5):\r
+ rt1\r
+ rt2\r
+ rt3\r
+ rt4\r
+ rt5\r
+\r
+P-space (rt6):\r
+ rt6\r
+\r
+P-space (rt7):\r
+ rt7\r
+\r
+Q-space:\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt9                                                                   \r
+2001:db8::9/128      IP6 internal 0                                     rt9(4)\r
+rt5                  TE-IS        10     rt5                  -         rt9(4)\r
+rt6                  TE-IS        10     rt6                  -         rt9(4)\r
+rt7                  TE-IS        10     rt7                  -         rt9(4)\r
+rt4                  TE-IS        20     rt5                  -         rt5(4)\r
+2001:db8::5/128      IP6 internal 20     rt5                  -         rt5(4)\r
+2001:db8::6/128      IP6 internal 20     rt6                  -         rt6(4)\r
+2001:db8::7/128      IP6 internal 20     rt7                  -         rt7(4)\r
+rt2                  TE-IS        30     rt5                  -         rt4(4)\r
+2001:db8::4/128      IP6 internal 30     rt5                  -         rt4(4)\r
+rt1                  TE-IS        40     rt5                  -         rt2(4)\r
+2001:db8::2/128      IP6 internal 40     rt5                  -         rt2(4)\r
+rt8                  TE-IS        50     rt5                  -         rt4(4)\r
+rt3                  TE-IS        50     rt5                  -         rt1(4)\r
+2001:db8::1/128      IP6 internal 50     rt5                  -         rt1(4)\r
+2001:db8::8/128      IP6 internal 60     rt5                  -         rt8(4)\r
+2001:db8::3/128      IP6 internal 60     rt5                  -         rt3(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::8/128  60      -          rt5      16041/27/16081  \r
+\r
+test# test isis topology 10 root rt1 ti-lfa system-id rt2\r
+P-space (self):\r
+ rt3\r
+ rt4\r
+ rt6\r
+ rt7\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt6\r
+\r
+P-space (rt4):\r
+ rt4\r
+ rt7\r
+\r
+Q-space:\r
+ rt2\r
+ rt5\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt3                  TE-IS        20     rt3                  -         rt1(4)\r
+rt4                  TE-IS        20     rt4                  -         rt1(4)\r
+rt6                  TE-IS        30     rt3                  -         rt3(4)\r
+rt7                  TE-IS        30     rt4                  -         rt4(4)\r
+10.0.255.3/32        IP TE        30     rt3                  -         rt3(4)\r
+10.0.255.4/32        IP TE        30     rt4                  -         rt4(4)\r
+10.0.255.6/32        IP TE        40     rt3                  -         rt6(4)\r
+10.0.255.7/32        IP TE        40     rt4                  -         rt7(4)\r
+rt8                  TE-IS        80     rt3                  -         rt6(4)\r
+                                         rt4                  -         rt7(4)\r
+rt5                  TE-IS        90     rt3                  -         rt8(4)\r
+                                         rt4                  -         \r
+10.0.255.8/32        IP TE        90     rt3                  -         rt8(4)\r
+                                         rt4                  -         \r
+rt2                  TE-IS        100    rt3                  -         rt5(4)\r
+                                         rt4                  -         \r
+10.0.255.5/32        IP TE        100    rt3                  -         rt5(4)\r
+                                         rt4                  -         \r
+10.0.255.2/32        IP TE        110    rt3                  -         rt2(4)\r
+                                         rt4                  -         \r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.2/32  110     -          rt3      20060/18/16020  \r
+                        -          rt4      16070/18/16020  \r
+ 10.0.255.5/32  100     -          rt3      20060/18/16050  \r
+                        -          rt4      16070/18/16050  \r
+ 10.0.255.8/32  90      -          rt3      20060/18/16080  \r
+                        -          rt4      16070/18/16080  \r
+\r
+P-space (self):\r
+ rt3\r
+ rt4\r
+ rt6\r
+ rt7\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt6\r
+\r
+P-space (rt4):\r
+ rt4\r
+ rt7\r
+\r
+Q-space:\r
+ rt2\r
+ rt5\r
+ rt8\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt3                  TE-IS        20     rt3                  -         rt1(4)\r
+rt4                  TE-IS        20     rt4                  -         rt1(4)\r
+rt6                  TE-IS        30     rt3                  -         rt3(4)\r
+rt7                  TE-IS        30     rt4                  -         rt4(4)\r
+2001:db8::3/128      IP6 internal 30     rt3                  -         rt3(4)\r
+2001:db8::4/128      IP6 internal 30     rt4                  -         rt4(4)\r
+2001:db8::6/128      IP6 internal 40     rt3                  -         rt6(4)\r
+2001:db8::7/128      IP6 internal 40     rt4                  -         rt7(4)\r
+rt8                  TE-IS        80     rt3                  -         rt6(4)\r
+                                         rt4                  -         rt7(4)\r
+rt5                  TE-IS        90     rt3                  -         rt8(4)\r
+                                         rt4                  -         \r
+2001:db8::8/128      IP6 internal 90     rt3                  -         rt8(4)\r
+                                         rt4                  -         \r
+rt2                  TE-IS        100    rt3                  -         rt5(4)\r
+                                         rt4                  -         \r
+2001:db8::5/128      IP6 internal 100    rt3                  -         rt5(4)\r
+                                         rt4                  -         \r
+2001:db8::2/128      IP6 internal 110    rt3                  -         rt2(4)\r
+                                         rt4                  -         \r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::2/128  110     -          rt3      20061/19/16021  \r
+                          -          rt4      16071/19/16021  \r
+ 2001:db8::5/128  100     -          rt3      20061/19/16051  \r
+                          -          rt4      16071/19/16051  \r
+ 2001:db8::8/128  90      -          rt3      20061/19/16081  \r
+                          -          rt4      16071/19/16081  \r
+\r
+test# test isis topology 10 root rt1 ti-lfa system-id rt4\r
+P-space (self):\r
+ rt2\r
+ rt3\r
+ rt5\r
+ rt6\r
+ rt8\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt5\r
+ rt8\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt6\r
+\r
+Q-space:\r
+ rt4\r
+ rt7\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt2                  TE-IS        10     rt2                  -         rt1(4)\r
+rt3                  TE-IS        20     rt3                  -         rt1(4)\r
+rt5                  TE-IS        20     rt2                  -         rt2(4)\r
+10.0.255.2/32        IP TE        20     rt2                  -         rt2(4)\r
+rt6                  TE-IS        30     rt3                  -         rt3(4)\r
+rt8                  TE-IS        30     rt2                  -         rt5(4)\r
+10.0.255.3/32        IP TE        30     rt3                  -         rt3(4)\r
+10.0.255.5/32        IP TE        30     rt2                  -         rt5(4)\r
+10.0.255.6/32        IP TE        40     rt3                  -         rt6(4)\r
+10.0.255.8/32        IP TE        40     rt2                  -         rt8(4)\r
+rt7                  TE-IS        80     rt2                  -         rt8(4)\r
+rt4                  TE-IS        90     rt2                  -         rt7(4)\r
+10.0.255.7/32        IP TE        90     rt2                  -         rt7(4)\r
+10.0.255.4/32        IP TE        100    rt2                  -         rt4(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)        \r
+ -----------------------------------------------------------\r
+ 10.0.255.4/32  100     -          rt2      16080/20/16040  \r
+ 10.0.255.7/32  90      -          rt2      16080/20/16070  \r
+\r
+P-space (self):\r
+ rt2\r
+ rt3\r
+ rt5\r
+ rt6\r
+ rt8\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt5\r
+ rt8\r
+\r
+P-space (rt3):\r
+ rt3\r
+ rt6\r
+\r
+Q-space:\r
+ rt4\r
+ rt7\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+2001:db8::1/128      IP6 internal 0                                     rt1(4)\r
+rt2                  TE-IS        10     rt2                  -         rt1(4)\r
+rt3                  TE-IS        20     rt3                  -         rt1(4)\r
+rt5                  TE-IS        20     rt2                  -         rt2(4)\r
+2001:db8::2/128      IP6 internal 20     rt2                  -         rt2(4)\r
+rt6                  TE-IS        30     rt3                  -         rt3(4)\r
+rt8                  TE-IS        30     rt2                  -         rt5(4)\r
+2001:db8::3/128      IP6 internal 30     rt3                  -         rt3(4)\r
+2001:db8::5/128      IP6 internal 30     rt2                  -         rt5(4)\r
+2001:db8::6/128      IP6 internal 40     rt3                  -         rt6(4)\r
+2001:db8::8/128      IP6 internal 40     rt2                  -         rt8(4)\r
+rt7                  TE-IS        80     rt2                  -         rt8(4)\r
+rt4                  TE-IS        90     rt2                  -         rt7(4)\r
+2001:db8::7/128      IP6 internal 90     rt2                  -         rt7(4)\r
+2001:db8::4/128      IP6 internal 100    rt2                  -         rt4(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)        \r
+ -------------------------------------------------------------\r
+ 2001:db8::4/128  100     -          rt2      16081/21/16041  \r
+ 2001:db8::7/128  90      -          rt2      16081/21/16071  \r
+\r
+test# test isis topology 11 root rt2 ti-lfa system-id rt4\r
+P-space (self):\r
+\r
+P-space (rt1):\r
+ rt1\r
+ rt3\r
+ rt5\r
+\r
+P-space (rt3):\r
+ rt1\r
+ rt3\r
+ rt5\r
+ rt6\r
+\r
+Q-space:\r
+ rt1\r
+ rt3\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt2                                                                   \r
+10.0.255.2/32        IP internal  0                                     rt2(4)\r
+rt1                  TE-IS        50     rt1                  -         rt2(4)\r
+rt3                  TE-IS        50     rt3                  -         rt2(4)\r
+rt2                                                                   \r
+rt5                  TE-IS        60     rt3                  -         rt3(4)\r
+10.0.255.1/32        IP TE        60     rt1                  -         rt1(4)\r
+10.0.255.3/32        IP TE        60     rt3                  -         rt3(4)\r
+rt4                  TE-IS        70     rt3                  -         rt5(4)\r
+rt6                  TE-IS        70     rt3                  -         rt5(4)\r
+10.0.255.5/32        IP TE        70     rt3                  -         rt5(4)\r
+10.0.255.4/32        IP TE        80     rt3                  -         rt4(4)\r
+10.0.255.6/32        IP TE        80     rt3                  -         rt6(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)       \r
+ ----------------------------------------------------------\r
+ 10.0.255.1/32  60      -          rt1      implicit-null  \r
+ 10.0.255.3/32  60      -          rt3      implicit-null  \r
+ 10.0.255.4/32  80      -          rt3      16050/16040    \r
+ 10.0.255.5/32  70      -          rt3      16050          \r
+ 10.0.255.6/32  80      -          rt3      16060          \r
+\r
+P-space (self):\r
+\r
+P-space (rt1):\r
+ rt1\r
+ rt3\r
+ rt5\r
+\r
+P-space (rt3):\r
+ rt1\r
+ rt3\r
+ rt5\r
+ rt6\r
+\r
+Q-space:\r
+ rt1\r
+ rt3\r
+ rt4\r
+ rt5\r
+ rt6\r
+\r
+IS-IS paths to level-1 routers that speak IPv6\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt2                                                                   \r
+2001:db8::2/128      IP6 internal 0                                     rt2(4)\r
+rt1                  TE-IS        50     rt1                  -         rt2(4)\r
+rt3                  TE-IS        50     rt3                  -         rt2(4)\r
+rt2                                                                   \r
+rt5                  TE-IS        60     rt3                  -         rt3(4)\r
+2001:db8::1/128      IP6 internal 60     rt1                  -         rt1(4)\r
+2001:db8::3/128      IP6 internal 60     rt3                  -         rt3(4)\r
+rt4                  TE-IS        70     rt3                  -         rt5(4)\r
+rt6                  TE-IS        70     rt3                  -         rt5(4)\r
+2001:db8::5/128      IP6 internal 70     rt3                  -         rt5(4)\r
+2001:db8::4/128      IP6 internal 80     rt3                  -         rt4(4)\r
+2001:db8::6/128      IP6 internal 80     rt3                  -         rt6(4)\r
+\r
+IS-IS L1 IPv6 routing table:\r
+\r
+ Prefix           Metric  Interface  Nexthop  Label(s)       \r
+ ------------------------------------------------------------\r
+ 2001:db8::1/128  60      -          rt1      implicit-null  \r
+ 2001:db8::3/128  60      -          rt3      implicit-null  \r
+ 2001:db8::4/128  80      -          rt3      16051/16041    \r
+ 2001:db8::5/128  70      -          rt3      16051          \r
+ 2001:db8::6/128  80      -          rt3      16061          \r
+\r
+test# test isis topology 12 root rt1 ti-lfa system-id rt3 ipv4-only\r
+P-space (self):\r
+ rt2\r
+ rt4\r
+ rt6\r
+ rt8\r
+ rt10\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt4\r
+ rt6\r
+ rt8\r
+ rt10\r
+\r
+Q-space:\r
+ rt3\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt2                  TE-IS        10     rt2                  -         rt1(4)\r
+rt4                  TE-IS        20     rt2                  -         rt2(4)\r
+10.0.255.2/32        IP TE        20     rt2                  -         rt2(4)\r
+rt6                  TE-IS        30     rt2                  -         rt4(4)\r
+10.0.255.4/32        IP TE        30     rt2                  -         rt4(4)\r
+rt8                  TE-IS        40     rt2                  -         rt6(4)\r
+10.0.255.6/32        IP TE        40     rt2                  -         rt6(4)\r
+rt10                 TE-IS        50     rt2                  -         rt8(4)\r
+10.0.255.8/32        IP TE        50     rt2                  -         rt8(4)\r
+10.0.255.10/32       IP TE        60     rt2                  -         rt10(4)\r
+rt7                  TE-IS        140    rt2                  -         rt8(4)\r
+rt9                  TE-IS        150    rt2                  -         rt7(4)\r
+10.0.255.7/32        IP TE        150    rt2                  -         rt7(4)\r
+10.0.255.9/32        IP TE        160    rt2                  -         rt9(4)\r
+rt5                  TE-IS        340    rt2                  -         rt7(4)\r
+10.0.255.5/32        IP TE        350    rt2                  -         rt5(4)\r
+rt3                  TE-IS        740    rt2                  -         rt5(4)\r
+10.0.255.3/32        IP TE        750    rt2                  -         rt3(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)              \r
+ -----------------------------------------------------------------\r
+ 10.0.255.3/32  750     -          rt2      16080/17/16/16/16030  \r
+ 10.0.255.5/32  350     -          rt2      16080/17/16/16050     \r
+ 10.0.255.7/32  150     -          rt2      16080/17/16070        \r
+ 10.0.255.9/32  160     -          rt2      16080/17/18/16090     \r
+\r
+test# test isis topology 13 root rt1 ti-lfa system-id rt3 ipv4-only\r
+P-space (self):\r
+ rt2\r
+\r
+P-space (rt2):\r
+ rt2\r
+ rt4\r
+\r
+Q-space:\r
+ rt3\r
+ rt4\r
+ rt5\r
+ rt6\r
+ rt7\r
+\r
+IS-IS paths to level-1 routers that speak IP\r
+Vertex               Type         Metric Next-Hop             Interface Parent\r
+rt1                                                                   \r
+10.0.255.1/32        IP internal  0                                     rt1(4)\r
+rt2                  TE-IS        10     rt2                  -         rt1(4)\r
+rt4                  TE-IS        20     rt2                  -         rt2(4)\r
+10.0.255.2/32        IP TE        20     rt2                  -         rt2(4)\r
+rt3                  TE-IS        30     rt2                  -         rt4(4)\r
+10.0.255.4/32        IP TE        30     rt2                  -         rt4(4)\r
+rt5                  TE-IS        40     rt2                  -         rt3(4)\r
+rt6                  TE-IS        40     rt2                  -         rt3(4)\r
+10.0.255.3/32        IP TE        40     rt2                  -         rt3(4)\r
+rt7                  TE-IS        50     rt2                  -         rt5(4)\r
+                                                                        rt6(4)\r
+10.0.255.5/32        IP TE        50     rt2                  -         rt5(4)\r
+10.0.255.6/32        IP TE        50     rt2                  -         rt6(4)\r
+10.0.255.7/32        IP TE        60     rt2                  -         rt7(4)\r
+\r
+IS-IS L1 IPv4 routing table:\r
+\r
+ Prefix         Metric  Interface  Nexthop  Label(s)     \r
+ --------------------------------------------------------\r
+ 10.0.255.3/32  40      -          rt2      16040/16030  \r
+ 10.0.255.5/32  50      -          rt2      16040/16050  \r
+ 10.0.255.6/32  50      -          rt2      16040/16060  \r
+ 10.0.255.7/32  60      -          rt2      16040/16070  \r
 \r
 test# 
 end.
index 5974edecc9d221f4030225d03811e2dca3c2804f..b9d2fc5fa2fd9d4ece37fb8444a1d81031735644 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestIsisVertexQueue(frrtest.TestMultiOut):
-    program = './test_isis_vertex_queue'
+    program = "./test_isis_vertex_queue"
+
 
 TestIsisVertexQueue.exit_cleanly()
index 8f062d8b5efdf916f3ae90160641bfc692f165d3..8dba1e29f08ba1c922b3b500073f44a6f5fa2618 100644 (file)
@@ -47,12 +47,10 @@ DEFPY(magic_test, magic_test_cmd,
        "magic (0-100) {ipv4net A.B.C.D/M|X:X::X:X$ipv6}",
        "1\n2\n3\n4\n5\n")
 {
-       char buf[256];
        vty_out(vty, "def: %s\n", self->string);
        vty_out(vty, "num: %ld\n", magic);
-       vty_out(vty, "ipv4: %s\n", prefix2str(ipv4net, buf, sizeof(buf)));
-       vty_out(vty, "ipv6: %s\n",
-               inet_ntop(AF_INET6, &ipv6, buf, sizeof(buf)));
+       vty_out(vty, "ipv4: %pFX\n", ipv4net);
+       vty_out(vty, "ipv6: %pI6\n", &ipv6);
        return CMD_SUCCESS;
 }
 
index 7371db283ac3a3d3a2bd7aae01d287044e54f349..6fdd6faa65fb1803c67528013e72a849b47f3397 100644 (file)
@@ -1,5 +1,6 @@
 import frrtest
 
+
 class TestCli(frrtest.TestRefOut):
-    program = './test_cli'
+    program = "./test_cli"
     built_refout = True
index d55345186a2f18f1b5a7299a2c916d3096a004ae..cf99077c3566f45a1718d5cee1add8d3d59f5801 100644 (file)
@@ -2,10 +2,12 @@ import frrtest
 import pytest
 import os
 
+
 class TestCommands(frrtest.TestRefOut):
-    program = './test_commands'
+    program = "./test_commands"
 
-    @pytest.mark.skipif('QUAGGA_TEST_COMMANDS' not in os.environ,
-                        reason='QUAGGA_TEST_COMMANDS not set')
+    @pytest.mark.skipif(
+        "QUAGGA_TEST_COMMANDS" not in os.environ, reason="QUAGGA_TEST_COMMANDS not set"
+    )
     def test_refout(self):
         return super(TestCommands, self).test_refout()
index 8f5fdd6fd0655722435acf2225c07ee48c364add..a02bf05c1a38c56d2e34f1b28dd257c6dbc68d1c 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestNbOperData(frrtest.TestRefOut):
-    program = './test_oper_data'
+    program = "./test_oper_data"
index 293d47f31663321b8a6454cdd2fa12d80ed913af..719a2e791d76a3c7164da1a364edaf00d1c6f7a6 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestAtomlist(frrtest.TestMultiOut):
-    program = './test_atomlist'
+    program = "./test_atomlist"
+
 
 TestAtomlist.exit_cleanly()
index 697e56c149733d2a0c63820bad10c951a5b3256c..b26986c83c5dee3c45351743fef6eee5f99980a5 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestGraph(frrtest.TestRefOut):
-    program = './test_graph'
+    program = "./test_graph"
index 22de082be40c25c5f9b21f88c2ba61b7033ce0fa..e2186dc521a631da9f4c06c71ce77d15bfd93d00 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestIDAlloc(frrtest.TestMultiOut):
-    program = './test_idalloc'
+    program = "./test_idalloc"
+
 
-TestIDAlloc.onesimple('ID Allocator test successful.')
+TestIDAlloc.onesimple("ID Allocator test successful.")
index bb330a1c752722e2067128a42e3307cf8144d8fb..0c39dce08e2639d2b8e9721a52545154b1694858 100644 (file)
@@ -1,7 +1,9 @@
 import frrtest
 
+
 class TestNexthopIter(frrtest.TestMultiOut):
-    program = './test_nexthop_iter'
+    program = "./test_nexthop_iter"
+
 
-TestNexthopIter.onesimple('Simple test passed.')
-TestNexthopIter.onesimple('PRNG test passed.')
+TestNexthopIter.onesimple("Simple test passed.")
+TestNexthopIter.onesimple("PRNG test passed.")
index 2526f53db5499d8acd2c5e3eeeed0e0e198838b8..69c43536203da23bce987c8baf85cd4c357111e7 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestNtop(frrtest.TestMultiOut):
-    program = './test_ntop'
+    program = "./test_ntop"
+
 
 TestNtop.exit_cleanly()
index 6e26d1b409653791a629a5d4a39a1a832378ee2e..fd883ed530a18428f1365874fc4720427975ae10 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestPrefix2str(frrtest.TestMultiOut):
-    program = './test_prefix2str'
+    program = "./test_prefix2str"
+
 
 TestPrefix2str.exit_cleanly()
index 4fe238618ed96bd5b8db6b4b94efb3133f0bcef4..b8ab89e337d8f4b5bdb5c069d458c78db7355d04 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestPrintfrr(frrtest.TestMultiOut):
-    program = './test_printfrr'
+    program = "./test_printfrr"
+
 
 TestPrintfrr.exit_cleanly()
index 5d994ddd7bdb6469e77beba1c5de7bac467211cc..0cd9dee2b7257d0348ccba6ee95052b23c064f30 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestRingbuf(frrtest.TestMultiOut):
-    program = './test_ringbuf'
+    program = "./test_ringbuf"
+
 
 TestRingbuf.exit_cleanly()
index dbfe8533655af1bce207e6cf6e877b060828b2f3..097da113ab0e712f4e3c4b84e5d85810b5c66403 100644 (file)
@@ -271,7 +271,7 @@ static void test_state_verify(struct test_state *test)
                                                       associated with rn */
                                expected_lock++;
 
-                       if (rn->lock != expected_lock)
+                       if (route_node_get_lock_count(rn) != expected_lock)
                                test_failed(
                                        test,
                                        "Dest rnode lock count doesn't match expected count!",
@@ -283,7 +283,7 @@ static void test_state_verify(struct test_state *test)
                            != NULL) /* The route node is not internal */
                                expected_lock++;
 
-                       if (rn->lock != expected_lock) {
+                       if (route_node_get_lock_count(rn) != expected_lock) {
                                srcdest_rnode_prefixes(
                                        rn, (const struct prefix **)&dst_p,
                                        (const struct prefix **)&src_p);
index ee73121025da18c079034f751525cae565625eac..d0dde6a8e5d8e532a45d2e503829730d31eb55b4 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestSrcdestTable(frrtest.TestMultiOut):
-    program = './test_srcdest_table'
+    program = "./test_srcdest_table"
+
 
-TestSrcdestTable.onesimple('PRNG Test successful.')
+TestSrcdestTable.onesimple("PRNG Test successful.")
index 6f42db18390b4c82de09e2c6afc29d4cd8db6fe6..11d902eb95f75783a0f7c07e95b0ba80e5fbe264 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestStream(frrtest.TestRefOut):
-    program = './test_stream'
+    program = "./test_stream"
index 90d6c76bf1c26a9f7c3402a759a6eb89b37e2988..290657bd562ea186540a4cce9e5a38eeb9099c59 100644 (file)
@@ -104,7 +104,6 @@ static void add_nodes(struct route_table *table, ...)
 static void print_subtree(struct route_node *rn, const char *legend,
                          int indent_level)
 {
-       char buf[PREFIX2STR_BUFFER];
        int i;
 
        /*
@@ -114,8 +113,7 @@ static void print_subtree(struct route_node *rn, const char *legend,
                printf("  ");
        }
 
-       prefix2str(&rn->p, buf, sizeof(buf));
-       printf("%s: %s", legend, buf);
+       printf("%s: %pFX", legend, &rn->p);
        if (!rn->info) {
                printf(" (internal)");
        }
index e72442127336e10acb9e878f71b9b37e4a5b0b81..ee1849fd8654c89c9f7d3e658b4168fb64aa07e6 100644 (file)
@@ -1,10 +1,12 @@
 import frrtest
 
+
 class TestTable(frrtest.TestMultiOut):
-    program = './test_table'
+    program = "./test_table"
+
 
 for i in range(6):
-    TestTable.onesimple('Verifying cmp')
+    TestTable.onesimple("Verifying cmp")
 for i in range(11):
-    TestTable.onesimple('Verifying successor')
-TestTable.onesimple('Verified pausing')
+    TestTable.onesimple("Verifying successor")
+TestTable.onesimple("Verified pausing")
index cbf9b05546d1d733a438e4630cfdab21ccb0a7e5..416ea39772796de470433d07da968f85467e45f7 100644 (file)
@@ -153,7 +153,7 @@ int main(int argc, char **argv)
                        continue;
 
                XFREE(MTYPE_TMP, timers[index]->arg);
-               thread_cancel(timers[index]);
+               thread_cancel(&timers[index]);
                timers[index] = NULL;
                timers_pending--;
        }
index 8b4a765a81bb3a669f9d2609c739fbca63117767..71f45f980c46a22480965fc3e944427b4cd34e94 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestTimerCorrectness(frrtest.TestMultiOut):
-    program = './test_timer_correctness'
+    program = "./test_timer_correctness"
+
 
-TestTimerCorrectness.onesimple('Expected output and actual output match.')
+TestTimerCorrectness.onesimple("Expected output and actual output match.")
index 2960e0d81e2382e081bb9578ecae58cd5d590260..45b29b92b1ec30204afc9351ee5c2a1610bde310 100644 (file)
@@ -59,7 +59,7 @@ int main(int argc, char **argv)
                thread_add_timer_msec(master, dummy_func, NULL, 0, &timers[i]);
        }
        for (i = 0; i < SCHEDULE_TIMERS; i++)
-               thread_cancel(timers[i]);
+               thread_cancel(&timers[i]);
 
        monotime(&tv_start);
 
@@ -78,8 +78,7 @@ int main(int argc, char **argv)
                int index;
 
                index = prng_rand(prng) % SCHEDULE_TIMERS;
-               if (timers[index])
-                       thread_cancel(timers[index]);
+               thread_cancel(&timers[index]);
                timers[index] = NULL;
        }
 
index 1d93932ad2976e9f9dba42a2d441421436344a3d..9151181a7281580fc4c4d0b7190064c606051b6e 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestTTable(frrtest.TestRefOut):
-    program = './test_ttable'
+    program = "./test_ttable"
index 0b3c74397195e69d3dc8dd510d7c2fefcc6255cd..fe3499cad834fe89fae97a71167c0a9c4114b99a 100644 (file)
@@ -1,19 +1,21 @@
 import frrtest
 
+
 class TestTypelist(frrtest.TestMultiOut):
-    program = './test_typelist'
+    program = "./test_typelist"
+
 
-TestTypelist.onesimple('LIST end')
-TestTypelist.onesimple('DLIST end')
-TestTypelist.onesimple('ATOMLIST end')
-TestTypelist.onesimple('HEAP end')
-TestTypelist.onesimple('SORTLIST_UNIQ end')
-TestTypelist.onesimple('SORTLIST_NONUNIQ end')
-TestTypelist.onesimple('HASH end')
-TestTypelist.onesimple('HASH_collisions end')
-TestTypelist.onesimple('SKIPLIST_UNIQ end')
-TestTypelist.onesimple('SKIPLIST_NONUNIQ end')
-TestTypelist.onesimple('RBTREE_UNIQ end')
-TestTypelist.onesimple('RBTREE_NONUNIQ end')
-TestTypelist.onesimple('ATOMSORT_UNIQ end')
-TestTypelist.onesimple('ATOMSORT_NONUNIQ end')
+TestTypelist.onesimple("LIST end")
+TestTypelist.onesimple("DLIST end")
+TestTypelist.onesimple("ATOMLIST end")
+TestTypelist.onesimple("HEAP end")
+TestTypelist.onesimple("SORTLIST_UNIQ end")
+TestTypelist.onesimple("SORTLIST_NONUNIQ end")
+TestTypelist.onesimple("HASH end")
+TestTypelist.onesimple("HASH_collisions end")
+TestTypelist.onesimple("SKIPLIST_UNIQ end")
+TestTypelist.onesimple("SKIPLIST_NONUNIQ end")
+TestTypelist.onesimple("RBTREE_UNIQ end")
+TestTypelist.onesimple("RBTREE_NONUNIQ end")
+TestTypelist.onesimple("ATOMSORT_UNIQ end")
+TestTypelist.onesimple("ATOMSORT_NONUNIQ end")
index 099075700046fd4f9b991b1c511e3b1d2df320fb..8ded53bd58f35f4e3315b29e026cfa11aca0abcc 100644 (file)
@@ -1,6 +1,8 @@
 import frrtest
 
+
 class TestVersionCmp(frrtest.TestMultiOut):
-    program = './test_versioncmp'
+    program = "./test_versioncmp"
+
 
 TestVersionCmp.exit_cleanly()
index 2ca25858868a1e688ee9d4364d88f1eff952ce20..2a2d54e20464bc3632d18d93433f2cef251641a1 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestZlog(frrtest.TestMultiOut):
-    program = './test_zlog'
+    program = "./test_zlog"
index 1f8ee541695ba8584e60f0a081e3341cf15b4bfc..5f6189d919d9f3105509f2b0c96336f3b0df193e 100644 (file)
@@ -2,10 +2,13 @@ import frrtest
 import pytest
 import os
 
+
 class TestZMQ(frrtest.TestRefOut):
-    program = './test_zmq'
+    program = "./test_zmq"
 
-    @pytest.mark.skipif('S["ZEROMQ_TRUE"]=""\n' not in open('../config.status').readlines(),
-                        reason='ZEROMQ not enabled')
+    @pytest.mark.skipif(
+        'S["ZEROMQ_TRUE"]=""\n' not in open("../config.status").readlines(),
+        reason="ZEROMQ not enabled",
+    )
     def test_refout(self):
         return super(TestZMQ, self).test_refout()
index 24821febe6be0ef4065efcc16f7cf87b3d430154..c5bdcd3d1342bc3cc0ed36ac75beeb546bde1b22 100644 (file)
@@ -134,9 +134,10 @@ DEFPY(lsdb_walk, lsdb_walk_cmd,
       "LSDB\n"
       "walk entries\n")
 {
-       struct ospf6_lsa *lsa;
+       struct ospf6_lsa *lsa, *lsanext;
+
        unsigned cnt = 0;
-       for (ALL_LSDB(lsdb, lsa)) {
+       for (ALL_LSDB(lsdb, lsa, lsanext)) {
                lsa_show_oneline(vty, lsa);
                cnt++;
        }
index 6a9439511373766b50cae4c033a09d4166eaea96..6ada6176571e91b2d8bd8260d4a049fe26aafc56 100644 (file)
@@ -1,4 +1,5 @@
 import frrtest
 
+
 class TestLSDB(frrtest.TestRefOut):
-    program = './test_lsdb'
+    program = "./test_lsdb"
index 533dc6b167c9add7caf7ff385e4ae1c4a1cd0624..4677796152d7995ce1d31797285fd2dbba6d865f 100644 (file)
@@ -2,5 +2,5 @@ import pytest
 import sys
 import os
 
-sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers','python'))
+sys.path.append(os.path.join(os.path.dirname(__file__), "helpers", "python"))
 raise SystemExit(pytest.main(sys.argv[1:]))
index d7318efc721cf04e403077247bfa9ddabb4f7ccf..211814c1c33b4956e9bd5c50d1b86fda5940e4f4 100644 (file)
@@ -168,6 +168,19 @@ tests_bgpd_test_peer_attr_CFLAGS = $(TESTS_CFLAGS)
 tests_bgpd_test_peer_attr_CPPFLAGS = $(TESTS_CPPFLAGS)
 tests_bgpd_test_peer_attr_LDADD = $(BGP_TEST_LDADD)
 tests_bgpd_test_peer_attr_SOURCES = tests/bgpd/test_peer_attr.c
+nodist_tests_bgpd_test_peer_attr_SOURCES = \
+    yang/frr-bgp-types.yang.c \
+    yang/frr-bgp.yang.c \
+    yang/frr-bgp-common-structure.yang.c \
+    yang/frr-bgp-common.yang.c \
+    yang/frr-bgp-common-multiprotocol.yang.c \
+    yang/frr-bgp-neighbor.yang.c \
+    yang/frr-bgp-peer-group.yang.c \
+    yang/frr-bgp-bmp.yang.c \
+    yang/frr-bgp-rpki.yang.c \
+    yang/frr-deviations-bgp-datacenter.yang.c \
+    # end
+
 
 tests_isisd_test_fuzz_isis_tlv_CFLAGS = $(TESTS_CFLAGS) -I$(top_builddir)/tests/isisd
 tests_isisd_test_fuzz_isis_tlv_CPPFLAGS = $(TESTS_CPPFLAGS) -I$(top_builddir)/tests/isisd
index 4b57928366b3dfbf735bf085d8dc93937825c841..0254ff6af6a404aeb5db17b5cc39702455669c53 100644 (file)
@@ -55,6 +55,7 @@ fatal_error = ""
 ##
 #####################################################
 
+
 class NetworkTopo(Topo):
     "All Protocol Startup Test"
 
@@ -64,15 +65,15 @@ class NetworkTopo(Topo):
         router = {}
         #
         # Setup Main Router
-        router[1] = topotest.addRouter(self, 'r1')
+        router[1] = topotest.addRouter(self, "r1")
         #
 
         # Setup Switches
         switch = {}
         #
         for i in range(0, 10):
-            switch[i] = self.addSwitch('sw%s' % i, cls=topotest.LegacySwitch)
-            self.addLink(switch[i], router[1], intfName2='r1-eth%s' % i )
+            switch[i] = self.addSwitch("sw%s" % i, cls=topotest.LegacySwitch)
+            self.addLink(switch[i], router[1], intfName2="r1-eth%s" % i)
 
 
 #####################################################
@@ -81,6 +82,7 @@ class NetworkTopo(Topo):
 ##
 #####################################################
 
+
 def setup_module(module):
     global topo, net
     global fatal_error
@@ -89,8 +91,8 @@ def setup_module(module):
     print("******************************************\n")
 
     print("Cleanup old Mininet runs")
-    os.system('sudo mn -c > /dev/null 2>&1')
-    os.system('sudo rm /tmp/r* > /dev/null 2>&1')
+    os.system("sudo mn -c > /dev/null 2>&1")
+    os.system("sudo rm /tmp/r* > /dev/null 2>&1")
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
     topo = NetworkTopo()
@@ -98,33 +100,35 @@ def setup_module(module):
     net = Mininet(controller=None, topo=topo)
     net.start()
 
-    if net['r1'].get_routertype() != 'frr':
+    if net["r1"].get_routertype() != "frr":
         fatal_error = "Test is only implemented for FRR"
-        sys.stderr.write('\n\nTest is only implemented for FRR - Skipping\n\n')
+        sys.stderr.write("\n\nTest is only implemented for FRR - Skipping\n\n")
         pytest.skip(fatal_error)
-        
+
     # Starting Routers
     #
     # Main router
     for i in range(1, 2):
-        net['r%s' % i].loadConf('zebra', '%s/r%s/zebra.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('ripd', '%s/r%s/ripd.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('ripngd', '%s/r%s/ripngd.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('ospfd', '%s/r%s/ospfd.conf' % (thisDir, i))
-        if net['r1'].checkRouterVersion('<', '4.0'):
-            net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf-pre-v4' % (thisDir, i))
+        net["r%s" % i].loadConf("zebra", "%s/r%s/zebra.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("ripd", "%s/r%s/ripd.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("ripngd", "%s/r%s/ripngd.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("ospfd", "%s/r%s/ospfd.conf" % (thisDir, i))
+        if net["r1"].checkRouterVersion("<", "4.0"):
+            net["r%s" % i].loadConf(
+                "ospf6d", "%s/r%s/ospf6d.conf-pre-v4" % (thisDir, i)
+            )
         else:
-            net['r%s' % i].loadConf('ospf6d', '%s/r%s/ospf6d.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('isisd', '%s/r%s/isisd.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('bgpd', '%s/r%s/bgpd.conf' % (thisDir, i))
-        if net['r%s' % i].daemon_available('ldpd'):
+            net["r%s" % i].loadConf("ospf6d", "%s/r%s/ospf6d.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("isisd", "%s/r%s/isisd.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("bgpd", "%s/r%s/bgpd.conf" % (thisDir, i))
+        if net["r%s" % i].daemon_available("ldpd"):
             # Only test LDPd if it's installed and Kernel >= 4.5
-            net['r%s' % i].loadConf('ldpd', '%s/r%s/ldpd.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('sharpd')
-        net['r%s' % i].loadConf('nhrpd', '%s/r%s/nhrpd.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('babeld', '%s/r%s/babeld.conf' % (thisDir, i))
-        net['r%s' % i].loadConf('pbrd', '%s/r%s/pbrd.conf' % (thisDir, i))
-        net['r%s' % i].startRouter()
+            net["r%s" % i].loadConf("ldpd", "%s/r%s/ldpd.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("sharpd")
+        net["r%s" % i].loadConf("nhrpd", "%s/r%s/nhrpd.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("babeld", "%s/r%s/babeld.conf" % (thisDir, i))
+        net["r%s" % i].loadConf("pbrd", "%s/r%s/pbrd.conf" % (thisDir, i))
+        net["r%s" % i].startRouter()
 
     # For debugging after starting FRR daemons, uncomment the next line
     # CLI(net)
@@ -145,7 +149,7 @@ def test_router_running():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Check if FRR is running on each Router node")
@@ -154,7 +158,7 @@ def test_router_running():
 
     # Starting Routers
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -166,7 +170,7 @@ def test_error_messages_vtysh():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Check for error messages on VTYSH")
@@ -179,38 +183,38 @@ def test_error_messages_vtysh():
         #
 
         # VTYSH output from router
-        vtystdout = net['r%s' % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
+        vtystdout = net["r%s" % i].cmd('vtysh -c "show version" 2> /dev/null').rstrip()
 
         # Fix newlines (make them all the same)
-        vtystdout = ('\n'.join(vtystdout.splitlines()) + '\n').rstrip()
+        vtystdout = ("\n".join(vtystdout.splitlines()) + "\n").rstrip()
         # Drop everything starting with "FRRouting X.xx" message
         vtystdout = re.sub(r"FRRouting [0-9]+.*", "", vtystdout, flags=re.DOTALL)
 
-        if (vtystdout == ''):
+        if vtystdout == "":
             print("r%s StdOut ok" % i)
 
-        assert vtystdout == '', "Vtysh StdOut Output check failed for router r%s" % i
+        assert vtystdout == "", "Vtysh StdOut Output check failed for router r%s" % i
 
         #
         # Second checking Standard Error
         #
 
         # VTYSH StdErr output from router
-        vtystderr = net['r%s' % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
+        vtystderr = net["r%s" % i].cmd('vtysh -c "show version" > /dev/null').rstrip()
 
         # Fix newlines (make them all the same)
-        vtystderr = ('\n'.join(vtystderr.splitlines()) + '\n').rstrip()
+        vtystderr = ("\n".join(vtystderr.splitlines()) + "\n").rstrip()
         # # Drop everything starting with "FRRouting X.xx" message
-        # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL) 
+        # vtystderr = re.sub(r"FRRouting [0-9]+.*", "", vtystderr, flags=re.DOTALL)
 
-        if (vtystderr == ''):
+        if vtystderr == "":
             print("r%s StdErr ok" % i)
 
-        assert vtystderr == '', "Vtysh StdErr Output check failed for router r%s" % i
+        assert vtystderr == "", "Vtysh StdErr Output check failed for router r%s" % i
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -222,7 +226,7 @@ def test_error_messages_daemons():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Check for error messages in daemons")
@@ -231,67 +235,73 @@ def test_error_messages_daemons():
     error_logs = ""
 
     for i in range(1, 2):
-        log = net['r%s' % i].getStdErr('ripd')
+        log = net["r%s" % i].getStdErr("ripd")
         if log:
             error_logs += "r%s RIPd StdErr Output:\n" % i
             error_logs += log
-        log = net['r%s' % i].getStdErr('ripngd')
+        log = net["r%s" % i].getStdErr("ripngd")
         if log:
             error_logs += "r%s RIPngd StdErr Output:\n" % i
             error_logs += log
-        log = net['r%s' % i].getStdErr('ospfd')
+        log = net["r%s" % i].getStdErr("ospfd")
         if log:
             error_logs += "r%s OSPFd StdErr Output:\n" % i
             error_logs += log
-        log = net['r%s' % i].getStdErr('ospf6d')
+        log = net["r%s" % i].getStdErr("ospf6d")
         if log:
             error_logs += "r%s OSPF6d StdErr Output:\n" % i
             error_logs += log
-        log = net['r%s' % i].getStdErr('isisd')
+        log = net["r%s" % i].getStdErr("isisd")
         # ISIS shows debugging enabled status on StdErr
         # Remove these messages
         log = re.sub(r"^IS-IS .* debugging is on.*", "", log).rstrip()
         if log:
             error_logs += "r%s ISISd StdErr Output:\n" % i
             error_logs += log
-        log = net['r%s' % i].getStdErr('bgpd')
+        log = net["r%s" % i].getStdErr("bgpd")
         if log:
             error_logs += "r%s BGPd StdErr Output:\n" % i
             error_logs += log
-        if (net['r%s' % i].daemon_available('ldpd')): 
-            log = net['r%s' % i].getStdErr('ldpd')
+        if net["r%s" % i].daemon_available("ldpd"):
+            log = net["r%s" % i].getStdErr("ldpd")
             if log:
                 error_logs += "r%s LDPd StdErr Output:\n" % i
                 error_logs += log
 
-        log = net['r1'].getStdErr('nhrpd')
+        log = net["r1"].getStdErr("nhrpd")
         if log:
             error_logs += "r%s NHRPd StdErr Output:\n" % i
             error_logs += log
 
-        log = net['r1'].getStdErr('babeld')
+        log = net["r1"].getStdErr("babeld")
         if log:
             error_logs += "r%s BABELd StdErr Output:\n" % i
             error_logs += log
 
-        log = net['r1'].getStdErr('pbrd')
+        log = net["r1"].getStdErr("pbrd")
         if log:
             error_logs += "r%s PBRd StdErr Output:\n" % i
             error_logs += log
 
-        log = net['r%s' % i].getStdErr('zebra')
+        log = net["r%s" % i].getStdErr("zebra")
         if log:
             error_logs += "r%s Zebra StdErr Output:\n"
             error_logs += log
 
     if error_logs:
-        sys.stderr.write('Failed check for StdErr Output on daemons:\n%s\n' % error_logs)
+        sys.stderr.write(
+            "Failed check for StdErr Output on daemons:\n%s\n" % error_logs
+        )
 
     # Ignoring the issue if told to ignore (ie not yet fixed)
-    if (error_logs != ""):
-        if (os.environ.get('bamboo_TOPOTESTS_ISSUE_349') == "IGNORE"):
-            sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n')
-            pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349')
+    if error_logs != "":
+        if os.environ.get("bamboo_TOPOTESTS_ISSUE_349") == "IGNORE":
+            sys.stderr.write(
+                "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349\n"
+            )
+            pytest.skip(
+                "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/349"
+            )
 
     assert error_logs == "", "Daemons report errors to StdErr"
 
@@ -304,7 +314,7 @@ def test_converge_protocols():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -318,62 +328,84 @@ def test_converge_protocols():
     # Make sure that all daemons are running
     failures = 0
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
-        print("Show that v4 routes are right\n");
-        v4_routesFile = '%s/r%s/ipv4_routes.ref' % (thisDir, i)
+        print("Show that v4 routes are right\n")
+        v4_routesFile = "%s/r%s/ipv4_routes.ref" % (thisDir, i)
         expected = open(v4_routesFile).read().rstrip()
-        expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
-
-        actual = net['r%s' %i].cmd('vtysh -c "show ip route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip()
+        expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
+
+        actual = (
+            net["r%s" % i]
+            .cmd(
+                'vtysh -c "show ip route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null'
+            )
+            .rstrip()
+        )
         # Drop time in last update
         actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
-        actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
-        diff = topotest.get_textdiff(actual, expected,
-                                     title1="Actual IP Routing Table",
-                                     title2="Expected IP RoutingTable")
+        actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
+        diff = topotest.get_textdiff(
+            actual,
+            expected,
+            title1="Actual IP Routing Table",
+            title2="Expected IP RoutingTable",
+        )
         if diff:
-            sys.stderr.write('r%s failed IP Routing table check:\n%s\n' % (i, diff))
+            sys.stderr.write("r%s failed IP Routing table check:\n%s\n" % (i, diff))
             failures += 1
         else:
-            print("r%s ok" %i)
+            print("r%s ok" % i)
 
         assert failures == 0, "IP Routing table failed for r%s\n%s" % (i, diff)
 
         failures = 0
 
         print("Show that v6 routes are right\n")
-        v6_routesFile = '%s/r%s/ipv6_routes.ref' % (thisDir, i)
+        v6_routesFile = "%s/r%s/ipv6_routes.ref" % (thisDir, i)
         expected = open(v6_routesFile).read().rstrip()
-        expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
-
-        actual = net['r%s' %i].cmd('vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null').rstrip()
+        expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
+
+        actual = (
+            net["r%s" % i]
+            .cmd(
+                'vtysh -c "show ipv6 route" | /usr/bin/tail -n +7 | env LC_ALL=en_US.UTF-8 sort 2> /dev/null'
+            )
+            .rstrip()
+        )
         # Drop time in last update
         actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
-        actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
-        diff = topotest.get_textdiff(actual, expected,
-                                     title1="Actual IPv6 Routing Table",
-                                     title2="Expected IPv6 RoutingTable")
+        actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
+        diff = topotest.get_textdiff(
+            actual,
+            expected,
+            title1="Actual IPv6 Routing Table",
+            title2="Expected IPv6 RoutingTable",
+        )
         if diff:
-            sys.stderr.write('r%s failed IPv6 Routing table check:\n%s\n' % (i, diff))
+            sys.stderr.write("r%s failed IPv6 Routing table check:\n%s\n" % (i, diff))
             failures += 1
         else:
-            print("r%s ok" %i)
+            print("r%s ok" % i)
 
         assert failures == 0, "IPv6 Routing table failed for r%s\n%s" % (i, diff)
 
     # For debugging after starting FRR daemons, uncomment the next line
     ## CLI(net)
 
+
 def route_get_nhg_id(route_str):
     output = net["r1"].cmd('vtysh -c "show ip route %s nexthop-group"' % route_str)
     match = re.search(r"Nexthop Group ID: (\d+)", output)
-    assert match is not None, "Nexthop Group ID not found for sharpd route %s" % route_str
+    assert match is not None, (
+        "Nexthop Group ID not found for sharpd route %s" % route_str
+    )
 
     nhg_id = int(match.group(1))
     return nhg_id
 
+
 def verify_nexthop_group(nhg_id, recursive=False, ecmp=0):
     # Verify NHG is valid/installed
     output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
@@ -389,10 +421,14 @@ def verify_nexthop_group(nhg_id, recursive=False, ecmp=0):
         depends = re.findall(r"\((\d+)\)", match.group(0))
 
         if ecmp:
-            assert (len(depends) == ecmp), "Nexthop Group ID=%d doesn't match ecmp size" % nhg_id
+            assert len(depends) == ecmp, (
+                "Nexthop Group ID=%d doesn't match ecmp size" % nhg_id
+            )
         else:
             # If recursive, we need to look at its resolved group
-            assert (len(depends) == 1), "Nexthop Group ID=%d should only have one recursive depend" % nhg_id
+            assert len(depends) == 1, (
+                "Nexthop Group ID=%d should only have one recursive depend" % nhg_id
+            )
             resolved_id = int(depends[0])
             verify_nexthop_group(resolved_id, False)
 
@@ -400,17 +436,19 @@ def verify_nexthop_group(nhg_id, recursive=False, ecmp=0):
         match = re.search(r"Installed", output)
         assert match is not None, "Nexthop Group ID=%d not marked Installed" % nhg_id
 
+
 def verify_route_nexthop_group(route_str, recursive=False, ecmp=0):
     # Verify route and that zebra created NHGs for and they are valid/installed
     nhg_id = route_get_nhg_id(route_str)
     verify_nexthop_group(nhg_id, recursive, ecmp)
 
+
 def test_nexthop_groups():
     global fatal_error
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Verifying Nexthop Groups")
@@ -421,7 +459,9 @@ def test_nexthop_groups():
     ## Basic test
 
     # Create a lib nexthop-group
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group basic" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"'
+    )
 
     # Create with sharpd using nexthop-group
     net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.1 nexthop-group basic 1"')
@@ -430,7 +470,9 @@ def test_nexthop_groups():
 
     ## Connected
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group connected" -c "nexthop r1-eth1" -c "nexthop r1-eth2"'
+    )
 
     net["r1"].cmd('vtysh -c "sharp install routes 2.2.2.2 nexthop-group connected 1"')
 
@@ -438,15 +480,21 @@ def test_nexthop_groups():
 
     ## Recursive
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group basic-recursive" -c "nexthop 2.2.2.1"'
+    )
 
-    net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"')
+    net["r1"].cmd(
+        'vtysh -c "sharp install routes 3.3.3.1 nexthop-group basic-recursive 1"'
+    )
 
     verify_route_nexthop_group("3.3.3.1/32", True)
 
     ## Duplicate
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group duplicate" -c "nexthop 2.2.2.1" -c "nexthop 1.1.1.1"'
+    )
 
     net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.2 nexthop-group duplicate 1"')
 
@@ -454,15 +502,19 @@ def test_nexthop_groups():
 
     ## Two 4-Way ECMP
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \
-            -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group fourA" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2" \
+            -c "nexthop 1.1.1.3" -c "nexthop 1.1.1.4"'
+    )
 
     net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.1 nexthop-group fourA 1"')
 
     verify_route_nexthop_group("4.4.4.1/32")
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \
-            -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group fourB" -c "nexthop 1.1.1.5" -c "nexthop 1.1.1.6" \
+            -c "nexthop 1.1.1.7" -c "nexthop 1.1.1.8"'
+    )
 
     net["r1"].cmd('vtysh -c "sharp install routes 4.4.4.2 nexthop-group fourB 1"')
 
@@ -470,9 +522,13 @@ def test_nexthop_groups():
 
     ## Recursive to 8-Way ECMP
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group eight-recursive" -c "nexthop 4.4.4.1" -c "nexthop 4.4.4.2"'
+    )
 
-    net["r1"].cmd('vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"')
+    net["r1"].cmd(
+        'vtysh -c "sharp install routes 5.5.5.1 nexthop-group eight-recursive 1"'
+    )
 
     verify_route_nexthop_group("5.5.5.1/32")
 
@@ -488,12 +544,13 @@ def test_nexthop_groups():
     net["r1"].cmd('vtysh -c "sharp remove routes 4.4.4.2 1"')
     net["r1"].cmd('vtysh -c "sharp remove routes 5.5.5.1 1"')
 
+
 def test_rip_status():
     global fatal_error
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -502,30 +559,37 @@ def test_rip_status():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/rip_status.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/rip_status.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show ip rip status" 2> /dev/null').rstrip()
-            # Drop time in next due 
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show ip rip status" 2> /dev/null')
+                .rstrip()
+            )
+            # Drop time in next due
             actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
             # Drop time in last update
             actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual IP RIP status",
-                title2="expected IP RIP status")
+                title2="expected IP RIP status",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed IP RIP status check:\n%s\n' % (i, diff))
+                sys.stderr.write("r%s failed IP RIP status check:\n%s\n" % (i, diff))
                 failures += 1
             else:
                 print("r%s ok" % i)
@@ -534,7 +598,7 @@ def test_rip_status():
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -546,7 +610,7 @@ def test_ripng_status():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -555,41 +619,53 @@ def test_ripng_status():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/ripng_status.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/ripng_status.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null').rstrip()
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show ipv6 ripng status" 2> /dev/null')
+                .rstrip()
+            )
             # Mask out Link-Local mac address portion. They are random...
             actual = re.sub(r" fe80::[0-9a-f:]+", " fe80::XXXX:XXXX:XXXX:XXXX", actual)
-            # Drop time in next due 
+            # Drop time in next due
             actual = re.sub(r"in [0-9]+ seconds", "in XX seconds", actual)
             # Drop time in last update
             actual = re.sub(r" [0-2][0-9]:[0-5][0-9]:[0-5][0-9]", " XX:XX:XX", actual)
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual IPv6 RIPng status",
-                title2="expected IPv6 RIPng status")
+                title2="expected IPv6 RIPng status",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed IPv6 RIPng status check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed IPv6 RIPng status check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
                 print("r%s ok" % i)
 
-            assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (i, diff)
+            assert failures == 0, "IPv6 RIPng status failed for router r%s:\n%s" % (
+                i,
+                diff,
+            )
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -601,7 +677,7 @@ def test_ospfv2_interfaces():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -610,50 +686,71 @@ def test_ospfv2_interfaces():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/show_ip_ospf_interface.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/show_ip_ospf_interface.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show ip ospf interface" 2> /dev/null').rstrip()
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show ip ospf interface" 2> /dev/null')
+                .rstrip()
+            )
             # Mask out Bandwidth portion. They may change..
             actual = re.sub(r"BW [0-9]+ Mbit", "BW XX Mbit", actual)
             actual = re.sub(r"ifindex [0-9]", "ifindex X", actual)
 
-            # Drop time in next due 
+            # Drop time in next due
             actual = re.sub(r"Hello due in [0-9\.]+s", "Hello due in XX.XXXs", actual)
-            actual = re.sub(r"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual)
+            actual = re.sub(
+                r"Hello due in [0-9\.]+ usecs", "Hello due in XX.XXXs", actual
+            )
             # Fix 'MTU mismatch detection: enabled' vs 'MTU mismatch detection:enabled' - accept both
-            actual = re.sub(r"MTU mismatch detection:([a-z]+.*)", r"MTU mismatch detection: \1", actual)
+            actual = re.sub(
+                r"MTU mismatch detection:([a-z]+.*)",
+                r"MTU mismatch detection: \1",
+                actual,
+            )
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual SHOW IP OSPF INTERFACE",
-                title2="expected SHOW IP OSPF INTERFACE")
+                title2="expected SHOW IP OSPF INTERFACE",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed SHOW IP OSPF INTERFACE check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed SHOW IP OSPF INTERFACE check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
                 print("r%s ok" % i)
 
             # Ignoring the issue if told to ignore (ie not yet fixed)
-            if (failures != 0):
-                if (os.environ.get('bamboo_TOPOTESTS_ISSUE_348') == "IGNORE"):
-                    sys.stderr.write('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n')
-                    pytest.skip('Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348')
-
-            assert failures == 0, "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
+            if failures != 0:
+                if os.environ.get("bamboo_TOPOTESTS_ISSUE_348") == "IGNORE":
+                    sys.stderr.write(
+                        "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348\n"
+                    )
+                    pytest.skip(
+                        "Known issue - IGNORING. See https://github.com/FRRouting/frr/issues/348"
+                    )
+
+            assert (
+                failures == 0
+            ), "SHOW IP OSPF INTERFACE failed for router r%s:\n%s" % (i, diff)
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -665,7 +762,7 @@ def test_isis_interfaces():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -674,42 +771,52 @@ def test_isis_interfaces():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/show_isis_interface_detail.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/show_isis_interface_detail.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show isis interface detail" 2> /dev/null').rstrip()
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show isis interface detail" 2> /dev/null')
+                .rstrip()
+            )
             # Mask out Link-Local mac address portion. They are random...
             actual = re.sub(r"fe80::[0-9a-f:]+", "fe80::XXXX:XXXX:XXXX:XXXX", actual)
             # Mask out SNPA mac address portion. They are random...
             actual = re.sub(r"SNPA: [0-9a-f\.]+", "SNPA: XXXX.XXXX.XXXX", actual)
             # Mask out Circuit ID number
-            actual = re.sub(r"Circuit Id: 0x[0-9a-f]+", "Circuit Id: 0xXX",
-                            actual)
+            actual = re.sub(r"Circuit Id: 0x[0-9a-f]+", "Circuit Id: 0xXX", actual)
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual SHOW ISIS INTERFACE DETAIL",
-                title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL")
+                title2="expected SHOW ISIS OSPF6 INTERFACE DETAIL",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed SHOW ISIS INTERFACE DETAIL check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
                 print("r%s ok" % i)
 
-            assert failures == 0, "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
+            assert (
+                failures == 0
+            ), "SHOW ISIS INTERFACE DETAIL failed for router r%s:\n%s" % (i, diff)
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -721,7 +828,7 @@ def test_bgp_summary():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -730,15 +837,19 @@ def test_bgp_summary():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/show_ip_bgp_summary.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/show_ip_bgp_summary.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show ip bgp summary" 2> /dev/null').rstrip()
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show ip bgp summary" 2> /dev/null')
+                .rstrip()
+            )
             # Mask out "using XXiXX bytes" portion. They are random...
             actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
             # Mask out "using XiXXX KiB" portion. They are random...
@@ -747,50 +858,60 @@ def test_bgp_summary():
             # Remove extra summaries which exist with newer versions
             #
             # Remove summary lines (changed recently)
-            actual = re.sub(r'Total number.*', '', actual)
-            actual = re.sub(r'Displayed.*', '', actual)
+            actual = re.sub(r"Total number.*", "", actual)
+            actual = re.sub(r"Displayed.*", "", actual)
             # Remove IPv4 Unicast Summary (Title only)
-            actual = re.sub(r'IPv4 Unicast Summary:', '', actual)
+            actual = re.sub(r"IPv4 Unicast Summary:", "", actual)
             # Remove IPv4 Multicast Summary (all of it)
-            actual = re.sub(r'IPv4 Multicast Summary:', '', actual)
-            actual = re.sub(r'No IPv4 Multicast neighbor is configured', '', actual)
+            actual = re.sub(r"IPv4 Multicast Summary:", "", actual)
+            actual = re.sub(r"No IPv4 Multicast neighbor is configured", "", actual)
             # Remove IPv4 VPN Summary (all of it)
-            actual = re.sub(r'IPv4 VPN Summary:', '', actual)
-            actual = re.sub(r'No IPv4 VPN neighbor is configured', '', actual)
+            actual = re.sub(r"IPv4 VPN Summary:", "", actual)
+            actual = re.sub(r"No IPv4 VPN neighbor is configured", "", actual)
             # Remove IPv4 Encap Summary (all of it)
-            actual = re.sub(r'IPv4 Encap Summary:', '', actual)
-            actual = re.sub(r'No IPv4 Encap neighbor is configured', '', actual)
+            actual = re.sub(r"IPv4 Encap Summary:", "", actual)
+            actual = re.sub(r"No IPv4 Encap neighbor is configured", "", actual)
             # Remove Unknown Summary (all of it)
-            actual = re.sub(r'Unknown Summary:', '', actual)
-            actual = re.sub(r'No Unknown neighbor is configured', '', actual)
+            actual = re.sub(r"Unknown Summary:", "", actual)
+            actual = re.sub(r"No Unknown neighbor is configured", "", actual)
 
-            actual = re.sub(r'IPv4 labeled-unicast Summary:', '', actual)
-            actual = re.sub(r'No IPv4 labeled-unicast neighbor is configured', '', actual)
+            actual = re.sub(r"IPv4 labeled-unicast Summary:", "", actual)
+            actual = re.sub(
+                r"No IPv4 labeled-unicast neighbor is configured", "", actual
+            )
 
             # Strip empty lines
             actual = actual.lstrip()
             actual = actual.rstrip()
             #
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual SHOW IP BGP SUMMARY",
-                title2="expected SHOW IP BGP SUMMARY")
+                title2="expected SHOW IP BGP SUMMARY",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed SHOW IP BGP SUMMARY check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed SHOW IP BGP SUMMARY check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
                 print("r%s ok" % i)
 
-            assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (i, diff)
+            assert failures == 0, "SHOW IP BGP SUMMARY failed for router r%s:\n%s" % (
+                i,
+                diff,
+            )
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -802,7 +923,7 @@ def test_bgp_ipv6_summary():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -811,15 +932,19 @@ def test_bgp_ipv6_summary():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/show_bgp_ipv6_summary.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/show_bgp_ipv6_summary.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null').rstrip()
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show bgp ipv6 summary" 2> /dev/null')
+                .rstrip()
+            )
             # Mask out "using XXiXX bytes" portion. They are random...
             actual = re.sub(r"using [0-9]+ bytes", "using XXXX bytes", actual)
             # Mask out "using XiXXX KiB" portion. They are random...
@@ -828,51 +953,61 @@ def test_bgp_ipv6_summary():
             # Remove extra summaries which exist with newer versions
             #
             # Remove summary lines (changed recently)
-            actual = re.sub(r'Total number.*', '', actual)
-            actual = re.sub(r'Displayed.*', '', actual)
+            actual = re.sub(r"Total number.*", "", actual)
+            actual = re.sub(r"Displayed.*", "", actual)
             # Remove IPv4 Unicast Summary (Title only)
-            actual = re.sub(r'IPv6 Unicast Summary:', '', actual)
+            actual = re.sub(r"IPv6 Unicast Summary:", "", actual)
             # Remove IPv4 Multicast Summary (all of it)
-            actual = re.sub(r'IPv6 Multicast Summary:', '', actual)
-            actual = re.sub(r'No IPv6 Multicast neighbor is configured', '', actual)
+            actual = re.sub(r"IPv6 Multicast Summary:", "", actual)
+            actual = re.sub(r"No IPv6 Multicast neighbor is configured", "", actual)
             # Remove IPv4 VPN Summary (all of it)
-            actual = re.sub(r'IPv6 VPN Summary:', '', actual)
-            actual = re.sub(r'No IPv6 VPN neighbor is configured', '', actual)
+            actual = re.sub(r"IPv6 VPN Summary:", "", actual)
+            actual = re.sub(r"No IPv6 VPN neighbor is configured", "", actual)
             # Remove IPv4 Encap Summary (all of it)
-            actual = re.sub(r'IPv6 Encap Summary:', '', actual)
-            actual = re.sub(r'No IPv6 Encap neighbor is configured', '', actual)
+            actual = re.sub(r"IPv6 Encap Summary:", "", actual)
+            actual = re.sub(r"No IPv6 Encap neighbor is configured", "", actual)
             # Remove Unknown Summary (all of it)
-            actual = re.sub(r'Unknown Summary:', '', actual)
-            actual = re.sub(r'No Unknown neighbor is configured', '', actual)
+            actual = re.sub(r"Unknown Summary:", "", actual)
+            actual = re.sub(r"No Unknown neighbor is configured", "", actual)
 
             # Remove Labeled Unicast Summary (all of it)
-            actual = re.sub(r'IPv6 labeled-unicast Summary:', '', actual)
-            actual = re.sub(r'No IPv6 labeled-unicast neighbor is configured', '', actual)
+            actual = re.sub(r"IPv6 labeled-unicast Summary:", "", actual)
+            actual = re.sub(
+                r"No IPv6 labeled-unicast neighbor is configured", "", actual
+            )
 
             # Strip empty lines
             actual = actual.lstrip()
             actual = actual.rstrip()
             #
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual SHOW BGP IPv6 SUMMARY",
-                title2="expected SHOW BGP IPv6 SUMMARY")
+                title2="expected SHOW BGP IPv6 SUMMARY",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed SHOW BGP IPv6 SUMMARY check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
                 print("r%s ok" % i)
 
-            assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (i, diff)
+            assert failures == 0, "SHOW BGP IPv6 SUMMARY failed for router r%s:\n%s" % (
+                i,
+                diff,
+            )
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -884,7 +1019,7 @@ def test_bgp_ipv4():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -894,27 +1029,31 @@ def test_bgp_ipv4():
     diffresult = {}
     for i in range(1, 2):
         success = 0
-        for refTableFile in (glob.glob(
-                '%s/r%s/show_bgp_ipv4*.ref' % (thisDir, i))):
+        for refTableFile in glob.glob("%s/r%s/show_bgp_ipv4*.ref" % (thisDir, i)):
             if os.path.isfile(refTableFile):
                 # Read expected result from file
                 expected = open(refTableFile).read().rstrip()
                 # Fix newlines (make them all the same)
-                expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+                expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
                 # Actual output from router
-                actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
+                actual = (
+                    net["r%s" % i].cmd('vtysh -c "show bgp ipv4" 2> /dev/null').rstrip()
+                )
                 # Remove summary line (changed recently)
-                actual = re.sub(r'Total number.*', '', actual)
-                actual = re.sub(r'Displayed.*', '', actual)
+                actual = re.sub(r"Total number.*", "", actual)
+                actual = re.sub(r"Displayed.*", "", actual)
                 actual = actual.rstrip()
                 # Fix newlines (make them all the same)
-                actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+                actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
                 # Generate Diff
-                diff = topotest.get_textdiff(actual, expected,
+                diff = topotest.get_textdiff(
+                    actual,
+                    expected,
                     title1="actual SHOW BGP IPv4",
-                    title2="expected SHOW BGP IPv4")
+                    title2="expected SHOW BGP IPv4",
+                )
 
                 # Empty string if it matches, otherwise diff contains unified diff
                 if diff:
@@ -925,17 +1064,20 @@ def test_bgp_ipv4():
                     break
 
         if not success:
-            resultstr = 'No template matched.\n'
+            resultstr = "No template matched.\n"
             for f in diffresult.iterkeys():
-                resultstr += (
-                    'template %s: r%s failed SHOW BGP IPv4 check:\n%s\n'
-                    % (f, i, diffresult[f]))
+                resultstr += "template %s: r%s failed SHOW BGP IPv4 check:\n%s\n" % (
+                    f,
+                    i,
+                    diffresult[f],
+                )
             raise AssertionError(
-                "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr))
+                "SHOW BGP IPv4 failed for router r%s:\n%s" % (i, resultstr)
+            )
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -947,7 +1089,7 @@ def test_bgp_ipv6():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -957,27 +1099,31 @@ def test_bgp_ipv6():
     diffresult = {}
     for i in range(1, 2):
         success = 0
-        for refTableFile in (glob.glob(
-                '%s/r%s/show_bgp_ipv6*.ref' % (thisDir, i))):
+        for refTableFile in glob.glob("%s/r%s/show_bgp_ipv6*.ref" % (thisDir, i)):
             if os.path.isfile(refTableFile):
                 # Read expected result from file
                 expected = open(refTableFile).read().rstrip()
                 # Fix newlines (make them all the same)
-                expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+                expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
                 # Actual output from router
-                actual = net['r%s' % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
+                actual = (
+                    net["r%s" % i].cmd('vtysh -c "show bgp ipv6" 2> /dev/null').rstrip()
+                )
                 # Remove summary line (changed recently)
-                actual = re.sub(r'Total number.*', '', actual)
-                actual = re.sub(r'Displayed.*', '', actual)
+                actual = re.sub(r"Total number.*", "", actual)
+                actual = re.sub(r"Displayed.*", "", actual)
                 actual = actual.rstrip()
                 # Fix newlines (make them all the same)
-                actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+                actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
                 # Generate Diff
-                diff = topotest.get_textdiff(actual, expected,
+                diff = topotest.get_textdiff(
+                    actual,
+                    expected,
                     title1="actual SHOW BGP IPv6",
-                    title2="expected SHOW BGP IPv6")
+                    title2="expected SHOW BGP IPv6",
+                )
 
                 # Empty string if it matches, otherwise diff contains unified diff
                 if diff:
@@ -987,27 +1133,31 @@ def test_bgp_ipv6():
                     print("template %s matched: r%s ok" % (refTableFile, i))
 
         if not success:
-            resultstr = 'No template matched.\n'
+            resultstr = "No template matched.\n"
             for f in diffresult.iterkeys():
-                resultstr += (
-                    'template %s: r%s failed SHOW BGP IPv6 check:\n%s\n'
-                    % (f, i, diffresult[f]))
+                resultstr += "template %s: r%s failed SHOW BGP IPv6 check:\n%s\n" % (
+                    f,
+                    i,
+                    diffresult[f],
+                )
             raise AssertionError(
-                "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr))
+                "SHOW BGP IPv6 failed for router r%s:\n%s" % (i, resultstr)
+            )
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
     # CLI(net)
 
+
 def test_route_map():
     global fatal_error
     global net
 
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -1016,32 +1166,42 @@ def test_route_map():
     print("*******************************************************\n")
     failures = 0
     for i in range(1, 2):
-        refroutemap = '%s/r%s/show_route_map.ref' % (thisDir, i)
+        refroutemap = "%s/r%s/show_route_map.ref" % (thisDir, i)
         if os.path.isfile(refroutemap):
             expected = open(refroutemap).read().rstrip()
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
-            actual = net['r%s' %i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip()
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = (
+                net["r%s" % i].cmd('vtysh -c "show route-map" 2> /dev/null').rstrip()
+            )
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
-            diff = topotest.get_textdiff(actual, expected,
-                                         title1="actual show route-map",
-                                         title2="expected show route-map")
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
+                title1="actual show route-map",
+                title2="expected show route-map",
+            )
 
             if diff:
-                sys.stderr.write('r%s failed show route-map command Check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed show route-map command Check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
-                print("r%s ok" %i)
+                print("r%s ok" % i)
+
+            assert (
+                failures == 0
+            ), "Show route-map command failed for router r%s:\n%s" % (i, diff)
 
-            assert failures == 0, "Show route-map command failed for router r%s:\n%s" % (i, diff)
 
 def test_nexthop_groups_with_route_maps():
     global fatal_error
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Verifying Nexthop Groups With Route-Maps")
@@ -1050,14 +1210,18 @@ def test_nexthop_groups_with_route_maps():
     ### Nexthop Group With Route-Map Tests
 
     # Create a lib nexthop-group
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group test" -c "nexthop 1.1.1.1" -c "nexthop 1.1.1.2"'
+    )
 
     ## Route-Map Proto Source
 
     route_str = "2.2.2.1"
     src_str = "192.168.0.1"
 
-    net["r1"].cmd('vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str)
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "route-map NH-SRC permit 111" -c "set src %s"' % src_str
+    )
     net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NH-SRC"')
 
     net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % route_str)
@@ -1066,14 +1230,19 @@ def test_nexthop_groups_with_route_maps():
 
     # Only a valid test on linux using nexthop objects
     if sys.platform.startswith("linux"):
-        output = net["r1"].cmd('ip route show %s/32' % route_str)
+        output = net["r1"].cmd("ip route show %s/32" % route_str)
         match = re.search(r"src %s" % src_str, output)
-        assert match is not None, "Route %s/32 not installed with src %s" % (route_str, src_str)
+        assert match is not None, "Route %s/32 not installed with src %s" % (
+            route_str,
+            src_str,
+        )
 
     # Remove NHG routes and route-map
     net["r1"].cmd('vtysh -c "sharp remove routes %s 1"' % route_str)
     net["r1"].cmd('vtysh -c "c t" -c "no ip protocol sharp route-map NH-SRC"')
-    net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str)
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "no route-map NH-SRC permit 111" -c "set src %s"' % src_str
+    )
     net["r1"].cmd('vtysh -c "c t" -c "no route-map NH-SRC"')
 
     ## Route-Map Deny/Permit with same nexthop group
@@ -1081,18 +1250,26 @@ def test_nexthop_groups_with_route_maps():
     permit_route_str = "3.3.3.1"
     deny_route_str = "3.3.3.2"
 
-    net["r1"].cmd('vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str)
-    net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str
+    )
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "route-map NOPE permit 111" -c "match ip address prefix-list NOPE"'
+    )
     net["r1"].cmd('vtysh -c "c t" -c "route-map NOPE deny 222"')
     net["r1"].cmd('vtysh -c "c t" -c "ip protocol sharp route-map NOPE"')
 
     # This route should be permitted
-    net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str)
+    net["r1"].cmd(
+        'vtysh -c "sharp install routes %s nexthop-group test 1"' % permit_route_str
+    )
 
     verify_route_nexthop_group("%s/32" % permit_route_str)
 
     # This route should be denied
-    net["r1"].cmd('vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str)
+    net["r1"].cmd(
+        'vtysh -c "sharp install routes %s nexthop-group test 1"' % deny_route_str
+    )
 
     nhg_id = route_get_nhg_id(deny_route_str)
     output = net["r1"].cmd('vtysh -c "show nexthop-group rib %d"' % nhg_id)
@@ -1110,14 +1287,18 @@ def test_nexthop_groups_with_route_maps():
     net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE permit 111"')
     net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE deny 222"')
     net["r1"].cmd('vtysh -c "c t" -c "no route-map NOPE"')
-    net["r1"].cmd('vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"' % permit_route_str)
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "no ip prefix-list NOPE seq 5 permit %s/32"'
+        % permit_route_str
+    )
+
 
 def test_nexthop_group_replace():
     global fatal_error
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Verifying Nexthop Groups")
@@ -1127,7 +1308,9 @@ def test_nexthop_group_replace():
 
     ## 2-Way ECMP Directly Connected
 
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group replace" -c "nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.2 r1-eth2 onlink"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group replace" -c "nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.2 r1-eth2 onlink"'
+    )
 
     # Create with sharpd using nexthop-group
     net["r1"].cmd('vtysh -c "sharp install routes 3.3.3.1 nexthop-group replace 1"')
@@ -1135,21 +1318,24 @@ def test_nexthop_group_replace():
     verify_route_nexthop_group("3.3.3.1/32")
 
     # Change the nexthop group
-    net["r1"].cmd('vtysh -c "c t" -c "nexthop-group replace" -c "no nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.3 r1-eth1 onlink" -c "nexthop 1.1.1.4 r1-eth4 onlink"')
+    net["r1"].cmd(
+        'vtysh -c "c t" -c "nexthop-group replace" -c "no nexthop 1.1.1.1 r1-eth1 onlink" -c "nexthop 1.1.1.3 r1-eth1 onlink" -c "nexthop 1.1.1.4 r1-eth4 onlink"'
+    )
 
     # Verify it updated. We can just check install and ecmp count here.
     verify_route_nexthop_group("3.3.3.1/32", False, 3)
 
+
 def test_mpls_interfaces():
     global fatal_error
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     # Skip if no LDP installed or old kernel
-    if (net['r1'].daemon_available('ldpd') == False):
+    if net["r1"].daemon_available("ldpd") == False:
         pytest.skip("No MPLS or kernel < 4.5")
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
@@ -1158,40 +1344,51 @@ def test_mpls_interfaces():
     print("******************************************\n")
     failures = 0
     for i in range(1, 2):
-        refTableFile = '%s/r%s/show_mpls_ldp_interface.ref' % (thisDir, i)
+        refTableFile = "%s/r%s/show_mpls_ldp_interface.ref" % (thisDir, i)
         if os.path.isfile(refTableFile):
             # Read expected result from file
             expected = open(refTableFile).read().rstrip()
             # Fix newlines (make them all the same)
-            expected = ('\n'.join(expected.splitlines()) + '\n').splitlines(1)
+            expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
 
             # Actual output from router
-            actual = net['r%s' % i].cmd('vtysh -c "show mpls ldp interface" 2> /dev/null').rstrip()
+            actual = (
+                net["r%s" % i]
+                .cmd('vtysh -c "show mpls ldp interface" 2> /dev/null')
+                .rstrip()
+            )
             # Mask out Timer in Uptime
             actual = re.sub(r" [0-9][0-9]:[0-9][0-9]:[0-9][0-9] ", " xx:xx:xx ", actual)
             # Fix newlines (make them all the same)
-            actual = ('\n'.join(actual.splitlines()) + '\n').splitlines(1)
+            actual = ("\n".join(actual.splitlines()) + "\n").splitlines(1)
 
             # Generate Diff
-            diff = topotest.get_textdiff(actual, expected,
+            diff = topotest.get_textdiff(
+                actual,
+                expected,
                 title1="actual MPLS LDP interface status",
-                title2="expected MPLS LDP interface status")
+                title2="expected MPLS LDP interface status",
+            )
 
             # Empty string if it matches, otherwise diff contains unified diff
             if diff:
-                sys.stderr.write('r%s failed MPLS LDP Interface status Check:\n%s\n' % (i, diff))
+                sys.stderr.write(
+                    "r%s failed MPLS LDP Interface status Check:\n%s\n" % (i, diff)
+                )
                 failures += 1
             else:
                 print("r%s ok" % i)
 
-            if failures>0:
+            if failures > 0:
                 fatal_error = "MPLS LDP Interface status failed"
 
-            assert failures == 0, "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
+            assert (
+                failures == 0
+            ), "MPLS LDP Interface status failed for router r%s:\n%s" % (i, diff)
 
     # Make sure that all daemons are running
     for i in range(1, 2):
-        fatal_error = net['r%s' % i].checkRouterRunning()
+        fatal_error = net["r%s" % i].checkRouterRunning()
         assert fatal_error == "", fatal_error
 
     # For debugging after starting FRR daemons, uncomment the next line
@@ -1203,58 +1400,60 @@ def test_shutdown_check_stderr():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
     print("\n\n** Verifying unexpected STDERR output from daemons")
     print("******************************************\n")
 
-    if os.environ.get('TOPOTESTS_CHECK_STDERR') is None:
-        print("SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n")
-        pytest.skip('Skipping test for Stderr output')
+    if os.environ.get("TOPOTESTS_CHECK_STDERR") is None:
+        print(
+            "SKIPPED final check on StdErr output: Disabled (TOPOTESTS_CHECK_STDERR undefined)\n"
+        )
+        pytest.skip("Skipping test for Stderr output")
 
     thisDir = os.path.dirname(os.path.realpath(__file__))
 
     print("thisDir=" + thisDir)
 
-    net['r1'].stopRouter()
+    net["r1"].stopRouter()
 
-    log = net['r1'].getStdErr('ripd')
+    log = net["r1"].getStdErr("ripd")
     if log:
         print("\nRIPd StdErr Log:\n" + log)
-    log = net['r1'].getStdErr('ripngd')
+    log = net["r1"].getStdErr("ripngd")
     if log:
         print("\nRIPngd StdErr Log:\n" + log)
-    log = net['r1'].getStdErr('ospfd')
+    log = net["r1"].getStdErr("ospfd")
     if log:
         print("\nOSPFd StdErr Log:\n" + log)
-    log = net['r1'].getStdErr('ospf6d')
+    log = net["r1"].getStdErr("ospf6d")
     if log:
         print("\nOSPF6d StdErr Log:\n" + log)
-    log = net['r1'].getStdErr('isisd')
+    log = net["r1"].getStdErr("isisd")
     if log:
         print("\nISISd StdErr Log:\n" + log)
-    log = net['r1'].getStdErr('bgpd')
+    log = net["r1"].getStdErr("bgpd")
     if log:
         print("\nBGPd StdErr Log:\n" + log)
 
-    log = net['r1'].getStdErr('nhrpd')
+    log = net["r1"].getStdErr("nhrpd")
     if log:
         print("\nNHRPd StdErr Log:\n" + log)
 
-    log = net['r1'].getStdErr('pbrd')
+    log = net["r1"].getStdErr("pbrd")
     if log:
         print("\nPBRd StdErr Log:\n" + log)
 
-    log = net['r1'].getStdErr('babeld')
+    log = net["r1"].getStdErr("babeld")
     if log:
         print("\nBABELd StdErr Log:\n" + log)
 
-    if (net['r1'].daemon_available('ldpd')):
-        log = net['r1'].getStdErr('ldpd')
+    if net["r1"].daemon_available("ldpd"):
+        log = net["r1"].getStdErr("ldpd")
         if log:
             print("\nLDPd StdErr Log:\n" + log)
-    log = net['r1'].getStdErr('zebra')
+    log = net["r1"].getStdErr("zebra")
     if log:
         print("\nZebra StdErr Log:\n" + log)
 
@@ -1264,23 +1463,27 @@ def test_shutdown_check_memleak():
     global net
 
     # Skip if previous fatal error condition is raised
-    if (fatal_error != ""):
+    if fatal_error != "":
         pytest.skip(fatal_error)
 
-    if os.environ.get('TOPOTESTS_CHECK_MEMLEAK') is None:
-        print("SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n")
-        pytest.skip('Skipping test for memory leaks')
-    
+    if os.environ.get("TOPOTESTS_CHECK_MEMLEAK") is None:
+        print(
+            "SKIPPED final check on Memory leaks: Disabled (TOPOTESTS_CHECK_MEMLEAK undefined)\n"
+        )
+        pytest.skip("Skipping test for memory leaks")
+
     thisDir = os.path.dirname(os.path.realpath(__file__))
 
     for i in range(1, 2):
-        net['r%s' % i].stopRouter()
-        net['r%s' % i].report_memory_leaks(os.environ.get('TOPOTESTS_CHECK_MEMLEAK'), os.path.basename(__file__))
+        net["r%s" % i].stopRouter()
+        net["r%s" % i].report_memory_leaks(
+            os.environ.get("TOPOTESTS_CHECK_MEMLEAK"), os.path.basename(__file__)
+        )
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
 
-    setLogLevel('info')
+    setLogLevel("info")
     # 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"])
index 3219371d2ee49327c467b96c0e3354bd624fbae2..8026aad49d3eb7bdeeaf8217e6a16c51bc54a103 100644 (file)
@@ -30,6 +30,7 @@ interface eth-rt3
  isis bfd
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0001.00
  is-type level-1
 !
index 63ccb640a451b751341d19ff8e265f435ba6a31a..b0fde64a5e7fb2a729b3028d5c4f7d39bcdb5ae3 100644 (file)
@@ -25,6 +25,7 @@ interface eth-rt5
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0002.00
  is-type level-1
 !
index 928f1e1a2bf1f9da83031ee2cc0373182e752dd6..5c36e96c0f522115946be36113aa15f36fb7f335 100644 (file)
@@ -26,6 +26,7 @@ interface eth-rt4
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0003.00
  is-type level-1
 !
index fde97478a9f8ef0fbb87d2291c3323e7a43d9851..3eac407776c72b26fe08dff58beeae123890b95c 100644 (file)
@@ -24,6 +24,7 @@ interface eth-rt5
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0004.00
  is-type level-1
 !
index fd00cb1ddbbb1a0f41bd27cbf697c8b127e4c890..5d449f6f93fbf3b9eda28b95c9b0b50e1f447f88 100644 (file)
@@ -24,6 +24,7 @@ interface eth-rt4
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0005.00
  is-type level-1
 !
index d27a783adf90198e12b2df53fc883b3ecc988876..ca965e3956921e4f197d525786bba83ff9080835 100644 (file)
@@ -11,6 +11,7 @@ interface r3-eth1
  isis bfd profile fasttx
 !
 router isis lan
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
  redistribute ipv6 connected level-1
 !
index 01e197bed5c1e208bd7e7d482e731f33374c11c2..d8ffc9bc2c0ed2a7400cb30b220d5e133a58f670 100644 (file)
@@ -11,6 +11,7 @@ interface r4-eth0
  isis bfd profile DOES_NOT_EXIST
 !
 router isis lan
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
  redistribute ipv6 connected level-1
 !
index 514933b891adbbe5d2df1fbe7ec59d2842393f47..bd3b876eeb117c9fbc9f9a0135ea2ca7be48da1c 100644 (file)
@@ -118,6 +118,7 @@ def teardown_module(_mod):
     tgen = get_topogen()
     tgen.stop_topology()
 
+
 def test_wait_protocols_convergence():
     "Wait for all protocols to converge"
     tgen = get_topogen()
@@ -128,41 +129,40 @@ def test_wait_protocols_convergence():
 
     def expect_loopback_route(router, iptype, route, proto):
         "Wait until route is present on RIB for protocol."
-        logger.info('waiting route {} in {}'.format(route, router))
+        logger.info("waiting route {} in {}".format(route, router))
         test_func = partial(
             topotest.router_json_cmp,
             tgen.gears[router],
-            'show {} route json'.format(iptype),
-            { route: [{ 'protocol': proto }] }
+            "show {} route json".format(iptype),
+            {route: [{"protocol": proto}]},
         )
         _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
         assertmsg = '"{}" OSPF convergence failure'.format(router)
         assert result is None, assertmsg
 
-
     # Wait for R1 <-> R6 convergence.
-    expect_loopback_route('r1', 'ip', '10.254.254.6/32', 'ospf')
+    expect_loopback_route("r1", "ip", "10.254.254.6/32", "ospf")
 
     # Wait for R6 <-> R1 convergence.
-    expect_loopback_route('r6', 'ip', '10.254.254.1/32', 'ospf')
+    expect_loopback_route("r6", "ip", "10.254.254.1/32", "ospf")
 
     # Wait for R2 <-> R3 convergence.
-    expect_loopback_route('r2', 'ip', '10.254.254.3/32', 'bgp')
+    expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
 
     # Wait for R3 <-> R2 convergence.
-    expect_loopback_route('r3', 'ip', '10.254.254.2/32', 'bgp')
+    expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp")
 
     # Wait for R3 <-> R4 convergence.
-    expect_loopback_route('r3', 'ipv6', '2001:db8:3::/64', 'isis')
+    expect_loopback_route("r3", "ipv6", "2001:db8:3::/64", "isis")
 
     # Wait for R4 <-> R3 convergence.
-    expect_loopback_route('r4', 'ipv6', '2001:db8:1::/64', 'isis')
+    expect_loopback_route("r4", "ipv6", "2001:db8:1::/64", "isis")
 
     # Wait for R4 <-> R5 convergence.
-    expect_loopback_route('r4', 'ipv6', '2001:db8:3::/64', 'ospf6')
+    expect_loopback_route("r4", "ipv6", "2001:db8:3::/64", "ospf6")
 
     # Wait for R5 <-> R4 convergence.
-    expect_loopback_route('r5', 'ipv6', '2001:db8:2::/64', 'ospf6')
+    expect_loopback_route("r5", "ipv6", "2001:db8:2::/64", "ospf6")
 
 
 def test_bfd_profile_values():
index fa68ace59d841c2e0b89c91d6894159804a1b35c..f473b6710878a21ae9e443981d06bdead1e66735 100644 (file)
@@ -103,44 +103,44 @@ def test_wait_bgp_convergence():
 
     def expect_loopback_route(router, iptype, route, proto):
         "Wait until route is present on RIB for protocol."
-        logger.info('waiting route {} in {}'.format(route, router))
+        logger.info("waiting route {} in {}".format(route, router))
         test_func = partial(
             topotest.router_json_cmp,
             tgen.gears[router],
-            'show {} route json'.format(iptype),
-            { route: [{ 'protocol': proto }] }
+            "show {} route json".format(iptype),
+            {route: [{"protocol": proto}]},
         )
         _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
         assertmsg = '"{}" OSPF convergence failure'.format(router)
         assert result is None, assertmsg
 
     # Wait for R1 <-> R2 convergence.
-    expect_loopback_route('r1', 'ip', '10.254.254.2/32', 'bgp')
+    expect_loopback_route("r1", "ip", "10.254.254.2/32", "bgp")
     # Wait for R1 <-> R3 convergence.
-    expect_loopback_route('r1', 'ip', '10.254.254.3/32', 'bgp')
+    expect_loopback_route("r1", "ip", "10.254.254.3/32", "bgp")
     # Wait for R1 <-> R4 convergence.
-    expect_loopback_route('r1', 'ip', '10.254.254.4/32', 'bgp')
+    expect_loopback_route("r1", "ip", "10.254.254.4/32", "bgp")
 
     # Wait for R2 <-> R1 convergence.
-    expect_loopback_route('r2', 'ip', '10.254.254.1/32', 'bgp')
+    expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp")
     # Wait for R2 <-> R3 convergence.
-    expect_loopback_route('r2', 'ip', '10.254.254.3/32', 'bgp')
+    expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
     # Wait for R2 <-> R4 convergence.
-    expect_loopback_route('r2', 'ip', '10.254.254.4/32', 'bgp')
+    expect_loopback_route("r2", "ip", "10.254.254.4/32", "bgp")
 
     # Wait for R3 <-> R1 convergence.
-    expect_loopback_route('r3', 'ip', '10.254.254.1/32', 'bgp')
+    expect_loopback_route("r3", "ip", "10.254.254.1/32", "bgp")
     # Wait for R3 <-> R2 convergence.
-    expect_loopback_route('r3', 'ip', '10.254.254.2/32', 'bgp')
+    expect_loopback_route("r3", "ip", "10.254.254.2/32", "bgp")
     # Wait for R3 <-> R4 convergence.
-    expect_loopback_route('r3', 'ip', '10.254.254.4/32', 'bgp')
+    expect_loopback_route("r3", "ip", "10.254.254.4/32", "bgp")
 
     # Wait for R4 <-> R1 convergence.
-    expect_loopback_route('r4', 'ip', '10.254.254.1/32', 'bgp')
+    expect_loopback_route("r4", "ip", "10.254.254.1/32", "bgp")
     # Wait for R4 <-> R2 convergence.
-    expect_loopback_route('r4', 'ip', '10.254.254.2/32', 'bgp')
+    expect_loopback_route("r4", "ip", "10.254.254.2/32", "bgp")
     # Wait for R4 <-> R3 convergence.
-    expect_loopback_route('r4', 'ip', '10.254.254.3/32', 'bgp')
+    expect_loopback_route("r4", "ip", "10.254.254.3/32", "bgp")
 
 
 def test_wait_bfd_convergence():
@@ -153,22 +153,22 @@ def test_wait_bfd_convergence():
 
     def expect_bfd_configuration(router):
         "Load JSON file and compare with 'show bfd peer json'"
-        logger.info('waiting BFD configuration on router {}'.format(router))
-        bfd_config = json.loads(open('{}/{}/bfd-peers.json'.format(CWD, router)).read())
+        logger.info("waiting BFD configuration on router {}".format(router))
+        bfd_config = json.loads(open("{}/{}/bfd-peers.json".format(CWD, router)).read())
         test_func = partial(
             topotest.router_json_cmp,
             tgen.gears[router],
-            'show bfd peers json',
-            bfd_config
+            "show bfd peers json",
+            bfd_config,
         )
         _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
         assertmsg = '"{}" BFD configuration failure'.format(router)
         assert result is None, assertmsg
 
-    expect_bfd_configuration('r1')
-    expect_bfd_configuration('r2')
-    expect_bfd_configuration('r3')
-    expect_bfd_configuration('r4')
+    expect_bfd_configuration("r1")
+    expect_bfd_configuration("r2")
+    expect_bfd_configuration("r3")
+    expect_bfd_configuration("r4")
 
 
 def teardown_module(_mod):
index 286af3bf65971fea912de3c0807e1a75bb2f1a38..559cf4fb1bb3c7ad2970eb694b724aaa96943781 100644 (file)
@@ -270,7 +270,7 @@ def peer_name(rtr, prefix, vrf):
 
 def print_diag(vrf):
     "print failure disagnostics"
-    
+
     tgen = get_topogen()
     router_list = tgen.routers()
     for rname, router in router_list.items():
@@ -330,7 +330,7 @@ def clear_ospf(vrf=""):
 
 def check_neigh_state(router, peer, state, vrf=""):
     "check BGP neighbor state on a router"
-    
+
     count = 0
     matched = False
     neigh_output = ""
index 41fa7c0a0950b74d452eb3f71a868ff5e5db97e1..b3b7256ac44dc476429971f3f6a7a84ed85dc9b3 100644 (file)
@@ -76,7 +76,7 @@ from lib.common_config import (
     create_prefix_lists,
     create_route_maps,
     verify_bgp_community,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import (
@@ -139,7 +139,7 @@ def setup_module(mod):
     """
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
@@ -567,7 +567,7 @@ def test_BGP_attributes_with_vrf_default_keyword_p0(request):
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    #reset_config_on_routers(tgen)
+    # reset_config_on_routers(tgen)
 
     step("Configure static routes and redistribute in BGP on R3")
     for addr_type in ADDR_TYPES:
index eed118ebdc4cf36d936120fc6aa4d23351a320a9..12069a12dcf41ae43c449f09eb1d0da7c0a679c8 100644 (file)
@@ -61,7 +61,7 @@ from lib.common_config import (
     check_address_types,
     interface_status,
     reset_config_on_routers,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
@@ -110,7 +110,7 @@ def setup_module(mod):
     global ADDR_TYPES
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
@@ -144,9 +144,7 @@ def setup_module(mod):
     )
 
     link_data = [
-        val
-        for links, val in topo["routers"]["r2"]["links"].items()
-        if "r3" in links
+        val for links, val in topo["routers"]["r2"]["links"].items() if "r3" in links
     ]
     for adt in ADDR_TYPES:
         NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data]
@@ -161,9 +159,7 @@ def setup_module(mod):
     INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1]))
 
     link_data = [
-        val
-        for links, val in topo["routers"]["r3"]["links"].items()
-        if "r2" in links
+        val for links, val in topo["routers"]["r3"]["links"].items() if "r2" in links
     ]
     INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data]
     INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1]))
index 7357c33824b972f602973fc008d5326208c0838b..50aa281d341fed3c055b4690fd4fddf37d4f05fb 100644 (file)
@@ -61,7 +61,7 @@ from lib.common_config import (
     check_address_types,
     interface_status,
     reset_config_on_routers,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp
@@ -110,7 +110,7 @@ def setup_module(mod):
     global ADDR_TYPES
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
@@ -145,9 +145,7 @@ def setup_module(mod):
         )
 
     link_data = [
-        val
-        for links, val in topo["routers"]["r2"]["links"].items()
-        if "r3" in links
+        val for links, val in topo["routers"]["r2"]["links"].items() if "r3" in links
     ]
     for adt in ADDR_TYPES:
         NEXT_HOPS[adt] = [val[adt].split("/")[0] for val in link_data]
@@ -162,9 +160,7 @@ def setup_module(mod):
     INTF_LIST_R2 = sorted(INTF_LIST_R2, key=lambda x: int(x.split("eth")[1]))
 
     link_data = [
-        val
-        for links, val in topo["routers"]["r3"]["links"].items()
-        if "r2" in links
+        val for links, val in topo["routers"]["r3"]["links"].items() if "r2" in links
     ]
     INTF_LIST_R3 = [val["interface"].split("/")[0] for val in link_data]
     INTF_LIST_R3 = sorted(INTF_LIST_R3, key=lambda x: int(x.split("eth")[1]))
index 9af22c06bda5e6e9911318c956ae917f43f3696a..4c56d1a02d81cc0ae60694d9c143501657da3d0f 100644 (file)
@@ -57,13 +57,13 @@ from mininet.topo import Topo
 
 
 class NetworkTopo(Topo):
-    '''
+    """
     EVPN Multihoming Topology -
     1. Two level CLOS
     2. Two spine switches - spine1, spine2
     3. Two racks with Top-of-Rack switches per rack - tormx1, tormx2
     4. Two dual attached hosts per-rack - hostdx1, hostdx2
-    '''
+    """
 
     def build(self, **_opts):
         "Build function"
@@ -84,7 +84,6 @@ class NetworkTopo(Topo):
         # On main router
         # First switch is for a dummy interface (for local network)
 
-
         ##################### spine1 ########################
         # spine1-eth0 is connected to torm11-eth0
         switch = tgen.add_switch("sw1")
@@ -178,38 +177,44 @@ class NetworkTopo(Topo):
 ##
 #####################################################
 
-tor_ips = {"torm11" : "192.168.100.15", \
-           "torm12" : "192.168.100.16", \
-           "torm21" : "192.168.100.17", \
-           "torm22" : "192.168.100.18"}
+tor_ips = {
+    "torm11": "192.168.100.15",
+    "torm12": "192.168.100.16",
+    "torm21": "192.168.100.17",
+    "torm22": "192.168.100.18",
+}
+
+svi_ips = {
+    "torm11": "45.0.0.2",
+    "torm12": "45.0.0.3",
+    "torm21": "45.0.0.4",
+    "torm22": "45.0.0.5",
+}
 
-svi_ips = {"torm11" : "45.0.0.2", \
-           "torm12" : "45.0.0.3", \
-           "torm21" : "45.0.0.4", \
-           "torm22" : "45.0.0.5"}
+tor_ips_rack_1 = {"torm11": "192.168.100.15", "torm12": "192.168.100.16"}
 
-tor_ips_rack_1 = {"torm11" : "192.168.100.15", \
-           "torm12" : "192.168.100.16"}
+tor_ips_rack_2 = {"torm21": "192.168.100.17", "torm22": "192.168.100.18"}
 
-tor_ips_rack_2 = {"torm21" : "192.168.100.17", \
-           "torm22" : "192.168.100.18"}
+host_es_map = {
+    "hostd11": "03:44:38:39:ff:ff:01:00:00:01",
+    "hostd12": "03:44:38:39:ff:ff:01:00:00:02",
+    "hostd21": "03:44:38:39:ff:ff:02:00:00:01",
+    "hostd22": "03:44:38:39:ff:ff:02:00:00:02",
+}
 
-host_es_map = {"hostd11" : "03:44:38:39:ff:ff:01:00:00:01",
-            "hostd12" : "03:44:38:39:ff:ff:01:00:00:02",
-            "hostd21" : "03:44:38:39:ff:ff:02:00:00:01",
-            "hostd22" : "03:44:38:39:ff:ff:02:00:00:02"}
 
 def config_bond(node, bond_name, bond_members, bond_ad_sys_mac, br):
-    '''
+    """
     Used to setup bonds on the TORs and hosts for MH
-    '''
+    """
     node.run("ip link add dev %s type bond mode 802.3ad" % bond_name)
     node.run("ip link set dev %s type bond lacp_rate 1" % bond_name)
     node.run("ip link set dev %s type bond miimon 100" % bond_name)
     node.run("ip link set dev %s type bond xmit_hash_policy layer3+4" % bond_name)
     node.run("ip link set dev %s type bond min_links 1" % bond_name)
-    node.run("ip link set dev %s type bond ad_actor_system %s" %\
-            (bond_name, bond_ad_sys_mac))
+    node.run(
+        "ip link set dev %s type bond ad_actor_system %s" % (bond_name, bond_ad_sys_mac)
+    )
 
     for bond_member in bond_members:
         node.run("ip link set dev %s down" % bond_member)
@@ -225,15 +230,14 @@ def config_bond(node, bond_name, bond_members, bond_ad_sys_mac, br):
         node.run("/sbin/bridge vlan del vid 1 dev %s" % bond_name)
         node.run("/sbin/bridge vlan del vid 1 untagged pvid dev %s" % bond_name)
         node.run("/sbin/bridge vlan add vid 1000 dev %s" % bond_name)
-        node.run("/sbin/bridge vlan add vid 1000 untagged pvid dev %s"\
-                % bond_name)
+        node.run("/sbin/bridge vlan add vid 1000 untagged pvid dev %s" % bond_name)
 
 
 def config_mcast_tunnel_termination_device(node):
-    '''
+    """
     The kernel requires a device to terminate VxLAN multicast tunnels
     when EVPN-PIM is used for flooded traffic
-    '''
+    """
     node.run("ip link add dev ipmr-lo type dummy")
     node.run("ip link set dev ipmr-lo mtu 16000")
     node.run("ip link set dev ipmr-lo mode dormant")
@@ -241,9 +245,9 @@ def config_mcast_tunnel_termination_device(node):
 
 
 def config_bridge(node):
-    '''
+    """
     Create a VLAN aware bridge
-    '''
+    """
     node.run("ip link add dev bridge type bridge stp_state 0")
     node.run("ip link set dev bridge type bridge vlan_filtering 1")
     node.run("ip link set dev bridge mtu 9216")
@@ -255,10 +259,10 @@ def config_bridge(node):
 
 
 def config_vxlan(node, node_ip):
-    '''
+    """
     Create a VxLAN device for VNI 1000 and add it to the bridge.
     VLAN-1000 is mapped to VNI-1000.
-    '''
+    """
     node.run("ip link add dev vx-1000 type vxlan id 1000 dstport 4789")
     node.run("ip link set dev vx-1000 type vxlan nolearning")
     node.run("ip link set dev vx-1000 type vxlan local %s" % node_ip)
@@ -279,9 +283,9 @@ def config_vxlan(node, node_ip):
 
 
 def config_svi(node, svi_pip):
-    '''
+    """
     Create an SVI for VLAN 1000
-    '''
+    """
     node.run("ip link add link bridge name vlan1000 type vlan id 1000 protocol 802.1q")
     node.run("ip addr add %s/24 dev vlan1000" % svi_pip)
     node.run("ip link set dev vlan1000 up")
@@ -297,9 +301,9 @@ def config_svi(node, svi_pip):
 
 
 def config_tor(tor_name, tor, tor_ip, svi_pip):
-    '''
+    """
     Create the bond/vxlan-bridge on the TOR which acts as VTEP and EPN-PE
-    '''
+    """
     # create a device for terminating VxLAN multicast tunnels
     config_mcast_tunnel_termination_device(tor)
 
@@ -329,17 +333,19 @@ def config_tors(tgen, tors):
         tor = tgen.gears[tor_name]
         config_tor(tor_name, tor, tor_ips.get(tor_name), svi_ips.get(tor_name))
 
+
 def compute_host_ip_mac(host_name):
     host_id = host_name.split("hostd")[1]
-    host_ip = "45.0.0."+ host_id + "/24"
+    host_ip = "45.0.0." + host_id + "/24"
     host_mac = "00:00:00:00:00:" + host_id
 
     return host_ip, host_mac
 
+
 def config_host(host_name, host):
-    '''
+    """
     Create the dual-attached bond on host nodes for MH
-    '''
+    """
     bond_members = []
     bond_members.append(host_name + "-eth0")
     bond_members.append(host_name + "-eth1")
@@ -407,9 +413,9 @@ def teardown_module(_mod):
 
 
 def check_local_es(esi, vtep_ips, dut_name, down_vteps):
-    '''
+    """
     Check if ES peers are setup correctly on local ESs
-    '''
+    """
     peer_ips = []
     if "torm1" in dut_name:
         tor_ips_rack = tor_ips_rack_1
@@ -432,9 +438,9 @@ def check_local_es(esi, vtep_ips, dut_name, down_vteps):
 
 
 def check_remote_es(esi, vtep_ips, dut_name, down_vteps):
-    '''
+    """
     Verify list of PEs associated with a remote ES
-    '''
+    """
     remote_ips = []
 
     if "torm1" in dut_name:
@@ -455,10 +461,11 @@ def check_remote_es(esi, vtep_ips, dut_name, down_vteps):
 
     return (esi, diff) if diff else None
 
+
 def check_es(dut):
-    '''
+    """
     Verify list of PEs associated all ESs, local and remote
-    '''
+    """
     bgp_es = dut.vtysh_cmd("show bgp l2vp evpn es json")
     bgp_es_json = json.loads(bgp_es)
 
@@ -490,10 +497,11 @@ def check_es(dut):
 
     return result if result else None
 
+
 def check_one_es(dut, esi, down_vteps):
-    '''
+    """
     Verify list of PEs associated all ESs, local and remote
-    '''
+    """
     bgp_es = dut.vtysh_cmd("show bgp l2vp evpn es %s json" % esi)
     es = json.loads(bgp_es)
 
@@ -513,12 +521,13 @@ def check_one_es(dut, esi, down_vteps):
 
     return result
 
+
 def test_evpn_es():
-    '''
+    """
     Two ES are setup on each rack. This test checks if -
     1. ES peer has been added to the local ES (via Type-1/EAD route)
     2. The remote ESs are setup with the right list of PEs (via Type-1)
-    '''
+    """
 
     tgen = get_topogen()
 
@@ -534,11 +543,12 @@ def test_evpn_es():
     assert result is None, assertmsg
     # tgen.mininet_cli()
 
+
 def test_evpn_ead_update():
-    '''
+    """
     Flap a host link one the remote rack and check if the EAD updates
     are sent/processed for the corresponding ESI
-    '''
+    """
     tgen = get_topogen()
 
     if tgen.routers_have_failure():
@@ -580,30 +590,32 @@ def test_evpn_ead_update():
 
     # tgen.mininet_cli()
 
+
 def check_mac(dut, vni, mac, m_type, esi, intf):
-    '''
+    """
     checks if mac is present and if desination matches the one provided
-    '''
+    """
 
     out = dut.vtysh_cmd("show evpn mac vni %d mac %s json" % (vni, mac))
 
     mac_js = json.loads(out)
     for mac, info in mac_js.items():
         tmp_esi = info.get("esi", "")
-        tmp_m_type =  info.get("type", "")
+        tmp_m_type = info.get("type", "")
         tmp_intf = info.get("intf", "") if tmp_m_type == "local" else ""
         if tmp_esi == esi and tmp_m_type == m_type and intf == intf:
             return None
 
     return "invalid vni %d mac %s out %s" % (vni, mac, mac_js)
 
+
 def test_evpn_mac():
-    '''
+    """
     1. Add a MAC on hostd11 and check if the MAC is synced between
     torm11 and torm12. And installed as a local MAC.
     2. Add a MAC on hostd21 and check if the MAC is installed as a
     remote MAC on torm11 and torm12
-    '''
+    """
 
     tgen = get_topogen()
 
@@ -646,6 +658,126 @@ def test_evpn_mac():
         assertmsg = '"{}" remote MAC content incorrect'.format(tor.name)
         assert result is None, assertmsg
 
+def check_df_role(dut, esi, role):
+    '''
+    Return error string if the df role on the dut is different
+    '''
+    es_json = dut.vtysh_cmd("show evpn es %s json" % esi)
+    es = json.loads(es_json)
+
+    if not es:
+        return "esi %s not found" % esi
+
+    flags = es.get("flags", [])
+    curr_role = "nonDF" if "nonDF" in flags else "DF"
+
+    if curr_role != role:
+        return "%s is %s for %s" % (dut.name, curr_role, esi)
+
+    return None
+
+def test_evpn_df():
+    '''
+    1. Check the DF role on all the PEs on rack-1.
+    2. Increase the DF preference on the non-DF and check if it becomes
+       the DF winner.
+    '''
+
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # We will run the tests on just one ES
+    esi = host_es_map.get("hostd11")
+    intf = "hostbond1"
+
+    tors = []
+    tors.append(tgen.gears["torm11"])
+    tors.append(tgen.gears["torm12"])
+    df_node = "torm11"
+
+    # check roles on rack-1
+    for tor in tors:
+        role = "DF" if tor.name == df_node else "nonDF"
+        test_fn = partial(check_df_role, tor, esi, role)
+        _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3)
+        assertmsg = '"{}" DF role incorrect'.format(tor.name)
+        assert result is None, assertmsg
+
+    # change df preference on the nonDF to make it the df
+    torm12 = tgen.gears["torm12"]
+    torm12.vtysh_cmd("conf\ninterface %s\nevpn mh es-df-pref %d" % (intf, 60000))
+    df_node = "torm12"
+
+    # re-check roles on rack-1; we should have a new winner
+    for tor in tors:
+        role = "DF" if tor.name == df_node else "nonDF"
+        test_fn = partial(check_df_role, tor, esi, role)
+        _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3)
+        assertmsg = '"{}" DF role incorrect'.format(tor.name)
+        assert result is None, assertmsg
+
+    # tgen.mininet_cli()
+
+def check_protodown_rc(dut, protodown_rc):
+    '''
+    check if specified protodown reason code is set
+    '''
+
+    out = dut.vtysh_cmd("show evpn json")
+
+    evpn_js = json.loads(out)
+    tmp_rc = evpn_js.get("protodownReasons", [])
+
+    if protodown_rc:
+        if protodown_rc not in tmp_rc:
+            return "protodown %s missing in %s" % (protodown_rc, tmp_rc)
+    else:
+        if tmp_rc:
+            return "unexpected protodown rc %s" % (tmp_rc)
+
+    return None
+
+def test_evpn_uplink_tracking():
+    '''
+    1. Wait for access ports to come out of startup-delay
+    2. disable uplinks and check if access ports have been protodowned
+    3. enable uplinks and check if access ports have been moved out
+       of protodown
+    '''
+
+    tgen = get_topogen()
+
+    dut_name = "torm11"
+    dut = tgen.gears[dut_name]
+
+    # wait for protodown rc to clear after startup
+    test_fn = partial(check_protodown_rc, dut, None)
+    _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3)
+    assertmsg = '"{}" protodown rc incorrect'.format(dut_name)
+    assert result is None, assertmsg
+
+    # disable the uplinks
+    dut.run("ip link set %s-eth0 down" % dut_name)
+    dut.run("ip link set %s-eth1 down" % dut_name)
+
+    # check if the access ports have been protodowned
+    test_fn = partial(check_protodown_rc, dut, "uplinkDown")
+    _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3)
+    assertmsg = '"{}" protodown rc incorrect'.format(dut_name)
+    assert result is None, assertmsg
+
+    # enable the uplinks
+    dut.run("ip link set %s-eth0 up" % dut_name)
+    dut.run("ip link set %s-eth1 up" % dut_name)
+
+    # check if the access ports have been moved out of protodown
+    test_fn = partial(check_protodown_rc, dut, None)
+    _, result = topotest.run_and_expect(test_fn, None, count=20, wait=3)
+    assertmsg = '"{}" protodown rc incorrect'.format(dut_name)
+    assert result is None, assertmsg
+
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index ee4e87e1c29e81f10f9283c8c5e2c99a1d4957e4..33e89c06ae1bcd34c751d0b4ff6b5083c253966c 100644 (file)
@@ -4,11 +4,15 @@ debug zebra evpn mh neigh
 debug zebra evpn mh nh
 debug zebra vxlan
 !
+evpn mh startup-delay 1
+!
 int torm11-eth0
   ip addr 192.168.1.2/24
+  evpn mh uplink
 !
 int torm11-eth1
   ip addr 192.168.5.2/24
+  evpn mh uplink
 !
 int lo
   ip addr 192.168.100.15/32
index 736af4159e959bc3ceb304d58144e80dc5a1526f..419f62b2aceedc871e0600224a37b20963740aad 100644 (file)
@@ -4,11 +4,16 @@ debug zebra evpn mh neigh
 debug zebra evpn mh nh
 debug zebra vxlan
 !
+evpn mh startup-delay 1
+!
 int torm12-eth0
   ip addr 192.168.2.2/24
+  evpn mh uplink
 !
 int torm12-eth1
   ip addr 192.168.6.2/24
+  evpn mh uplink
+!
 !
 int lo
   ip addr 192.168.100.16/32
index 0ebe6f2d956088efa491bb0bfe24d9844ef6ead3..525f5eb0998c36f4671801704381ec20e6574239 100644 (file)
@@ -4,11 +4,17 @@ debug zebra evpn mh neigh
 debug zebra evpn mh nh
 debug zebra vxlan
 !
+evpn mh startup-delay 1
+!
 int torm21-eth0
   ip addr 192.168.3.2/24
+  evpn mh uplink
+!
 !
 int torm21-eth1
   ip addr 192.168.7.2/24
+  evpn mh uplink
+!
 !
 int lo
   ip addr 192.168.100.17/32
index b4f4f1dc25c5999f0c957b36d4b2a5960bb51970..432135c94a79210ba00d3cb399d50242f4be20d2 100644 (file)
@@ -5,7 +5,6 @@ debug bgp evpn mh es
 debug bgp evpn mh route
 debug bgp zebra
 !
-!
 router bgp 65005
   bgp router-id 192.168.100.18
   no bgp ebgp-requires-policy
index 356d8a43e7bad48efbc139095ffc12b0b1e0e6cf..398064df6c3037577abbd42f8b72d46b48fd0b75 100644 (file)
@@ -4,11 +4,17 @@ debug zebra evpn mh neigh
 debug zebra evpn mh nh
 debug zebra vxlan
 !
+evpn mh startup-delay 1
+!
 int torm22-eth0
   ip addr 192.168.4.2/24
+  evpn mh uplink
+!
 !
 int torm22-eth1
   ip addr 192.168.8.2/24
+  evpn mh uplink
+!
 !
 int lo
   ip addr 192.168.100.18/32
old mode 100644 (file)
new mode 100755 (executable)
index 2a14105..5098808
@@ -197,8 +197,12 @@ def mac_learn_test(host, local):
 
     host_output = host.vtysh_cmd("show interface {}-eth0".format(host.name))
     int_lines = host_output.splitlines()
-    line_items = int_lines[7].split(": ")
-    mac = line_items[1]
+    for line in int_lines:
+        line_items = line.split(": ")
+        if "HWaddr" in line_items[0]:
+            mac = line_items[1]
+            break
+
     mac_output = local.vtysh_cmd("show evpn mac vni 101 mac {} json".format(mac))
     mac_output_json = json.loads(mac_output)
     assertmsg = "Local MAC output does not match interface mac {}".format(mac)
@@ -287,8 +291,11 @@ def ip_learn_test(tgen, host, local, remote, ip_addr):
     "check the host IP gets learned by the VNI"
     host_output = host.vtysh_cmd("show interface {}-eth0".format(host.name))
     int_lines = host_output.splitlines()
-    mac_line = int_lines[7].split(": ")
-    mac = mac_line[1]
+    for line in int_lines:
+        line_items = line.split(": ")
+        if "HWaddr" in line_items[0]:
+            mac = line_items[1]
+            break
     print(host_output)
 
     # check we have a local association between the MAC and IP
index 5aa1bdf32921c2bd27f06ca0aaac220088bcfdec..36f1d8cd566c009671d0e9a548135102c374786a 100644 (file)
@@ -90,84 +90,36 @@ def test_vrf_route_leak():
 
     # Test DONNA VRF.
     expect = {
-        '10.0.0.0/24': [
-            {
-                'protocol': 'connected',
-            }
+        "10.0.0.0/24": [{"protocol": "connected",}],
+        "10.0.1.0/24": [
+            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
         ],
-        '10.0.1.0/24': [
-            {
-                'protocol': 'bgp',
-                'selected': True,
-                'nexthops': [
-                    {
-                        'fib': True
-                    }
-                ]
-            }
+        "10.0.2.0/24": [{"protocol": "connected"}],
+        "10.0.3.0/24": [
+            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
         ],
-        '10.0.2.0/24': [
-            {
-                'protocol': 'connected'
-            }
-        ],
-        '10.0.3.0/24': [
-            {
-                'protocol': 'bgp',
-                'selected': True,
-                'nexthops': [
-                    {
-                        'fib': True
-                    }
-                ]
-            }
-        ]
     }
 
     test_func = partial(
-        topotest.router_json_cmp, r1, 'show ip route vrf DONNA json', expect
+        topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect
     )
     result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
     assert result, "BGP VRF DONNA check failed:\n{}".format(diff)
 
     # Test EVA VRF.
     expect = {
-        '10.0.0.0/24': [
-            {
-                'protocol': 'bgp',
-                'selected': True,
-                'nexthops': [
-                    {
-                        'fib': True
-                    }
-                ]
-            }
-        ],
-        '10.0.1.0/24': [
-            {
-                'protocol': 'connected',
-            }
+        "10.0.0.0/24": [
+            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
         ],
-        '10.0.2.0/24': [
-            {
-                'protocol': 'bgp',
-                'selected': True,
-                'nexthops': [
-                    {
-                        'fib': True
-                    }
-                ]
-            }
+        "10.0.1.0/24": [{"protocol": "connected",}],
+        "10.0.2.0/24": [
+            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}
         ],
-        '10.0.3.0/24': [
-            {
-                'protocol': 'connected',
-            }
-        ]
+        "10.0.3.0/24": [{"protocol": "connected",}],
     }
 
     test_func = partial(
-        topotest.router_json_cmp, r1, 'show ip route vrf EVA json', expect
+        topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect
     )
     result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
     assert result, "BGP VRF EVA check failed:\n{}".format(diff)
diff --git a/tests/topotests/bgp_aggregate_address_topo1/__init__.py b/tests/topotests/bgp_aggregate_address_topo1/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_aggregate_address_topo1/exabgp.env b/tests/topotests/bgp_aggregate_address_topo1/exabgp.env
new file mode 100644 (file)
index 0000000..28e6423
--- /dev/null
@@ -0,0 +1,53 @@
+[exabgp.api]
+encoder = text
+highres = false
+respawn = false
+socket = ''
+
+[exabgp.bgp]
+openwait = 60
+
+[exabgp.cache]
+attributes = true
+nexthops = true
+
+[exabgp.daemon]
+daemonize = true
+pid = '/var/run/exabgp/exabgp.pid'
+user = 'exabgp'
+##daemonize = false
+
+[exabgp.log]
+all = false
+configuration = true
+daemon = true
+destination = '/var/log/exabgp.log'
+enable = true
+level = INFO
+message = false
+network = true
+packets = false
+parser = false
+processes = true
+reactor = true
+rib = false
+routes = false
+short = false
+timers = false
+
+[exabgp.pdb]
+enable = false
+
+[exabgp.profile]
+enable = false
+file = ''
+
+[exabgp.reactor]
+speed = 1.0
+
+[exabgp.tcp]
+acl = false
+bind = ''
+delay = 0
+once = false
+port = 179
diff --git a/tests/topotests/bgp_aggregate_address_topo1/peer1/exabgp.cfg b/tests/topotests/bgp_aggregate_address_topo1/peer1/exabgp.cfg
new file mode 100644 (file)
index 0000000..e0f6ab6
--- /dev/null
@@ -0,0 +1,21 @@
+neighbor 10.0.0.1 {
+  router-id 10.254.254.3;
+  local-address 10.0.0.2;
+  local-as 65001;
+  peer-as 65000;
+  static {
+    route 10.254.254.3/32 next-hop 10.0.0.2;
+
+    route 192.168.0.1/32 next-hop 10.0.0.2 med 10;
+    route 192.168.0.2/32 next-hop 10.0.0.2 med 10;
+    route 192.168.0.3/32 next-hop 10.0.0.2 med 10;
+
+    route 192.168.1.1/32 next-hop 10.0.0.2 med 10;
+    route 192.168.1.2/32 next-hop 10.0.0.2 med 10;
+    route 192.168.1.3/32 next-hop 10.0.0.2 med 20;
+
+    route 192.168.2.1/32 next-hop 10.0.0.2;
+    route 192.168.2.2/32 next-hop 10.0.0.2;
+    route 192.168.2.3/32 next-hop 10.0.0.2;
+  }
+}
diff --git a/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf b/tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..fa52150
--- /dev/null
@@ -0,0 +1,30 @@
+debug bgp updates
+!
+access-list acl-sup-one seq 5 permit 192.168.2.1/32
+access-list acl-sup-one seq 10 deny any
+!
+access-list acl-sup-two seq 5 permit 192.168.2.2/32
+access-list acl-sup-two seq 10 deny any
+!
+access-list acl-sup-three seq 5 permit 192.168.2.3/32
+access-list acl-sup-three seq 10 deny any
+!
+route-map rm-sup-one permit 10
+ match ip address acl-sup-one
+!
+route-map rm-sup-two permit 10
+ match ip address acl-sup-two
+!
+router bgp 65000
+  no bgp ebgp-requires-policy
+  neighbor 10.0.0.2 remote-as 65001
+  neighbor 10.0.0.2 timers 3 10
+  neighbor 10.0.1.2 remote-as internal
+  neighbor 10.0.1.2 timers 3 10
+  address-family ipv4 unicast
+   redistribute connected
+   aggregate-address 192.168.0.0/24 matching-MED-only
+   aggregate-address 192.168.1.0/24 matching-MED-only
+   aggregate-address 192.168.2.0/24 suppress-map rm-sup-one
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_aggregate_address_topo1/r1/zebra.conf b/tests/topotests/bgp_aggregate_address_topo1/r1/zebra.conf
new file mode 100644 (file)
index 0000000..931c73d
--- /dev/null
@@ -0,0 +1,13 @@
+!
+interface lo
+ ip address 10.254.254.1/32
+!
+interface r1-eth0
+ ip address 10.0.0.1/24
+!
+interface r1-eth1
+ ip address 10.0.1.1/24
+!
+ip forwarding
+ipv6 forwarding
+!
diff --git a/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf b/tests/topotests/bgp_aggregate_address_topo1/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..acacd86
--- /dev/null
@@ -0,0 +1,7 @@
+router bgp 65000
+  neighbor 10.0.1.1 remote-as internal
+  neighbor 10.0.1.1 timers 3 10
+  address-family ipv4 unicast
+    redistribute connected
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_aggregate_address_topo1/r2/zebra.conf b/tests/topotests/bgp_aggregate_address_topo1/r2/zebra.conf
new file mode 100644 (file)
index 0000000..38e0c44
--- /dev/null
@@ -0,0 +1,10 @@
+!
+interface lo
+ ip address 10.254.254.2/32
+!
+interface r2-eth0
+ ip address 10.0.1.2/24
+!
+ip forwarding
+ipv6 forwarding
+!
diff --git a/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py b/tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py
new file mode 100644 (file)
index 0000000..3f3b71d
--- /dev/null
@@ -0,0 +1,286 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_aggregate_address_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# 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 BGP aggregate address features.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class BgpAggregateAddressTopo1(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        r1 = tgen.add_router("r1")
+        r2 = tgen.add_router("r2")
+        peer1 = tgen.add_exabgp_peer(
+            "peer1", ip="10.0.0.2", defaultRoute="via 10.0.0.1"
+        )
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(r1)
+        switch.add_link(peer1)
+
+        switch = tgen.add_switch("s2")
+        switch.add_link(r1)
+        switch.add_link(r2)
+
+
+def setup_module(mod):
+    tgen = Topogen(BgpAggregateAddressTopo1, mod.__name__)
+    tgen.start_topology()
+
+    router = tgen.gears["r1"]
+    router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r1/zebra.conf"))
+    router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r1/bgpd.conf"))
+    router.start()
+
+    router = tgen.gears["r2"]
+    router.load_config(TopoRouter.RD_ZEBRA, os.path.join(CWD, "r2/zebra.conf"))
+    router.load_config(TopoRouter.RD_BGP, os.path.join(CWD, "r2/bgpd.conf"))
+    router.start()
+
+    peer = tgen.gears["peer1"]
+    peer.start(os.path.join(CWD, "peer1"), os.path.join(CWD, "exabgp.env"))
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def expect_route(router_name, routes_expected):
+    "Helper function to avoid repeated code."
+    tgen = get_topogen()
+    test_func = functools.partial(
+        topotest.router_json_cmp,
+        tgen.gears[router_name],
+        "show ip route json",
+        routes_expected,
+    )
+    _, result = topotest.run_and_expect(test_func, None, count=120, wait=1)
+    assertmsg = '"{}" BGP convergence failure'.format(router_name)
+    assert result is None, assertmsg
+
+
+def test_expect_convergence():
+    "Test that BGP protocol converged."
+
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info("waiting for protocols to converge")
+
+    def expect_loopback_route(router, iptype, route, proto):
+        "Wait until route is present on RIB for protocol."
+        logger.info("waiting route {} in {}".format(route, router))
+        test_func = functools.partial(
+            topotest.router_json_cmp,
+            tgen.gears[router],
+            "show {} route json".format(iptype),
+            {route: [{"protocol": proto}]},
+        )
+        _, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+        assertmsg = '"{}" BGP convergence failure'.format(router)
+        assert result is None, assertmsg
+
+    expect_loopback_route("r2", "ip", "10.254.254.1/32", "bgp")
+    expect_loopback_route("r2", "ip", "10.254.254.3/32", "bgp")
+
+
+def test_bgp_aggregate_address_matching_med_only():
+    "Test that the command matching-MED-only works."
+
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    routes_expected = {
+        # All MED matches, aggregation must exist.
+        "192.168.0.0/24": [{"protocol": "bgp", "metric": 0}],
+        "192.168.0.1/32": [{"protocol": "bgp", "metric": 10}],
+        "192.168.0.2/32": [{"protocol": "bgp", "metric": 10}],
+        "192.168.0.3/32": [{"protocol": "bgp", "metric": 10}],
+        # Non matching MED: aggregation must not exist.
+        "192.168.1.0/24": None,
+        "192.168.1.1/32": [{"protocol": "bgp", "metric": 10}],
+        "192.168.1.2/32": [{"protocol": "bgp", "metric": 10}],
+        "192.168.1.3/32": [{"protocol": "bgp", "metric": 20}],
+    }
+
+    test_func = functools.partial(
+        topotest.router_json_cmp,
+        tgen.gears["r2"],
+        "show ip route json",
+        routes_expected,
+    )
+    _, result = topotest.run_and_expect(test_func, None, count=20, wait=1)
+    assertmsg = '"r2" BGP convergence failure'
+    assert result is None, assertmsg
+
+
+def test_bgp_aggregate_address_match_and_supress():
+    "Test that the command matching-MED-only with suppression works."
+
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    tgen.gears["r1"].vtysh_multicmd(
+        """
+configure terminal
+router bgp 65000
+address-family ipv4 unicast
+no aggregate-address 192.168.0.0/24 matching-MED-only
+no aggregate-address 192.168.1.0/24 matching-MED-only
+aggregate-address 192.168.0.0/24 matching-MED-only summary-only
+aggregate-address 192.168.1.0/24 matching-MED-only summary-only
+"""
+    )
+
+    routes_expected = {
+        # All MED matches, aggregation must exist.
+        "192.168.0.0/24": [{"protocol": "bgp", "metric": 0}],
+        "192.168.0.1/32": None,
+        "192.168.0.2/32": None,
+        "192.168.0.3/32": None,
+        # Non matching MED: aggregation must not exist.
+        "192.168.1.0/24": None,
+        "192.168.1.1/32": [{"protocol": "bgp", "metric": 10}],
+        "192.168.1.2/32": [{"protocol": "bgp", "metric": 10}],
+        "192.168.1.3/32": [{"protocol": "bgp", "metric": 20}],
+    }
+
+    test_func = functools.partial(
+        topotest.router_json_cmp,
+        tgen.gears["r2"],
+        "show ip route json",
+        routes_expected,
+    )
+    _, result = topotest.run_and_expect(test_func, None, count=120, wait=1)
+    assertmsg = '"r2" BGP convergence failure'
+    assert result is None, assertmsg
+
+
+def test_bgp_aggregate_address_suppress_map():
+    "Test that the command suppress-map works."
+
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    expect_route('r2', {
+        "192.168.2.0/24": [{"protocol": "bgp"}],
+        "192.168.2.1/32": None,
+        "192.168.2.2/32": [{"protocol": "bgp"}],
+        "192.168.2.3/32": [{"protocol": "bgp"}],
+    })
+
+    # Change route map and test again.
+    tgen.gears["r1"].vtysh_multicmd(
+        """
+configure terminal
+router bgp 65000
+address-family ipv4 unicast
+no aggregate-address 192.168.2.0/24 suppress-map rm-sup-one
+aggregate-address 192.168.2.0/24 suppress-map rm-sup-two
+"""
+    )
+
+    expect_route('r2', {
+        "192.168.2.0/24": [{"protocol": "bgp"}],
+        "192.168.2.1/32": [{"protocol": "bgp"}],
+        "192.168.2.2/32": None,
+        "192.168.2.3/32": [{"protocol": "bgp"}],
+    })
+
+
+def test_bgp_aggregate_address_suppress_map_update_route_map():
+    "Test that the suppress-map late route map creation works."
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    tgen.gears["r1"].vtysh_multicmd(
+        """
+configure terminal
+router bgp 65000
+address-family ipv4 unicast
+no aggregate-address 192.168.2.0/24 suppress-map rm-sup-two
+aggregate-address 192.168.2.0/24 suppress-map rm-sup-three
+"""
+    )
+
+    expect_route('r2', {
+        "192.168.2.0/24": [{"protocol": "bgp"}],
+        "192.168.2.1/32": [{"protocol": "bgp"}],
+        "192.168.2.2/32": [{"protocol": "bgp"}],
+        "192.168.2.3/32": [{"protocol": "bgp"}],
+    })
+
+    # Create missing route map and test again.
+    tgen.gears["r1"].vtysh_multicmd(
+        """
+configure terminal
+route-map rm-sup-three permit 10
+match ip address acl-sup-three
+"""
+    )
+
+    expect_route('r2', {
+        "192.168.2.0/24": [{"protocol": "bgp"}],
+        "192.168.2.1/32": [{"protocol": "bgp"}],
+        "192.168.2.2/32": [{"protocol": "bgp"}],
+        "192.168.2.3/32": None,
+    })
+
+
+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 f9d22a3a3696d5206e31bf4c4a95b91db15eecdc..544bda145cb1d6c1723ccc4ce520e017aa61be41 100644 (file)
@@ -65,7 +65,7 @@ from lib.common_config import (
     create_route_maps,
     check_address_types,
     step,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import (
@@ -114,7 +114,7 @@ def setup_module(mod):
     """
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
diff --git a/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json b/tests/topotests/bgp_communities_topo1/bgp_communities_topo2.json
new file mode 100644 (file)
index 0000000..fa89f6b
--- /dev/null
@@ -0,0 +1,191 @@
+{
+    "address_types": [
+        "ipv4",
+        "ipv6"
+    ],
+    "ipv4base": "10.0.0.0",
+    "ipv4mask": 24,
+    "ipv6base": "fd00::",
+    "ipv6mask": 64,
+    "link_ip_start": {
+        "ipv4": "10.0.0.0",
+        "v4mask": 24,
+        "ipv6": "fd00::",
+        "v6mask": 64
+    },
+    "lo_prefix": {
+        "ipv4": "1.0.",
+        "v4mask": 32,
+        "ipv6": "2001:db8:f::",
+        "v6mask": 128
+    },
+    "routers": {
+        "r1": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r2": {
+                    "ipv4": "auto",
+                    "ipv6": "auto"
+                },
+                "r3": {
+                    "ipv4": "auto",
+                    "ipv6": "auto"
+                }
+            },
+            "bgp": {
+                "local_as": "100",
+                "address_family": {
+                    "ipv4": {
+                        "unicast": {
+                            "neighbor": {
+                                "r2": {
+                                    "dest_link": {
+                                        "r1": {}
+                                    }
+                                },
+                                "r3": {
+                                    "dest_link": {
+                                        "r1": {
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "ipv6": {
+                        "unicast": {
+                            "neighbor": {
+                                "r2": {
+                                    "dest_link": {
+                                        "r1": {
+                                        }
+                                    }
+                                },
+                                "r3": {
+                                    "dest_link": {
+                                        "r1": {
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        },
+        "r2": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1": {
+                    "ipv4": "auto",
+                    "ipv6": "auto"
+                }
+            },
+            "bgp": {
+                "local_as": "100",
+                "address_family": {
+                    "ipv4": {
+                        "unicast": {
+                            "neighbor": {
+                                "r1": {
+                                    "dest_link": {
+                                        "r2": {}
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "ipv6": {
+                        "unicast": {
+                            "neighbor": {
+                                "r1": {
+                                    "dest_link": {
+                                        "r2": {
+                                            "route_maps": [{
+                                                "name": "rmap_global",
+                                                "direction": "in"
+                                            }]
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            "route_maps": {
+                "rmap_global": [{
+                    "action": "permit",
+                    "set": {
+                        "ipv6": {
+                            "nexthop": "prefer-global"
+                        }
+                    }
+                }]
+            }
+        },
+        "r3": {
+            "links": {
+                "lo": {
+                    "ipv4": "auto",
+                    "ipv6": "auto",
+                    "type": "loopback"
+                },
+                "r1": {
+                    "ipv4": "auto",
+                    "ipv6": "auto"
+                }
+            },
+            "bgp": {
+                "local_as": "300",
+                "address_family": {
+                    "ipv4": {
+                        "unicast": {
+                            "neighbor": {
+                                "r1": {
+                                    "dest_link": {
+                                        "r3": {}
+                                    }
+                                }
+                            }
+                        }
+                    },
+                    "ipv6": {
+                        "unicast": {
+                            "neighbor": {
+                                "r1": {
+                                    "dest_link": {
+                                        "r3": {
+                                            "route_maps": [{
+                                                "name": "rmap_global",
+                                                "direction": "in"
+                                            }]
+                                        }
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            },
+            "route_maps": {
+                "rmap_global": [{
+                    "action": "permit",
+                    "set": {
+                        "ipv6": {
+                            "nexthop": "prefer-global"
+                        }
+                    }
+                }]
+            }
+        }
+    }
+}
index 57e8e0d34aefdcc717b3359f167eab8b890de32b..f2e54b24d6bc57b38b5f409c01b07397edf6402f 100644 (file)
@@ -54,7 +54,7 @@ from lib.common_config import (
     create_route_maps,
     create_prefix_lists,
     create_route_maps,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import (
@@ -104,7 +104,7 @@ def setup_module(mod):
     """
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
diff --git a/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py b/tests/topotests/bgp_communities_topo1/test_bgp_communities_topo2.py
new file mode 100644 (file)
index 0000000..c084214
--- /dev/null
@@ -0,0 +1,422 @@
+#!/usr/bin/python
+
+#
+# Copyright (c) 2020 by VMware, Inc. ("VMware")
+# Used Copyright (c) 2018 by Network Device Education Foundation,
+# Inc. ("NetDEF") in this file.
+#
+# 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 VMWARE DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL VMWARE 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.
+#
+
+"""
+Following tests are covered to test bgp community functionality:
+1. Verify that BGP well known communities work fine for
+   eBGP and iBGP peers.
+   Well known communities tested: no-export, local-AS, internet
+
+"""
+
+import os
+import sys
+import time
+import json
+import pytest
+
+# 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 mininet.topo import Topo
+from lib.topogen import Topogen, get_topogen
+
+# Import topoJson from lib, to create topology and initial configuration
+from lib.common_config import (
+    start_topology,
+    write_test_header,
+    write_test_footer,
+    reset_config_on_routers,
+    verify_rib,
+    create_static_routes,
+    check_address_types,
+    step,
+    create_route_maps,
+    create_prefix_lists,
+    create_route_maps,
+    required_linux_kernel_version,
+)
+
+from lib.topolog import logger
+from lib.bgp import (
+    verify_bgp_convergence,
+    create_router_bgp,
+    clear_bgp_and_verify,
+    verify_bgp_rib,
+    verify_bgp_community,
+)
+from lib.topojson import build_topo_from_json, build_config_from_json
+from copy import deepcopy
+
+# Reading the data from JSON File for topology creation
+jsonFile = "{}/bgp_communities_topo2.json".format(CWD)
+try:
+    with open(jsonFile, "r") as topoJson:
+        topo = json.load(topoJson)
+except IOError:
+    assert False, "Could not read file {}".format(jsonFile)
+
+# Global variables
+BGP_CONVERGENCE = False
+ADDR_TYPES = check_address_types()
+NETWORK = {
+    "ipv4": ["192.0.2.1/32", "192.0.2.2/32"],
+    "ipv6": ["2001:DB8::1:1/128", "2001:DB8::1:2/128"],
+}
+
+
+class BGPCOMMUNITIES(Topo):
+    """
+    Test BGPCOMMUNITIES - topology 1
+
+    * `Topo`: Topology object
+    """
+
+    def build(self, *_args, **_opts):
+        """Build function"""
+        tgen = get_topogen(self)
+
+        # Building topology from json file
+        build_topo_from_json(tgen, topo)
+
+
+def setup_module(mod):
+    """
+    Sets up the pytest environment
+
+    * `mod`: module name
+    """
+
+    # Required linux kernel version for this suite to run.
+    result = required_linux_kernel_version("4.14")
+    if result is not True:
+        pytest.skip("Kernel requirements are not met")
+
+    testsuite_run_time = time.asctime(time.localtime(time.time()))
+    logger.info("Testsuite start time: {}".format(testsuite_run_time))
+    logger.info("=" * 40)
+
+    logger.info("Running setup_module to create topology")
+
+    # This function initiates the topology build with Topogen...
+    tgen = Topogen(BGPCOMMUNITIES, mod.__name__)
+    # ... and here it calls Mininet initialization functions.
+
+    # Starting topology, create tmp files which are loaded to routers
+    #  to start deamons and then start routers
+    start_topology(tgen)
+
+    # Creating configuration from JSON
+    build_config_from_json(tgen, topo)
+
+    # Checking BGP convergence
+    global BGP_CONVERGENCE
+    global ADDR_TYPES
+
+    # Don't run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    # Api call verify whether BGP is converged
+    BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
+    assert BGP_CONVERGENCE is True, "setup_module :Failed \n Error:" " {}".format(
+        BGP_CONVERGENCE
+    )
+
+    logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+    """
+    Teardown the pytest environment
+
+    * `mod`: module name
+    """
+
+    logger.info("Running teardown_module to delete topology")
+
+    tgen = get_topogen()
+
+    # Stop toplogy and Remove tmp files
+    tgen.stop_topology()
+
+    logger.info(
+        "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+    )
+    logger.info("=" * 40)
+
+
+#####################################################
+#
+#   Tests starting
+#
+#####################################################
+
+
+def test_bgp_no_export_local_as_and_internet_communities_p0(request):
+    """
+    Verify that BGP well known communities work fine for
+    eBGP and iBGP peers.
+    Well known communities tested: no-export, local-AS, internet
+    """
+
+    tc_name = request.node.name
+    write_test_header(tc_name)
+    tgen = get_topogen()
+
+    # Don"t run this test if we have any failure.
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    step("Initial config: Configure BGP neighborship between R1 and R3.")
+    reset_config_on_routers(tgen)
+
+    step("Configure static routes on R1 with next-hop as null0")
+    for addr_type in ADDR_TYPES:
+        input_dict_4 = {
+            "r1": {
+                "static_routes": [{"network": NETWORK[addr_type], "next_hop": "null0"}]
+            }
+        }
+        result = create_static_routes(tgen, input_dict_4)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+    for comm_type in ["no-export", "local-AS", "internet"]:
+
+        step("Create a route-map on R1 to set community as {}".format(comm_type))
+
+        seq_id = 10
+        input_rmap = {
+            "r1": {
+                "route_maps": {
+                    "rmap_wkc": [
+                        {
+                            "action": "permit",
+                            "seq_id": seq_id,
+                            "set": {"community": {"num": "{}".format(comm_type)}},
+                        }
+                    ]
+                }
+            }
+        }
+        result = create_route_maps(tgen, input_rmap)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
+
+        step("Apply route-map while redistributing static routes into BGP")
+        input_dict_2 = {
+            "r1": {
+                "bgp": {
+                    "address_family": {
+                        "ipv4": {
+                            "unicast": {
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
+                                        "attribute": {"route-map": "rmap_wkc"},
+                                    }
+                                ]
+                            }
+                        },
+                        "ipv6": {
+                            "unicast": {
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
+                                        "attribute": {"route-map": "rmap_wkc"},
+                                    }
+                                ]
+                            }
+                        },
+                    }
+                }
+            }
+        }
+        result = create_router_bgp(tgen, topo, input_dict_2)
+
+        step("Verify that BGP prefixes on R1 have community: {}".format(comm_type))
+        input_dict_4 = {"community": "{}".format(comm_type)}
+        for addr_type in ADDR_TYPES:
+            result = verify_bgp_community(
+                tgen, addr_type, "r1", NETWORK[addr_type], input_dict_4
+            )
+            assert result is True, "Test case {} : Should fail \n Error: {}".format(
+                tc_name, result
+            )
+
+        for addr_type in ADDR_TYPES:
+            input_dict_4 = {
+                "r1": {
+                    "static_routes": [
+                        {
+                            "network": NETWORK[addr_type],
+                            "next_hop": topo["routers"]["r2"]["links"]["r1"][
+                                addr_type
+                            ].split("/")[0],
+                        }
+                    ]
+                }
+            }
+            result = verify_bgp_rib(
+                tgen,
+                addr_type,
+                "r2",
+                input_dict_4,
+                next_hop=topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0],
+            )
+            assert result is True, "Testcase  : Failed \n Error: {}".format(
+                tc_name, result
+            )
+
+            if comm_type == "internet":
+                step(
+                    "Verify that these prefixes, originated on R1, are"
+                    "received on both R2 and R3"
+                )
+
+                result = verify_rib(
+                    tgen,
+                    addr_type,
+                    "r3",
+                    input_dict_4,
+                    next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[
+                        0
+                    ],
+                )
+                assert result is True, "Testcase  : Failed \n Error: {}".format(
+                    tc_name, result
+                )
+            else:
+                step(
+                    "Verify that these prefixes, originated on R1, are not"
+                    "received on R3 but received on R2"
+                )
+
+                result = verify_rib(
+                    tgen,
+                    addr_type,
+                    "r3",
+                    input_dict_4,
+                    next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[
+                        0
+                    ],
+                    expected=False,
+                )
+                assert result is not True, "Testcase  : Failed \n Error: {}".format(
+                    tc_name, result
+                )
+
+        step("Remove route-map from redistribute static on R1")
+        input_dict_2 = {
+            "r1": {
+                "bgp": {
+                    "address_family": {
+                        "ipv4": {
+                            "unicast": {
+                                "redistribute": [
+                                    {"redist_type": "static", "delete": True}
+                                ]
+                            }
+                        },
+                        "ipv6": {
+                            "unicast": {
+                                "redistribute": [
+                                    {"redist_type": "static", "delete": True}
+                                ]
+                            }
+                        },
+                    }
+                }
+            }
+        }
+        result = create_router_bgp(tgen, topo, input_dict_2)
+        assert result is True, "Testcase  : Failed \n Error: {}".format(tc_name, result)
+
+        step("Configure redistribute static")
+        input_dict_2 = {
+            "r1": {
+                "bgp": {
+                    "address_family": {
+                        "ipv4": {
+                            "unicast": {"redistribute": [{"redist_type": "static"}]}
+                        },
+                        "ipv6": {
+                            "unicast": {"redistribute": [{"redist_type": "static"}]}
+                        },
+                    }
+                }
+            }
+        }
+        result = create_router_bgp(tgen, topo, input_dict_2)
+        assert result is True, "Testcase  : Failed \n Error: {}".format(tc_name, result)
+
+        step(
+            "Verify that these prefixes, originated on R1, are now"
+            "received on both routers R2 and R3"
+        )
+        for addr_type in ADDR_TYPES:
+            input_dict_4 = {
+                "r1": {
+                    "static_routes": [
+                        {
+                            "network": NETWORK[addr_type],
+                            "next_hop": topo["routers"]["r2"]["links"]["r1"][
+                                addr_type
+                            ].split("/")[0],
+                        }
+                    ]
+                }
+            }
+            result = verify_bgp_rib(
+                tgen,
+                addr_type,
+                "r2",
+                input_dict_4,
+                next_hop=topo["routers"]["r1"]["links"]["r2"][addr_type].split("/")[0],
+            )
+            assert result is True, "Testcase  : Failed \n Error: {}".format(
+                tc_name, result
+            )
+
+            result = verify_bgp_rib(
+                tgen,
+                addr_type,
+                "r3",
+                input_dict_4,
+                next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0],
+            )
+            assert result is True, "Testcase  : Failed \n Error: {}".format(
+                tc_name, result
+            )
+
+    write_test_footer(tc_name)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_conditional_advertisement/__init__.py b/tests/topotests/bgp_conditional_advertisement/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..633d183
--- /dev/null
@@ -0,0 +1,30 @@
+!
+ip prefix-list CUST seq 5 permit 10.139.224.0/20
+ip prefix-list DEFAULT seq 5 permit 0.0.0.0/0
+ip prefix-list PL1 seq 5 permit 192.0.2.1/32
+!
+route-map CUST permit 10
+ match ip address prefix-list CUST
+ set community 64671:501
+!
+route-map RM1 permit 10
+ match ip address prefix-list PL1
+ set community 64952:3008
+!
+route-map DEF permit 10
+ match ip address prefix-list DEFAULT
+ set community 64848:3011 65011:200 65013:200
+!
+router bgp 1
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 10.10.10.2 remote-as 2
+ !
+ address-family ipv4 unicast
+  network 0.0.0.0/0 route-map DEF
+  network 192.0.2.1/32 route-map RM1
+  network 192.0.2.5/32
+  redistribute connected route-map CUST
+  neighbor 10.10.10.2 soft-reconfiguration inbound
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r1/zebra.conf
new file mode 100644 (file)
index 0000000..bb887e4
--- /dev/null
@@ -0,0 +1,19 @@
+!
+hostname Router1
+!
+ip route 0.0.0.0/0 blackhole
+ip route 192.0.2.1/32 blackhole
+ip route 192.0.2.2/32 blackhole
+ip route 192.0.2.3/32 blackhole
+ip route 192.0.2.4/32 blackhole
+ip route 192.0.2.5/32 blackhole
+!
+interface r1-eth0
+ ip address 10.10.10.1/24
+!
+interface lo
+ ip address 10.139.224.1/20
+!
+ip forwarding
+ipv6 forwarding
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..c6147fe
--- /dev/null
@@ -0,0 +1,44 @@
+!
+ip prefix-list DEFAULT seq 5 permit 192.0.2.5/32
+ip prefix-list DEFAULT seq 10 permit 192.0.2.1/32
+ip prefix-list EXIST seq 5 permit 10.10.10.10/32
+ip prefix-list DEFAULT-ROUTE seq 5 permit 0.0.0.0/0
+ip prefix-list IP1 seq 5 permit 10.139.224.0/20
+ip prefix-list IP2 seq 5 permit 203.0.113.1/32
+!
+bgp community-list standard DC-ROUTES seq 5 permit 64952:3008
+bgp community-list standard DC-ROUTES seq 10 permit 64671:501
+bgp community-list standard DC-ROUTES seq 15 permit 64950:3009
+bgp community-list standard DEFAULT-ROUTE seq 5 permit 65013:200
+!
+route-map ADV-MAP-1 permit 10
+ match ip address prefix-list IP1
+!
+route-map ADV-MAP-1 permit 20
+ match community DC-ROUTES
+!
+route-map ADV-MAP-2 permit 10
+ match ip address prefix-list IP2
+!
+route-map EXIST-MAP permit 10
+ match community DEFAULT-ROUTE
+ match ip address prefix-list DEFAULT-ROUTE
+!
+route-map RMAP-1 deny 10
+ match ip address prefix-list IP1
+!
+route-map RMAP-2 deny 10
+ match ip address prefix-list IP2
+!
+router bgp 2
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 10.10.10.1 remote-as 1
+ neighbor 10.10.20.3 remote-as 3
+ !
+ address-family ipv4 unicast
+  network 203.0.113.1/32
+  neighbor 10.10.10.1 soft-reconfiguration inbound
+  neighbor 10.10.20.3 soft-reconfiguration inbound
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r2/zebra.conf
new file mode 100644 (file)
index 0000000..434ab68
--- /dev/null
@@ -0,0 +1,15 @@
+!
+hostname Router2
+!
+interface r2-eth0
+ ip address 10.10.10.2/24
+!
+interface r2-eth1
+ ip address 10.10.20.2/24
+!
+interface lo
+ ip address 203.0.113.1/32
+!
+ip forwarding
+ipv6 forwarding
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf b/tests/topotests/bgp_conditional_advertisement/r3/bgpd.conf
new file mode 100644 (file)
index 0000000..2f4f506
--- /dev/null
@@ -0,0 +1,11 @@
+!
+router bgp 3
+ bgp log-neighbor-changes
+ no bgp ebgp-requires-policy
+ neighbor 10.10.20.2 remote-as 2
+ !
+ address-family ipv4 unicast
+  neighbor 10.10.20.2 soft-reconfiguration inbound
+ exit-address-family
+!
+
diff --git a/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf b/tests/topotests/bgp_conditional_advertisement/r3/zebra.conf
new file mode 100644 (file)
index 0000000..0dadfdb
--- /dev/null
@@ -0,0 +1,12 @@
+!
+hostname Router3
+!
+interface r3-eth0
+ ip address 10.10.20.3/24
+!
+interface lo
+ ip address 198.51.100.1/32
+!
+ip forwarding
+ipv6 forwarding
+!
diff --git a/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py b/tests/topotests/bgp_conditional_advertisement/test_bgp_conditional_advertisement.py
new file mode 100644 (file)
index 0000000..0e31ab1
--- /dev/null
@@ -0,0 +1,961 @@
+#!/usr/bin/env python
+
+#
+# test_bgp_conditional_advertisement.py
+#
+# Copyright (c) 2020 by
+# Samsung R&D Institute India - Bangalore.
+# Madhurilatha Kuruganti
+#
+# 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 BGP conditional advertisement functionality.
+
+    +--------+            +--------+            +--------+
+    |        |            |        |            |        |
+    |   R1   |------------|   R2   |------------|   R3   |
+    |        |            |        |            |        |
+    +--------+            +--------+            +--------+
+
+R2 is DUT and peers with R1 and R3 in default bgp instance.
+
+Following tests are covered under BGP conditional advertisement functionality.
+Conditional advertisement
+-------------------------
+TC11: R3 BGP convergence, without advertise-map configuration.
+      All routes are advertised to R3.
+
+TC21: exist-map routes present in R2's BGP table.
+      advertise-map routes present in R2's BGP table are advertised to R3.
+TC22: exist-map routes not present in R2's BGP table
+      advertise-map routes present in R2's BGP table are withdrawn from R3.
+TC31: non-exist-map routes not present in R2's BGP table
+      advertise-map routes present in R2's BGP table are advertised to R3.
+TC32: non-exist-map routes present in R2's BGP table
+      advertise-map routes present in R2's BGP table are withdrawn from R3.
+
+TC41: non-exist-map route-map configuration removed in R2.
+      advertise-map routes present in R2's BGP table are advertised to R3.
+TC42: exist-map route-map configuration removed in R2
+      advertise-map routes present in R2's BGP table are withdrawn from R3.
+
+Conditional advertisement(received routes) along with Route-map Filter
+----------------------------------------------------------------------
+TC51: exist-map routes present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 except advertise-map routes.
+TC52: exist-map routes present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 including advertise-map routes.
+TC53: non-exist-map routes present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 including advertise-map routes.
+TC54: non-exist-map routes present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 except advertise-map routes.
+
+TC61: exist-map routes not present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 including advertise-map routes.
+TC62: exist-map routes not present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 except advertise-map routes.
+TC63: non-exist-map routes not present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 except advertise-map routes.
+TC64: non-exist-map routes not present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 including advertise-map routes.
+
+Conditional advertisement(attached routes) along with Route-map Filter
+-----------------------------------------------------------------
+TC71: exist-map routes present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 except advertise-map routes.
+TC72: exist-map routes present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 including advertise-map routes.
+TC73: non-exist-map routes present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 including advertise-map routes.
+TC74: non-exist-map routes present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 except advertise-map routes.
+
+TC81: exist-map routes not present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 including advertise-map routes.
+TC82: exist-map routes not present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 except advertise-map routes.
+TC83: non-exist-map routes not present in R2's BGP table, with route-map filter.
+      All routes are withdrawn from R3 except advertise-map routes.
+TC84: non-exist-map routes not present in R2's BGP table, without route-map filter.
+      All routes are advertised to R3 including advertise-map routes.
+
+TC91: exist-map routes present in R2's BGP table, with route-map filter and network.
+      All routes are advertised to R3 including advertise-map routes.
+TC92: exist-map routes present in R2's BGP table, with route-map filter and no network.
+      All routes are advertised to R3 except advertise-map routes.
+TC93: non-exist-map routes not present in R2's BGP table, with route-map filter and network.
+      All routes are advertised to R3 including advertise-map routes.
+TC94: non-exist-map routes not present in R2's BGP table, with route-map filter and no network.
+      All routes are advertised to R3 except advertise-map routes.
+
+i.e.
++----------------+-------------------------+------------------------+
+|  Routes in     |  exist-map status       | advertise-map status   |
+|  BGP table     |                         |                        |
++----------------+-------------------------+------------------------+
+|  Present       |  Condition matched      | Advertise              |
++----------------+-------------------------+------------------------+
+|  Not Present   |  Condition not matched  | Withdrawn              |
++----------------+-------------------------+------------------------+
+|                |  non-exist-map status   | advertise-map status   |
+|                |                         |                        |
++----------------+-------------------------+------------------------+
+|  Present       |  Condition matched      | Withdrawn              |
++----------------+-------------------------+------------------------+
+|  Not Present   |  Condition not matched  | Advertise              |
++----------------+-------------------------+------------------------+
+Here in this topology, based on the default route presence in R2 and
+the configured condition-map (exist-map/non-exist-map) 10.139.224.0/20
+will be either advertised/withdrawn to/from R3.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class BgpConditionalAdvertisementTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        r1 = tgen.add_router("r1")
+        r2 = tgen.add_router("r2")
+        r3 = tgen.add_router("r3")
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(r1)
+        switch.add_link(r2)
+
+        switch = tgen.add_switch("s2")
+        switch.add_link(r2)
+        switch.add_link(r3)
+
+
+def setup_module(mod):
+    testsuite_run_time = time.asctime(time.localtime(time.time()))
+    logger.info("Testsuite start time: {}".format(testsuite_run_time))
+    logger.info("=" * 40)
+
+    logger.info("Running setup_module to create topology")
+
+    tgen = Topogen(BgpConditionalAdvertisementTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.items(), 1):
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+    logger.info("Running setup_module() done")
+
+
+def teardown_module(mod):
+    """
+    Teardown the pytest environment
+    * `mod`: module name
+    """
+
+    logger.info("Running teardown_module to delete topology")
+
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+    logger.info(
+        "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+    )
+    logger.info("=" * 40)
+
+
+def test_bgp_conditional_advertisement():
+    """
+    Test BGP conditional advertisement functionality.
+    """
+
+    tgen = get_topogen()
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router1 = tgen.gears["r1"]
+    router2 = tgen.gears["r2"]
+    router3 = tgen.gears["r3"]
+
+    passed = "PASSED!!!"
+    failed = "FAILED!!!"
+
+    def _all_routes_advertised(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": [{"protocol": "bgp"}],
+            "192.0.2.1/32": [{"protocol": "bgp"}],
+            "192.0.2.5/32": [{"protocol": "bgp"}],
+            "10.139.224.0/20": [{"protocol": "bgp"}],
+            "203.0.113.1/32": [{"protocol": "bgp"}],
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _all_routes_withdrawn(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": None,
+            "192.0.2.1/32": None,
+            "192.0.2.5/32": None,
+            "10.139.224.0/20": None,
+            "203.0.113.1/32": None,
+        }
+        return topotest.json_cmp(output, expected)
+
+    # BGP conditional advertisement with route-maps
+    # EXIST-MAP, ADV-MAP-1 and RMAP-1
+    def _exist_map_routes_present(router):
+        return _all_routes_advertised(router)
+
+    def _exist_map_routes_not_present(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": None,
+            "192.0.2.1/32": None,
+            "192.0.2.5/32": [{"protocol": "bgp"}],
+            "10.139.224.0/20": None,
+            "203.0.113.1/32": [{"protocol": "bgp"}],
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _non_exist_map_routes_present(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": [{"protocol": "bgp"}],
+            "192.0.2.1/32": None,
+            "192.0.2.5/32": [{"protocol": "bgp"}],
+            "10.139.224.0/20": None,
+            "203.0.113.1/32": [{"protocol": "bgp"}],
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _non_exist_map_routes_not_present(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": None,
+            "192.0.2.1/32": [{"protocol": "bgp"}],
+            "192.0.2.5/32": [{"protocol": "bgp"}],
+            "10.139.224.0/20": [{"protocol": "bgp"}],
+            "203.0.113.1/32": [{"protocol": "bgp"}],
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _exist_map_no_condition_route_map(router):
+        return _non_exist_map_routes_present(router)
+
+    def _non_exist_map_no_condition_route_map(router):
+        return _all_routes_advertised(router)
+
+    def _exist_map_routes_present_rmap_filter(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": None,
+            "192.0.2.1/32": [{"protocol": "bgp"}],
+            "192.0.2.5/32": None,
+            "10.139.224.0/20": [{"protocol": "bgp"}],
+            "203.0.113.1/32": None,
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _exist_map_routes_present_no_rmap_filter(router):
+        return _all_routes_advertised(router)
+
+    def _non_exist_map_routes_present_rmap_filter(router):
+        return _all_routes_withdrawn(router)
+
+    def _non_exist_map_routes_present_no_rmap_filter(router):
+        return _non_exist_map_routes_present(router)
+
+    def _exist_map_routes_not_present_rmap_filter(router):
+        return _all_routes_withdrawn(router)
+
+    def _exist_map_routes_not_present_no_rmap_filter(router):
+        return _exist_map_routes_not_present(router)
+
+    def _non_exist_map_routes_not_present_rmap_filter(router):
+        return _exist_map_routes_present_rmap_filter(router)
+
+    def _non_exist_map_routes_not_present_no_rmap_filter(router):
+        return _non_exist_map_routes_not_present(router)
+
+    # BGP conditional advertisement with route-maps
+    # EXIST-MAP, ADV-MAP-2 and RMAP-2
+    def _exist_map_routes_not_present_rmap2_filter(router):
+        return _all_routes_withdrawn(router)
+
+    def _exist_map_routes_not_present_no_rmap2_filter(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": None,
+            "192.0.2.1/32": [{"protocol": "bgp"}],
+            "192.0.2.5/32": [{"protocol": "bgp"}],
+            "10.139.224.0/20": [{"protocol": "bgp"}],
+            "203.0.113.1/32": None,
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _non_exist_map_routes_not_present_rmap2_filter(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": None,
+            "192.0.2.1/32": None,
+            "192.0.2.5/32": None,
+            "10.139.224.0/20": None,
+            "203.0.113.1/32": [{"protocol": "bgp"}],
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _non_exist_map_routes_not_present_no_rmap2_filter(router):
+        return _non_exist_map_routes_not_present(router)
+
+    def _exist_map_routes_present_rmap2_filter(router):
+        return _non_exist_map_routes_not_present_rmap2_filter(router)
+
+    def _exist_map_routes_present_no_rmap2_filter(router):
+        return _all_routes_advertised(router)
+
+    def _non_exist_map_routes_present_rmap2_filter(router):
+        return _all_routes_withdrawn(router)
+
+    def _non_exist_map_routes_present_no_rmap2_filter(router):
+        output = json.loads(router.vtysh_cmd("show ip route json"))
+        expected = {
+            "0.0.0.0/0": [{"protocol": "bgp"}],
+            "192.0.2.1/32": [{"protocol": "bgp"}],
+            "192.0.2.5/32": [{"protocol": "bgp"}],
+            "10.139.224.0/20": [{"protocol": "bgp"}],
+            "203.0.113.1/32": None,
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _exist_map_routes_present_rmap2_network(router):
+        return _non_exist_map_routes_not_present_rmap2_filter(router)
+
+    def _exist_map_routes_present_rmap2_no_network(router):
+        return _all_routes_withdrawn(router)
+
+    def _non_exist_map_routes_not_present_rmap2_network(router):
+        return _non_exist_map_routes_not_present_rmap2_filter(router)
+
+    def _non_exist_map_routes_not_present_rmap2_no_network(router):
+        return _all_routes_withdrawn(router)
+
+    # TC11: R3 BGP convergence, without advertise-map configuration.
+    # All routes are advertised to R3.
+    test_func = functools.partial(_all_routes_advertised, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=130, wait=1)
+
+    msg = 'TC11: "router3" BGP convergence - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC21: exist-map routes present in R2's BGP table.
+    # advertise-map routes present in R2's BGP table are advertised to R3.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 2
+              address-family ipv4 unicast
+               neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = 'TC21: exist-map routes present in "router2" BGP table - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC22: exist-map routes not present in R2's BGP table
+    # advertise-map routes present in R2's BGP table are withdrawn from R3.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 1
+              address-family ipv4 unicast
+               no network 0.0.0.0/0 route-map DEF
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_not_present, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = 'TC22: exist-map routes not present in "router2" BGP table - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC31: non-exist-map routes not present in R2's BGP table
+    # advertise-map routes present in R2's BGP table are advertised to R3.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 2
+              address-family ipv4 unicast
+               neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_non_exist_map_routes_not_present, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = 'TC31: non-exist-map routes not present in "router2" BGP table - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC32: non-exist-map routes present in R2's BGP table
+    # advertise-map routes present in R2's BGP table are withdrawn from R3.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 1
+              address-family ipv4 unicast
+               network 0.0.0.0/0 route-map DEF
+        """
+    )
+
+    test_func = functools.partial(_non_exist_map_routes_present, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = 'TC32: non-exist-map routes present in "router2" BGP table - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC41: non-exist-map route-map configuration removed in R2.
+    # advertise-map routes present in R2's BGP table are advertised to R3.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           no route-map EXIST-MAP permit 10
+        """
+    )
+
+    test_func = functools.partial(_non_exist_map_no_condition_route_map, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = 'TC41: non-exist-map route-map removed in "router2" - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC42: exist-map route-map configuration removed in R2
+    # advertise-map routes present in R2's BGP table are withdrawn from R3.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 2
+              address-family ipv4 unicast
+               neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_exist_map_no_condition_route_map, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = 'TC42: exist-map route-map removed in "router2" - '
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC51: exist-map routes present in R2's BGP table, with route-map filter.
+    # All routes are withdrawn from R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           route-map EXIST-MAP permit 10
+            match community DEFAULT-ROUTE
+            match ip address prefix-list DEFAULT-ROUTE
+           !
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-1 out
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present_rmap_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC51: exist-map routes present with route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC52: exist-map routes present in R2's BGP table, no route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-1 out
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present_no_rmap_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC52: exist-map routes present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC53: non-exist-map routes present in R2's BGP table, with route-map filter.
+    # All routes are withdrawn from R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 2
+              address-family ipv4 unicast
+               neighbor 10.10.20.3 route-map RMAP-1 out
+               neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_non_exist_map_routes_present_rmap_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC53: non-exist-map routes present, with route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC54: non-exist-map routes present in R2's BGP table, no route-map filter.
+    # All routes are advertised to R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 2
+              address-family ipv4 unicast
+               no neighbor 10.10.20.3 route-map RMAP-1 out
+        """
+    )
+
+    test_func = functools.partial(_non_exist_map_routes_present_no_rmap_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC54: non-exist-map routes present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC61: exist-map routes not present in R2's BGP table, with route-map filter.
+    # All routes are withdrawn from R3 including advertise-map routes.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+            router bgp 1
+              address-family ipv4 unicast
+               no network 0.0.0.0/0 route-map DEF
+        """
+    )
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-1 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-1 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_not_present_rmap_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC61: exist-map routes not present, route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC62: exist-map routes not present in R2's BGP table, without route-map filter.
+    # All routes are advertised to R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-1 out
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_not_present_no_rmap_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC62: exist-map routes not present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC63: non-exist-map routes not present in R2's BGP table, with route-map filter.
+    # All routes are withdrawn from R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-1 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-1 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_not_present_rmap_filter, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC63: non-exist-map routes not present, route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC64: non-exist-map routes not present in R2's BGP table, without route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-1 out
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_not_present_no_rmap_filter, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC64: non-exist-map routes not present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC71: exist-map routes present in R2's BGP table, with route-map filter.
+    # All routes are withdrawn from R3 except advertise-map routes.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 1
+            address-family ipv4 unicast
+             network 0.0.0.0/0 route-map DEF
+        """
+    )
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-2 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present_rmap2_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC71: exist-map routes present, route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC72: exist-map routes present in R2's BGP table, without route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-2 out
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present_no_rmap2_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC72: exist-map routes present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC73: non-exist-map routes present in R2's BGP table, with route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-2 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_non_exist_map_routes_present_rmap2_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC73: non-exist-map routes present, route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC74: non-exist-map routes present in R2's BGP table, without route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-2 out
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_present_no_rmap2_filter, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC74: non-exist-map routes present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC81: exist-map routes not present in R2's BGP table, with route-map filter.
+    # All routes are withdrawn from R3 including advertise-map routes.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 1
+            address-family ipv4 unicast
+             no network 0.0.0.0/0 route-map DEF
+        """
+    )
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-2 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_not_present_rmap2_filter, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC81: exist-map routes not present, route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC82: exist-map routes not present in R2's BGP table, without route-map filter.
+    # All routes are advertised to R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-2 out
+        """
+    )
+
+    test_func = functools.partial(
+        _exist_map_routes_not_present_no_rmap2_filter, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC82: exist-map routes not present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC83: non-exist-map routes not present in R2's BGP table, with route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-2 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_not_present_rmap2_filter, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC83: non-exist-map routes not present, route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC84: non-exist-map routes not present in R2's BGP table, without route-map filter.
+    # All routes are advertised to R3 including advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no neighbor 10.10.20.3 route-map RMAP-2 out
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_not_present_no_rmap2_filter, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC84: non-exist-map routes not present, no route-map filter - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC91: exist-map routes present in R2's BGP table, with route-map filter and network.
+    # All routes are advertised to R3 including advertise-map routes.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 1
+            address-family ipv4 unicast
+             network 0.0.0.0/0 route-map DEF
+        """
+    )
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             neighbor 10.10.20.3 route-map RMAP-2 out
+             neighbor 10.10.20.3 advertise-map ADV-MAP-2 exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present_rmap2_network, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC91: exist-map routes present, route-map filter and network - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC92: exist-map routes present in R2's BGP table, with route-map filter and no network.
+    # All routes are advertised to R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no network 203.0.113.1/32
+        """
+    )
+
+    test_func = functools.partial(_exist_map_routes_present_rmap2_no_network, router3)
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC92: exist-map routes present, route-map filter and no network - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC93: non-exist-map routes not present in R2's BGP table, with route-map filter and network.
+    # All routes are advertised to R3 including advertise-map routes.
+    router1.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 1
+            address-family ipv4 unicast
+             no network 0.0.0.0/0 route-map DEF
+        """
+    )
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             network 203.0.113.1/32
+             neighbor 10.10.20.3 advertise-map ADV-MAP-2 non-exist-map EXIST-MAP
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_not_present_rmap2_network, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC93: non-exist-map routes not present, route-map filter and network - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+    # TC94: non-exist-map routes not present in R2's BGP table, with route-map filter and no network.
+    # All routes are advertised to R3 except advertise-map routes.
+    router2.vtysh_cmd(
+        """
+          configure terminal
+           router bgp 2
+            address-family ipv4 unicast
+             no network 203.0.113.1/32
+        """
+    )
+
+    test_func = functools.partial(
+        _non_exist_map_routes_not_present_rmap2_no_network, router3
+    )
+    success, result = topotest.run_and_expect(test_func, None, count=90, wait=1)
+
+    msg = "TC94: non-exist-map routes not present, route-map filter and no network - "
+    assert result is None, msg + failed
+
+    logger.info(msg + passed)
+
+
+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))
diff --git a/tests/topotests/bgp_default-route/__init__.py b/tests/topotests/bgp_default-route/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_default-route/r1/bgpd.conf b/tests/topotests/bgp_default-route/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..8699d62
--- /dev/null
@@ -0,0 +1,8 @@
+router bgp 65000
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.2 remote-as 65001
+  neighbor 192.168.255.2 timers 3 10
+  address-family ipv4 unicast
+    neighbor 192.168.255.2 default-originate
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_default-route/r1/zebra.conf b/tests/topotests/bgp_default-route/r1/zebra.conf
new file mode 100644 (file)
index 0000000..0a283c0
--- /dev/null
@@ -0,0 +1,9 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route/r2/bgpd.conf b/tests/topotests/bgp_default-route/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..00c96cc
--- /dev/null
@@ -0,0 +1,8 @@
+router bgp 65001
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.1 remote-as 65000
+  neighbor 192.168.255.1 timers 3 10
+  address-family ipv4 unicast
+    redistribute connected
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_default-route/r2/zebra.conf b/tests/topotests/bgp_default-route/r2/zebra.conf
new file mode 100644 (file)
index 0000000..606c17b
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route/test_bgp_default-originate.py b/tests/topotests/bgp_default-route/test_bgp_default-originate.py
new file mode 100644 (file)
index 0000000..d8de0f0
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019-2020 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# 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 if default-originate works without route-map.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        for routern in range(1, 3):
+            tgen.add_router("r{}".format(routern))
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.items(), 1):
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_default_originate_route_map():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router = tgen.gears["r2"]
+
+    def _bgp_converge(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
+        expected = {
+            "192.168.255.1": {
+                "bgpState": "Established",
+                "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
+            }
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _bgp_default_route_is_valid(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json"))
+        expected = {"paths": [{"valid": True}]}
+        return topotest.json_cmp(output, expected)
+
+    test_func = functools.partial(_bgp_converge, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert result is None, 'Failed to see bgp convergence in "{}"'.format(router)
+
+    test_func = functools.partial(_bgp_default_route_is_valid, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert (
+        result is None
+    ), 'Failed to see applied metric for default route in "{}"'.format(router)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_default-route_route-map/__init__.py b/tests/topotests/bgp_default-route_route-map/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map/r1/bgpd.conf
deleted file mode 100644 (file)
index cb07ea9..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-router bgp 65000
-  no bgp ebgp-requires-policy
-  neighbor 192.168.255.2 remote-as 65001
-  neighbor 192.168.255.2 timers 3 10
-  address-family ipv4 unicast
-    neighbor 192.168.255.2 default-originate route-map default
-  exit-address-family
-!
-route-map default permit 10
-  set metric 123
-!
diff --git a/tests/topotests/bgp_default-route_route-map/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map/r1/zebra.conf
deleted file mode 100644 (file)
index 0a283c0..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-!
-interface lo
- ip address 172.16.255.254/32
-!
-interface r1-eth0
- ip address 192.168.255.1/24
-!
-ip forwarding
-!
diff --git a/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map/r2/bgpd.conf
deleted file mode 100644 (file)
index 00c96cc..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-router bgp 65001
-  no bgp ebgp-requires-policy
-  neighbor 192.168.255.1 remote-as 65000
-  neighbor 192.168.255.1 timers 3 10
-  address-family ipv4 unicast
-    redistribute connected
-  exit-address-family
-!
diff --git a/tests/topotests/bgp_default-route_route-map/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map/r2/zebra.conf
deleted file mode 100644 (file)
index 606c17b..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-!
-interface r2-eth0
- ip address 192.168.255.2/24
-!
-ip forwarding
-!
diff --git a/tests/topotests/bgp_default-route_route-map/test_bgp_default-originate_route-map.py b/tests/topotests/bgp_default-route_route-map/test_bgp_default-originate_route-map.py
deleted file mode 100644 (file)
index a72c3a4..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-
-#
-# bgp_default-originate_route-map.py
-# Part of NetDEF Topology Tests
-#
-# Copyright (c) 2019 by
-# Donatas Abraitis <donatas.abraitis@gmail.com>
-#
-# 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.
-#
-
-"""
-bgp_default-originate_route-map.py:
-
-Test if works the following commands:
-router bgp 65031
-  address-family ipv4 unicast
-    neighbor 192.168.255.2 default-originate route-map default
-
-route-map default permit 10
-  set metric 123
-"""
-
-import os
-import sys
-import json
-import time
-import pytest
-import functools
-
-CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, "../"))
-
-# pylint: disable=C0413
-from lib import topotest
-from lib.topogen import Topogen, TopoRouter, get_topogen
-from lib.topolog import logger
-from mininet.topo import Topo
-
-
-class TemplateTopo(Topo):
-    def build(self, *_args, **_opts):
-        tgen = get_topogen(self)
-
-        for routern in range(1, 3):
-            tgen.add_router("r{}".format(routern))
-
-        switch = tgen.add_switch("s1")
-        switch.add_link(tgen.gears["r1"])
-        switch.add_link(tgen.gears["r2"])
-
-
-def setup_module(mod):
-    tgen = Topogen(TemplateTopo, mod.__name__)
-    tgen.start_topology()
-
-    router_list = tgen.routers()
-
-    for i, (rname, router) in enumerate(router_list.items(), 1):
-        router.load_config(
-            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
-        )
-        router.load_config(
-            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
-        )
-
-    tgen.start_router()
-
-
-def teardown_module(mod):
-    tgen = get_topogen()
-    tgen.stop_topology()
-
-
-def test_bgp_default_originate_route_map():
-    tgen = get_topogen()
-
-    if tgen.routers_have_failure():
-        pytest.skip(tgen.errors)
-
-    router = tgen.gears["r2"]
-
-    def _bgp_converge(router):
-        output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
-        expected = {
-            "192.168.255.1": {
-                "bgpState": "Established",
-                "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
-            }
-        }
-        return topotest.json_cmp(output, expected)
-
-    def _bgp_default_route_has_metric(router):
-        output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json"))
-        expected = {"paths": [{"metric": 123}]}
-        return topotest.json_cmp(output, expected)
-
-    test_func = functools.partial(_bgp_converge, router)
-    success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-
-    assert result is None, 'Failed to see bgp convergence in "{}"'.format(router)
-
-    test_func = functools.partial(_bgp_default_route_has_metric, router)
-    success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-
-    assert (
-        result is None
-    ), 'Failed to see applied metric for default route in "{}"'.format(router)
-
-
-if __name__ == "__main__":
-    args = ["-s"] + sys.argv[1:]
-    sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_default-route_route-map_match/__init__.py b/tests/topotests/bgp_default-route_route-map_match/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_default-route_route-map_match/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..97b440f
--- /dev/null
@@ -0,0 +1,17 @@
+router bgp 65000
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.2 remote-as 65001
+  neighbor 192.168.255.2 timers 3 10
+  address-family ipv4 unicast
+    network 192.168.13.0/24 route-map internal
+    neighbor 192.168.255.2 default-originate route-map default
+  exit-address-family
+!
+bgp community-list standard default seq 5 permit 65000:1
+!
+route-map default permit 10
+  match community default
+!
+route-map internal permit 10
+  set community 65000:1
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map_match/r1/zebra.conf
new file mode 100644 (file)
index 0000000..9e581a7
--- /dev/null
@@ -0,0 +1,11 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip route 192.168.13.0./24 Null0
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..00c96cc
--- /dev/null
@@ -0,0 +1,8 @@
+router bgp 65001
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.1 remote-as 65000
+  neighbor 192.168.255.1 timers 3 10
+  address-family ipv4 unicast
+    redistribute connected
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map_match/r2/zebra.conf
new file mode 100644 (file)
index 0000000..606c17b
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match/test_bgp_default-originate_route-map_match.py b/tests/topotests/bgp_default-route_route-map_match/test_bgp_default-originate_route-map_match.py
new file mode 100644 (file)
index 0000000..089c9a9
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019-2020 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# 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 if default-originate works with ONLY match operations.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        for routern in range(1, 3):
+            tgen.add_router("r{}".format(routern))
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.items(), 1):
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_default_originate_route_map():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router = tgen.gears["r2"]
+
+    def _bgp_converge(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
+        expected = {
+            "192.168.255.1": {
+                "bgpState": "Established",
+                "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
+            }
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _bgp_default_route_is_valid(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json"))
+        expected = {"paths": [{"valid": True}]}
+        return topotest.json_cmp(output, expected)
+
+    test_func = functools.partial(_bgp_converge, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert result is None, 'Failed to see bgp convergence in "{}"'.format(router)
+
+    test_func = functools.partial(_bgp_default_route_is_valid, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert (
+        result is None
+    ), 'Failed to see applied metric for default route in "{}"'.format(router)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_default-route_route-map_match_set/__init__.py b/tests/topotests/bgp_default-route_route-map_match_set/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match_set/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..6ef8b1c
--- /dev/null
@@ -0,0 +1,18 @@
+router bgp 65000
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.2 remote-as 65001
+  neighbor 192.168.255.2 timers 3 10
+  address-family ipv4 unicast
+    network 192.168.13.0/24 route-map internal
+    neighbor 192.168.255.2 default-originate route-map default
+  exit-address-family
+!
+bgp community-list standard default seq 5 permit 65000:1
+!
+route-map default permit 10
+  match community default
+  set metric 123
+!
+route-map internal permit 10
+  set community 65000:1
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map_match_set/r1/zebra.conf
new file mode 100644 (file)
index 0000000..9e581a7
--- /dev/null
@@ -0,0 +1,11 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip route 192.168.13.0./24 Null0
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map_match_set/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..00c96cc
--- /dev/null
@@ -0,0 +1,8 @@
+router bgp 65001
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.1 remote-as 65000
+  neighbor 192.168.255.1 timers 3 10
+  address-family ipv4 unicast
+    redistribute connected
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match_set/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map_match_set/r2/zebra.conf
new file mode 100644 (file)
index 0000000..606c17b
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route_route-map_match_set/test_bgp_default-originate_route-map_match_set.py b/tests/topotests/bgp_default-route_route-map_match_set/test_bgp_default-originate_route-map_match_set.py
new file mode 100644 (file)
index 0000000..d9ea5db
--- /dev/null
@@ -0,0 +1,115 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2020 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# 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 if default-originate works with match operations.
+And verify if set operations work as well.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        for routern in range(1, 3):
+            tgen.add_router("r{}".format(routern))
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.items(), 1):
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_default_originate_route_map():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router = tgen.gears["r2"]
+
+    def _bgp_converge(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
+        expected = {
+            "192.168.255.1": {
+                "bgpState": "Established",
+                "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
+            }
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _bgp_default_route_has_metric(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json"))
+        expected = {"paths": [{"metric": 123}]}
+        return topotest.json_cmp(output, expected)
+
+    test_func = functools.partial(_bgp_converge, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert result is None, 'Failed to see bgp convergence in "{}"'.format(router)
+
+    test_func = functools.partial(_bgp_default_route_has_metric, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert (
+        result is None
+    ), 'Failed to see applied metric for default route in "{}"'.format(router)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_default-route_route-map_set/__init__.py b/tests/topotests/bgp_default-route_route-map_set/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/bgp_default-route_route-map_set/r1/bgpd.conf b/tests/topotests/bgp_default-route_route-map_set/r1/bgpd.conf
new file mode 100644 (file)
index 0000000..cb07ea9
--- /dev/null
@@ -0,0 +1,11 @@
+router bgp 65000
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.2 remote-as 65001
+  neighbor 192.168.255.2 timers 3 10
+  address-family ipv4 unicast
+    neighbor 192.168.255.2 default-originate route-map default
+  exit-address-family
+!
+route-map default permit 10
+  set metric 123
+!
diff --git a/tests/topotests/bgp_default-route_route-map_set/r1/zebra.conf b/tests/topotests/bgp_default-route_route-map_set/r1/zebra.conf
new file mode 100644 (file)
index 0000000..0a283c0
--- /dev/null
@@ -0,0 +1,9 @@
+!
+interface lo
+ ip address 172.16.255.254/32
+!
+interface r1-eth0
+ ip address 192.168.255.1/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route_route-map_set/r2/bgpd.conf b/tests/topotests/bgp_default-route_route-map_set/r2/bgpd.conf
new file mode 100644 (file)
index 0000000..00c96cc
--- /dev/null
@@ -0,0 +1,8 @@
+router bgp 65001
+  no bgp ebgp-requires-policy
+  neighbor 192.168.255.1 remote-as 65000
+  neighbor 192.168.255.1 timers 3 10
+  address-family ipv4 unicast
+    redistribute connected
+  exit-address-family
+!
diff --git a/tests/topotests/bgp_default-route_route-map_set/r2/zebra.conf b/tests/topotests/bgp_default-route_route-map_set/r2/zebra.conf
new file mode 100644 (file)
index 0000000..606c17b
--- /dev/null
@@ -0,0 +1,6 @@
+!
+interface r2-eth0
+ ip address 192.168.255.2/24
+!
+ip forwarding
+!
diff --git a/tests/topotests/bgp_default-route_route-map_set/test_bgp_default-originate_route-map_set.py b/tests/topotests/bgp_default-route_route-map_set/test_bgp_default-originate_route-map_set.py
new file mode 100644 (file)
index 0000000..9a22c58
--- /dev/null
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2019-2020 by
+# Donatas Abraitis <donatas.abraitis@gmail.com>
+#
+# 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 if default-originate works with ONLY set operations.
+"""
+
+import os
+import sys
+import json
+import time
+import pytest
+import functools
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from mininet.topo import Topo
+
+
+class TemplateTopo(Topo):
+    def build(self, *_args, **_opts):
+        tgen = get_topogen(self)
+
+        for routern in range(1, 3):
+            tgen.add_router("r{}".format(routern))
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
+
+
+def setup_module(mod):
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    for i, (rname, router) in enumerate(router_list.items(), 1):
+        router.load_config(
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
+        )
+        router.load_config(
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
+        )
+
+    tgen.start_router()
+
+
+def teardown_module(mod):
+    tgen = get_topogen()
+    tgen.stop_topology()
+
+
+def test_bgp_default_originate_route_map():
+    tgen = get_topogen()
+
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    router = tgen.gears["r2"]
+
+    def _bgp_converge(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp neighbor 192.168.255.1 json"))
+        expected = {
+            "192.168.255.1": {
+                "bgpState": "Established",
+                "addressFamilyInfo": {"ipv4Unicast": {"acceptedPrefixCounter": 1}},
+            }
+        }
+        return topotest.json_cmp(output, expected)
+
+    def _bgp_default_route_has_metric(router):
+        output = json.loads(router.vtysh_cmd("show ip bgp 0.0.0.0/0 json"))
+        expected = {"paths": [{"metric": 123}]}
+        return topotest.json_cmp(output, expected)
+
+    test_func = functools.partial(_bgp_converge, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert result is None, 'Failed to see bgp convergence in "{}"'.format(router)
+
+    test_func = functools.partial(_bgp_default_route_has_metric, router)
+    success, result = topotest.run_and_expect(test_func, None, count=30, wait=0.5)
+
+    assert (
+        result is None
+    ), 'Failed to see applied metric for default route in "{}"'.format(router)
+
+
+if __name__ == "__main__":
+    args = ["-s"] + sys.argv[1:]
+    sys.exit(pytest.main(args))
index 2520763bda81f7499f51949846825efbd65c7b4f..003193f108d21940e97b23dc50d483dcb548bca5 100644 (file)
@@ -122,27 +122,39 @@ def test_ebgp_requires_policy():
 
     test_func = functools.partial(_bgp_converge, "r2")
     success, result = topotest.run_and_expect(test_func, None, count=65, wait=2)
-    assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(tgen.gears["r2"])
+    assert success is True, 'Failed bgp convergence (r2) in "{}"'.format(
+        tgen.gears["r2"]
+    )
 
     test_func = functools.partial(_bgp_has_routes, "r2")
     success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-    assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(tgen.gears["r2"])
+    assert success is True, 'eBGP policy is not working (r2) in "{}"'.format(
+        tgen.gears["r2"]
+    )
 
     test_func = functools.partial(_bgp_converge, "r4")
     success, result = topotest.run_and_expect(test_func, None, count=65, wait=2)
-    assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(tgen.gears["r4"])
+    assert success is True, 'Failed bgp convergence (r4) in "{}"'.format(
+        tgen.gears["r4"]
+    )
 
     test_func = functools.partial(_bgp_has_routes, "r4")
     success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-    assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(tgen.gears["r4"])
+    assert success is False, 'eBGP policy is not working (r4) in "{}"'.format(
+        tgen.gears["r4"]
+    )
 
     test_func = functools.partial(_bgp_converge, "r6")
     success, result = topotest.run_and_expect(test_func, None, count=65, wait=2)
-    assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(tgen.gears["r6"])
+    assert success is True, 'Failed bgp convergence (r6) in "{}"'.format(
+        tgen.gears["r6"]
+    )
 
     test_func = functools.partial(_bgp_has_routes, "r6")
     success, result = topotest.run_and_expect(test_func, None, count=60, wait=0.5)
-    assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(tgen.gears["r6"])
+    assert success is True, 'eBGP policy is not working (r6) in "{}"'.format(
+        tgen.gears["r6"]
+    )
 
 
 if __name__ == "__main__":
index 0d99f23ad919df1b9a4a0256eda0d4f49ac1c34e..222478f12dc4f73274fbf62400f32475a73ad4fb 100644 (file)
@@ -35,7 +35,7 @@ import platform
 
 # Save the Current Working Directory to find configuration files.
 CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, '../'))
+sys.path.append(os.path.join(CWD, "../"))
 
 # pylint: disable=C0413
 # Import topogen and topotest helpers
@@ -47,27 +47,30 @@ from lib.topolog import logger
 from mininet.topo import Topo
 
 l3mdev_accept = 0
-krel = ''
+krel = ""
+
 
 class BGPEVPNTopo(Topo):
     "Test topology builder"
+
     def build(self, *_args, **_opts):
         "Build function"
         tgen = get_topogen(self)
 
-        tgen.add_router('r1')
-        tgen.add_router('r2')
+        tgen.add_router("r1")
+        tgen.add_router("r2")
+
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
 
-        switch = tgen.add_switch('s1')
-        switch.add_link(tgen.gears['r1'])
-        switch.add_link(tgen.gears['r2'])
+        switch = tgen.add_switch("s2")
+        switch.add_link(tgen.gears["r1"])
+
+        switch = tgen.add_switch("s3")
+        switch.add_link(tgen.gears["r2"])
 
-        switch = tgen.add_switch('s2')
-        switch.add_link(tgen.gears['r1'])
 
-        switch = tgen.add_switch('s3')
-        switch.add_link(tgen.gears['r2'])
-        
 def setup_module(mod):
     "Sets up the pytest environment"
     global l3mdev_accept
@@ -79,99 +82,109 @@ def setup_module(mod):
     router_list = tgen.routers()
 
     krel = platform.release()
-    if topotest.version_cmp(krel, '4.18') < 0:
-        logger.info('BGP EVPN RT5 NETNS tests will not run (have kernel "{}", but it requires 4.18)'.format(krel))
-        return pytest.skip('Skipping BGP EVPN RT5 NETNS Test. Kernel not supported')
+    if topotest.version_cmp(krel, "4.18") < 0:
+        logger.info(
+            'BGP EVPN RT5 NETNS tests will not run (have kernel "{}", but it requires 4.18)'.format(
+                krel
+            )
+        )
+        return pytest.skip("Skipping BGP EVPN RT5 NETNS Test. Kernel not supported")
 
     l3mdev_accept = 1
-    logger.info('setting net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept))
+    logger.info("setting net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept))
 
     # create VRF vrf-101 on R1 and R2
     # create loop101
-    cmds_vrflite = ['sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept),
-                    'ip link add {}-vrf-101 type vrf table 101',
-                    'ip ru add oif {}-vrf-101 table 101',
-                    'ip ru add iif {}-vrf-101 table 101',
-                    'ip link set dev {}-vrf-101 up',
-                    'sysctl -w net.ipv4.tcp_l3mdev_accept={}'.format(l3mdev_accept),
-                    'ip link add loop101 type dummy',
-                    'ip link set dev loop101 master {}-vrf-101',
-                    'ip link set dev loop101 up']
-    cmds_netns = ['ip netns add {}-vrf-101',
-                  'ip link add loop101 type dummy',
-                  'ip link set dev loop101 netns {}-vrf-101',
-                  'ip netns exec {}-vrf-101 ip link set dev loop101 up']
-
-    cmds_r2 = [ # config routing 101
-               'ip link add name bridge-101 up type bridge stp_state 0',
-               'ip link set bridge-101 master {}-vrf-101',
-               'ip link set dev bridge-101 up',
-               'ip link add name vxlan-101 type vxlan id 101 dstport 4789 dev r2-eth0 local 192.168.100.41',
-               'ip link set dev vxlan-101 master bridge-101',
-               'ip link set vxlan-101 up type bridge_slave learning off flood off mcast_flood off']
-
-    cmds_r1_netns_method3 = ['ip link add name vxlan-{1} type vxlan id {1} dstport 4789 dev {0}-eth0 local 192.168.100.21',
-                             'ip link set dev vxlan-{1} netns {0}-vrf-{1}',
-                             'ip netns exec {0}-vrf-{1} ip li set dev lo up',
-                             'ip netns exec {0}-vrf-{1} ip link add name bridge-{1} up type bridge stp_state 0',
-                             'ip netns exec {0}-vrf-{1} ip link set dev vxlan-{1} master bridge-{1}',
-                             'ip netns exec {0}-vrf-{1} ip link set bridge-{1} up',
-                             'ip netns exec {0}-vrf-{1} ip link set vxlan-{1} up']
-
-    router = tgen.gears['r1']
+    cmds_vrflite = [
+        "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept),
+        "ip link add {}-vrf-101 type vrf table 101",
+        "ip ru add oif {}-vrf-101 table 101",
+        "ip ru add iif {}-vrf-101 table 101",
+        "ip link set dev {}-vrf-101 up",
+        "sysctl -w net.ipv4.tcp_l3mdev_accept={}".format(l3mdev_accept),
+        "ip link add loop101 type dummy",
+        "ip link set dev loop101 master {}-vrf-101",
+        "ip link set dev loop101 up",
+    ]
+    cmds_netns = [
+        "ip netns add {}-vrf-101",
+        "ip link add loop101 type dummy",
+        "ip link set dev loop101 netns {}-vrf-101",
+        "ip netns exec {}-vrf-101 ip link set dev loop101 up",
+    ]
+
+    cmds_r2 = [  # config routing 101
+        "ip link add name bridge-101 up type bridge stp_state 0",
+        "ip link set bridge-101 master {}-vrf-101",
+        "ip link set dev bridge-101 up",
+        "ip link add name vxlan-101 type vxlan id 101 dstport 4789 dev r2-eth0 local 192.168.100.41",
+        "ip link set dev vxlan-101 master bridge-101",
+        "ip link set vxlan-101 up type bridge_slave learning off flood off mcast_flood off",
+    ]
+
+    cmds_r1_netns_method3 = [
+        "ip link add name vxlan-{1} type vxlan id {1} dstport 4789 dev {0}-eth0 local 192.168.100.21",
+        "ip link set dev vxlan-{1} netns {0}-vrf-{1}",
+        "ip netns exec {0}-vrf-{1} ip li set dev lo up",
+        "ip netns exec {0}-vrf-{1} ip link add name bridge-{1} up type bridge stp_state 0",
+        "ip netns exec {0}-vrf-{1} ip link set dev vxlan-{1} master bridge-{1}",
+        "ip netns exec {0}-vrf-{1} ip link set bridge-{1} up",
+        "ip netns exec {0}-vrf-{1} ip link set vxlan-{1} up",
+    ]
+
+    router = tgen.gears["r1"]
     for cmd in cmds_netns:
-        logger.info('cmd to r1: '+cmd);
-        output = router.run(cmd.format('r1'))
-        logger.info('result: '+output);
+        logger.info("cmd to r1: " + cmd)
+        output = router.run(cmd.format("r1"))
+        logger.info("result: " + output)
 
-    router = tgen.gears['r2']
+    router = tgen.gears["r2"]
     for cmd in cmds_vrflite:
-        logger.info('cmd to r2: '+cmd.format('r2'));
-        output = router.run(cmd.format('r2'))
-        logger.info('result: '+output);
+        logger.info("cmd to r2: " + cmd.format("r2"))
+        output = router.run(cmd.format("r2"))
+        logger.info("result: " + output)
 
     for cmd in cmds_r2:
-        logger.info('cmd to r2: '+cmd.format('r2'));
-        output = router.run(cmd.format('r2'))
-        logger.info('result: '+output);
+        logger.info("cmd to r2: " + cmd.format("r2"))
+        output = router.run(cmd.format("r2"))
+        logger.info("result: " + output)
 
-    router = tgen.gears['r1']
-    bridge_id = '101'
+    router = tgen.gears["r1"]
+    bridge_id = "101"
     for cmd in cmds_r1_netns_method3:
-        logger.info('cmd to r1: '+cmd.format('r1', bridge_id));
-        output = router.run(cmd.format('r1', bridge_id))
-        logger.info('result: '+output);
-    router = tgen.gears['r1']
+        logger.info("cmd to r1: " + cmd.format("r1", bridge_id))
+        output = router.run(cmd.format("r1", bridge_id))
+        logger.info("result: " + output)
+    router = tgen.gears["r1"]
 
     for rname, router in router_list.items():
-        if rname == 'r1':
+        if rname == "r1":
             router.load_config(
                 TopoRouter.RD_ZEBRA,
-                os.path.join(CWD, '{}/zebra.conf'.format(rname)),
-                '--vrfwnetns -o vrf0'
+                os.path.join(CWD, "{}/zebra.conf".format(rname)),
+                "--vrfwnetns -o vrf0",
             )
         else:
             router.load_config(
-                TopoRouter.RD_ZEBRA,
-                os.path.join(CWD, '{}/zebra.conf'.format(rname))
+                TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
             )
         router.load_config(
-            TopoRouter.RD_BGP,
-            os.path.join(CWD, '{}/bgpd.conf'.format(rname))
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
         )
 
     # Initialize all routers.
     tgen.start_router()
 
+
 def teardown_module(_mod):
     "Teardown the pytest environment"
     tgen = get_topogen()
-    cmds_rx_netns = ['ip netns del {}-vrf-101']
-    
-    router = tgen.gears['r1']
+    cmds_rx_netns = ["ip netns del {}-vrf-101"]
+
+    router = tgen.gears["r1"]
     for cmd in cmds_rx_netns:
-        logger.info('cmd to r1: '+cmd.format('r1'));
-        output = router.run(cmd.format('r1'))
+        logger.info("cmd to r1: " + cmd.format("r1"))
+        output = router.run(cmd.format("r1"))
     tgen.stop_topology()
 
 
@@ -183,52 +196,59 @@ def test_protocols_convergence():
     tgen = get_topogen()
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
-    topotest.sleep(4, 'waiting 4 seconds for bgp convergence')
+    topotest.sleep(4, "waiting 4 seconds for bgp convergence")
     # Check IPv4/IPv6 routing tables.
-    output = tgen.gears['r1'].vtysh_cmd('show bgp l2vpn evpn', isjson=False)
-    logger.info('==== result from show bgp l2vpn evpn')
+    output = tgen.gears["r1"].vtysh_cmd("show bgp l2vpn evpn", isjson=False)
+    logger.info("==== result from show bgp l2vpn evpn")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show bgp l2vpn evpn route detail', isjson=False)
-    logger.info('==== result from show bgp l2vpn evpn route detail')
+    output = tgen.gears["r1"].vtysh_cmd(
+        "show bgp l2vpn evpn route detail", isjson=False
+    )
+    logger.info("==== result from show bgp l2vpn evpn route detail")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show bgp vrf r1-vrf-101 ipv4', isjson=False)
-    logger.info('==== result from show bgp vrf r1-vrf-101 ipv4')
+    output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101 ipv4", isjson=False)
+    logger.info("==== result from show bgp vrf r1-vrf-101 ipv4")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show bgp vrf r1-vrf-101', isjson=False)
-    logger.info('==== result from show bgp vrf r1-vrf-101 ')
+    output = tgen.gears["r1"].vtysh_cmd("show bgp vrf r1-vrf-101", isjson=False)
+    logger.info("==== result from show bgp vrf r1-vrf-101 ")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show ip route vrf r1-vrf-101', isjson=False)
-    logger.info('==== result from show ip route vrf r1-vrf-101')
+    output = tgen.gears["r1"].vtysh_cmd("show ip route vrf r1-vrf-101", isjson=False)
+    logger.info("==== result from show ip route vrf r1-vrf-101")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show evpn vni detail', isjson=False)
-    logger.info('==== result from show evpn vni detail')
+    output = tgen.gears["r1"].vtysh_cmd("show evpn vni detail", isjson=False)
+    logger.info("==== result from show evpn vni detail")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show evpn next-hops vni all', isjson=False)
-    logger.info('==== result from show evpn next-hops vni all')
+    output = tgen.gears["r1"].vtysh_cmd("show evpn next-hops vni all", isjson=False)
+    logger.info("==== result from show evpn next-hops vni all")
     logger.info(output)
-    output = tgen.gears['r1'].vtysh_cmd('show evpn rmac vni all', isjson=False)
-    logger.info('==== result from show evpn next-hops vni all')
+    output = tgen.gears["r1"].vtysh_cmd("show evpn rmac vni all", isjson=False)
+    logger.info("==== result from show evpn next-hops vni all")
     logger.info(output)
     # Check IPv4 and IPv6 connectivity between r1 and r2 ( routing vxlan evpn)
-    pingrouter = tgen.gears['r1']
-    logger.info('Check Ping IPv4 from  R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)')
-    output = pingrouter.run('ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000')
+    pingrouter = tgen.gears["r1"]
+    logger.info(
+        "Check Ping IPv4 from  R1(r1-vrf-101) to R2(r2-vrf-101 = 192.168.101.41)"
+    )
+    output = pingrouter.run("ip netns exec r1-vrf-101 ping 192.168.101.41 -f -c 1000")
     logger.info(output)
-    if '1000 packets transmitted, 1000 received' not in output:
-        assertmsg = 'expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok'
+    if "1000 packets transmitted, 1000 received" not in output:
+        assertmsg = (
+            "expected ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) should be ok"
+        )
         assert 0, assertmsg
     else:
-        logger.info('Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK')
+        logger.info("Check Ping IPv4 from R1(r1-vrf-101) to R2(192.168.101.41) OK")
+
 
 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')
+        pytest.skip("Memory leak test/report is disabled")
 
     tgen.report_memory_leaks()
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index 4ec060b642082911e441cc871eac37b55510d271..bd092c4340f97e723662903ebcd8554787668bf2 100644 (file)
@@ -188,11 +188,15 @@ def test_bgp_shutdown():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65000\" -c \"bgp shutdown message ABCDabcd\"')
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65000" -c "bgp shutdown message ABCDabcd"'
+    )
 
     # Check BGP Summary on local and remote routers
     for rtrNum in [1, 2, 4]:
-        logger.info("Checking BGP Summary after shutdown of R1 BGP on router r{}".format(rtrNum))
+        logger.info(
+            "Checking BGP Summary after shutdown of R1 BGP on router r{}".format(rtrNum)
+        )
 
         router = tgen.gears["r{}".format(rtrNum)]
         reffile = os.path.join(CWD, "r{}/bgp_shutdown_summary.json".format(rtrNum))
@@ -202,7 +206,9 @@ def test_bgp_shutdown():
             topotest.router_json_cmp, router, "show ip bgp summary json", expected
         )
         _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
-        assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(rtrNum)
+        assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(
+            rtrNum
+        )
         assert res is None, assertmsg
 
 
@@ -218,18 +224,21 @@ def test_bgp_shutdown_message():
     for rtrNum in [2, 4]:
         logger.info("Checking BGP shutdown received on router r{}".format(rtrNum))
 
-        shut_message = tgen.net['r{}'.format(rtrNum)].cmd(
-            'tail bgpd.log | grep "NOTIFICATION.*Cease/Administratively Shutdown"')
+        shut_message = tgen.net["r{}".format(rtrNum)].cmd(
+            'tail bgpd.log | grep "NOTIFICATION.*Cease/Administratively Shutdown"'
+        )
         assertmsg = "BGP shutdown message not received on router R{}".format(rtrNum)
-        assert shut_message != '', assertmsg
+        assert shut_message != "", assertmsg
 
-        m = re.search('.*([0-9]+ bytes[ 0-9a-fA-F]+)', shut_message)
+        m = re.search(".*([0-9]+ bytes[ 0-9a-fA-F]+)", shut_message)
         if m:
             found = m.group(1)
         else:
-            found = ''
-        assertmsg = "Incorrect BGP shutdown message received on router R{}".format(rtrNum)
-        assert found == '8 bytes 41 42 43 44 61 62 63 64', assertmsg
+            found = ""
+        assertmsg = "Incorrect BGP shutdown message received on router R{}".format(
+            rtrNum
+        )
+        assert found == "8 bytes 41 42 43 44 61 62 63 64", assertmsg
 
     # tgen.mininet_cli()
 
@@ -243,11 +252,15 @@ def test_bgp_no_shutdown():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65000\" -c \"no bgp shutdown\"')
+    tgen.net["r1"].cmd('vtysh -c "conf t" -c "router bgp 65000" -c "no bgp shutdown"')
 
     # Check BGP Summary on local and remote routers
     for rtrNum in [1, 2, 4]:
-        logger.info("Checking BGP Summary after removing bgp shutdown on router r1 on router r{}".format(rtrNum))
+        logger.info(
+            "Checking BGP Summary after removing bgp shutdown on router r1 on router r{}".format(
+                rtrNum
+            )
+        )
 
         router = tgen.gears["r{}".format(rtrNum)]
         reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum))
@@ -257,7 +270,9 @@ def test_bgp_no_shutdown():
             topotest.router_json_cmp, router, "show ip bgp summary json", expected
         )
         _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
-        assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(rtrNum)
+        assertmsg = "BGP sessions on router R{} are in incorrect state (not down as expected?)".format(
+            rtrNum
+        )
         assert res is None, assertmsg
 
 
@@ -303,31 +318,43 @@ def test_bgp_metric_config():
     #  set metric +12
     # !
 
-    tgen.net['r1'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
-        '-c "address-family ipv4 unicast" '+
-        '-c "neighbor 192.168.0.2 route-map addmetric-in in" '+
-        '-c "neighbor 192.168.0.2 route-map addmetric-out out" '+
-        '-c "neighbor 192.168.101.2 route-map setmetric-in in" '+
-        '-c "neighbor 192.168.101.2 route-map setmetric-out out" ')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "ip prefix-list net1 seq 10 permit 192.168.101.0/24" '+
-        '-c "ip prefix-list net2 seq 20 permit 192.168.1.0/24"')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "route-map setmetric-in permit 10" '+
-        '-c "match ip address prefix-list net1" '+
-        '-c "set metric 111" '+
-        '-c "route-map setmetric-in permit 20"')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "route-map setmetric-out permit 10" '+
-        '-c "match ip address prefix-list net2" '+
-        '-c "set metric 1011" '+
-        '-c "route-map setmetric-out permit 20"')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "route-map addmetric-in permit 10" '+
-        '-c "set metric +11"')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "route-map addmetric-out permit 10" '+
-        '-c "set metric +12"')
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65000" '
+        + '-c "address-family ipv4 unicast" '
+        + '-c "neighbor 192.168.0.2 route-map addmetric-in in" '
+        + '-c "neighbor 192.168.0.2 route-map addmetric-out out" '
+        + '-c "neighbor 192.168.101.2 route-map setmetric-in in" '
+        + '-c "neighbor 192.168.101.2 route-map setmetric-out out" '
+    )
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "ip prefix-list net1 seq 10 permit 192.168.101.0/24" '
+        + '-c "ip prefix-list net2 seq 20 permit 192.168.1.0/24"'
+    )
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map setmetric-in permit 10" '
+        + '-c "match ip address prefix-list net1" '
+        + '-c "set metric 111" '
+        + '-c "route-map setmetric-in permit 20"'
+    )
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map setmetric-out permit 10" '
+        + '-c "match ip address prefix-list net2" '
+        + '-c "set metric 1011" '
+        + '-c "route-map setmetric-out permit 20"'
+    )
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map addmetric-in permit 10" '
+        + '-c "set metric +11"'
+    )
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map addmetric-out permit 10" '
+        + '-c "set metric +12"'
+    )
 
     # # Adding the following configuration to r2:
     # router bgp 65000
@@ -360,50 +387,72 @@ def test_bgp_metric_config():
     #  set metric -23
     # !
 
-    tgen.net['r2'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
-        '-c "address-family ipv4 unicast" '+
-        '-c "neighbor 192.168.0.1 route-map subtractmetric-in in" '+
-        '-c "neighbor 192.168.0.1 route-map subtractmetric-out out" '+
-        '-c "neighbor 192.168.201.2 route-map setmetric-in in" ' +
-        '-c "neighbor 192.168.201.2 route-map setmetric-out out" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "ip prefix-list net1 seq 10 permit 192.168.201.0/24" '+
-        '-c "ip prefix-list net2 seq 20 permit 192.168.2.0/24" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "route-map setmetric-in permit 10" '+
-        '-c "match ip address prefix-list net1" '+
-        '-c "set metric 222" '+
-        '-c "route-map setmetric-in permit 20"')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "route-map setmetric-out permit 10" '+
-        '-c "match ip address prefix-list net2" '+
-        '-c "set metric 2022" '+
-        '-c "route-map setmetric-out permit 20"')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "route-map subtractmetric-in permit 10" '+
-        '-c "set metric -22"')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "route-map subtractmetric-out permit 10" '+
-        '-c "set metric -23"')
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65000" '
+        + '-c "address-family ipv4 unicast" '
+        + '-c "neighbor 192.168.0.1 route-map subtractmetric-in in" '
+        + '-c "neighbor 192.168.0.1 route-map subtractmetric-out out" '
+        + '-c "neighbor 192.168.201.2 route-map setmetric-in in" '
+        + '-c "neighbor 192.168.201.2 route-map setmetric-out out" '
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "ip prefix-list net1 seq 10 permit 192.168.201.0/24" '
+        + '-c "ip prefix-list net2 seq 20 permit 192.168.2.0/24" '
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map setmetric-in permit 10" '
+        + '-c "match ip address prefix-list net1" '
+        + '-c "set metric 222" '
+        + '-c "route-map setmetric-in permit 20"'
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map setmetric-out permit 10" '
+        + '-c "match ip address prefix-list net2" '
+        + '-c "set metric 2022" '
+        + '-c "route-map setmetric-out permit 20"'
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map subtractmetric-in permit 10" '
+        + '-c "set metric -22"'
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "route-map subtractmetric-out permit 10" '
+        + '-c "set metric -23"'
+    )
 
     # Clear IN the bgp neighbors to make sure the route-maps are applied
-    tgen.net['r1'].cmd('vtysh -c "clear ip bgp 192.168.0.2 in" '+
-        '-c "clear ip bgp 192.168.101.2 in"')
-    tgen.net['r2'].cmd('vtysh -c "clear ip bgp 192.168.0.1 in" '+
-        '-c "clear ip bgp 192.168.201.2 in"')
+    tgen.net["r1"].cmd(
+        'vtysh -c "clear ip bgp 192.168.0.2 in" ' + '-c "clear ip bgp 192.168.101.2 in"'
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "clear ip bgp 192.168.0.1 in" ' + '-c "clear ip bgp 192.168.201.2 in"'
+    )
 
     # tgen.mininet_cli()
 
     # Checking BGP config - should show the bgp metric settings in the route-maps
     logger.info("Checking BGP configuration for correct 'set metric' values")
 
-    setmetric111 = tgen.net['r1'].cmd('vtysh -c "show running" | grep "^ set metric 111"').rstrip()
-    assertmsg = "'set metric 111' configuration applied to R1, but not visible in configuration"
-    assert setmetric111 == ' set metric 111', assertmsg
+    setmetric111 = (
+        tgen.net["r1"].cmd('vtysh -c "show running" | grep "^ set metric 111"').rstrip()
+    )
+    assertmsg = (
+        "'set metric 111' configuration applied to R1, but not visible in configuration"
+    )
+    assert setmetric111 == " set metric 111", assertmsg
 
-    setmetric222 = tgen.net['r2'].cmd('vtysh -c "show running" | grep "^ set metric 222"').rstrip()
-    assertmsg = "'set metric 222' configuration applied to R2, but not visible in configuration"
-    assert setmetric222 == ' set metric 222', assertmsg
+    setmetric222 = (
+        tgen.net["r2"].cmd('vtysh -c "show running" | grep "^ set metric 222"').rstrip()
+    )
+    assertmsg = (
+        "'set metric 222' configuration applied to R2, but not visible in configuration"
+    )
+    assert setmetric222 == " set metric 222", assertmsg
 
 
 def test_bgp_metric_add_config():
@@ -417,9 +466,13 @@ def test_bgp_metric_add_config():
 
     logger.info("Checking BGP configuration for correct 'set metric' ADD value")
 
-    setmetricP11 = tgen.net['r1'].cmd('vtysh -c "show running" | grep "^ set metric +11"').rstrip()
-    assertmsg = "'set metric +11' configuration applied to R1, but not visible in configuration"
-    assert setmetricP11 == ' set metric +11', assertmsg
+    setmetricP11 = (
+        tgen.net["r1"].cmd('vtysh -c "show running" | grep "^ set metric +11"').rstrip()
+    )
+    assertmsg = (
+        "'set metric +11' configuration applied to R1, but not visible in configuration"
+    )
+    assert setmetricP11 == " set metric +11", assertmsg
 
 
 def test_bgp_metric_subtract_config():
@@ -433,9 +486,13 @@ def test_bgp_metric_subtract_config():
 
     logger.info("Checking BGP configuration for correct 'set metric' SUBTRACT value")
 
-    setmetricM22 = tgen.net['r2'].cmd('vtysh -c "show running" | grep "^ set metric -22"').rstrip()
-    assertmsg = "'set metric -22' configuration applied to R2, but not visible in configuration"
-    assert setmetricM22 == ' set metric -22', assertmsg
+    setmetricM22 = (
+        tgen.net["r2"].cmd('vtysh -c "show running" | grep "^ set metric -22"').rstrip()
+    )
+    assertmsg = (
+        "'set metric -22' configuration applied to R2, but not visible in configuration"
+    )
+    assert setmetricM22 == " set metric -22", assertmsg
 
 
 def test_bgp_set_metric():
@@ -478,47 +535,49 @@ def test_bgp_remove_metric_rmaps():
 
     # Remove metric route-maps and relevant comfiguration
 
-    tgen.net['r1'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
-        '-c "address-family ipv4 unicast" '+
-        '-c "no neighbor 192.168.0.2 route-map addmetric-in in" '+
-        '-c "no neighbor 192.168.0.2 route-map addmetric-out out" '+
-        '-c "no neighbor 192.168.101.2 route-map setmetric-in in" '+
-        '-c "no neighbor 192.168.101.2 route-map setmetric-out out" ')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "no ip prefix-list net1" '+
-        '-c "no ip prefix-list net2"')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map setmetric-in" ')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map setmetric-out" ')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map addmetric-in" ')
-    tgen.net['r1'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map addmetric-out" ')
-
-    tgen.net['r2'].cmd('vtysh -c "conf t" -c "router bgp 65000" '+
-        '-c "address-family ipv4 unicast" '+
-        '-c "no neighbor 192.168.0.1 route-map subtractmetric-in in" '+
-        '-c "no neighbor 192.168.0.1 route-map subtractmetric-out out" '+
-        '-c "no neighbor 192.168.201.2 route-map setmetric-in in" ' +
-        '-c "no neighbor 192.168.201.2 route-map setmetric-out out" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "no ip prefix-list net1" '+
-        '-c "no ip prefix-list net2" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map setmetric-in" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map setmetric-out" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map addmetric-in" ')
-    tgen.net['r2'].cmd('vtysh -c "conf t" '+
-        '-c "no route-map addmetric-out" ')
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65000" '
+        + '-c "address-family ipv4 unicast" '
+        + '-c "no neighbor 192.168.0.2 route-map addmetric-in in" '
+        + '-c "no neighbor 192.168.0.2 route-map addmetric-out out" '
+        + '-c "no neighbor 192.168.101.2 route-map setmetric-in in" '
+        + '-c "no neighbor 192.168.101.2 route-map setmetric-out out" '
+    )
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "no ip prefix-list net1" '
+        + '-c "no ip prefix-list net2"'
+    )
+    tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-in" ')
+    tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-out" ')
+    tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-in" ')
+    tgen.net["r1"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-out" ')
+
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65000" '
+        + '-c "address-family ipv4 unicast" '
+        + '-c "no neighbor 192.168.0.1 route-map subtractmetric-in in" '
+        + '-c "no neighbor 192.168.0.1 route-map subtractmetric-out out" '
+        + '-c "no neighbor 192.168.201.2 route-map setmetric-in in" '
+        + '-c "no neighbor 192.168.201.2 route-map setmetric-out out" '
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "conf t" '
+        + '-c "no ip prefix-list net1" '
+        + '-c "no ip prefix-list net2" '
+    )
+    tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-in" ')
+    tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map setmetric-out" ')
+    tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-in" ')
+    tgen.net["r2"].cmd('vtysh -c "conf t" ' + '-c "no route-map addmetric-out" ')
 
     # Clear IN the bgp neighbors to make sure the route-maps are applied
-    tgen.net['r1'].cmd('vtysh -c "clear ip bgp 192.168.0.2 in" '+
-        '-c "clear ip bgp 192.168.101.2 in"')
-    tgen.net['r2'].cmd('vtysh -c "clear ip bgp 192.168.0.1 in" '+
-        '-c "clear ip bgp 192.168.201.2 in"')
+    tgen.net["r1"].cmd(
+        'vtysh -c "clear ip bgp 192.168.0.2 in" ' + '-c "clear ip bgp 192.168.101.2 in"'
+    )
+    tgen.net["r2"].cmd(
+        'vtysh -c "clear ip bgp 192.168.0.1 in" ' + '-c "clear ip bgp 192.168.201.2 in"'
+    )
 
     # tgen.mininet_cli()
 
@@ -534,7 +593,9 @@ def test_bgp_remove_metric_rmaps():
             topotest.router_json_cmp, router, "show ip bgp json", expected
         )
         _, res = topotest.run_and_expect(test_func, None, count=60, wait=2)
-        assertmsg = "BGP routes on router r{} are wrong after removing metric route-maps".format(rtrNum)
+        assertmsg = "BGP routes on router r{} are wrong after removing metric route-maps".format(
+            rtrNum
+        )
         assert res is None, assertmsg
 
 
@@ -549,15 +610,17 @@ def test_bgp_norib():
 
     logger.info("Configuring 'bgp no-rib' on router r1")
 
-    tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"bgp no-rib\"')
+    tgen.net["r1"].cmd('vtysh -c "conf t" -c "bgp no-rib"')
 
     # Checking BGP config - should show the "bgp no-rib" under the router bgp section
     logger.info("Checking BGP configuration for 'bgp no-rib'")
 
-    norib_cfg = tgen.net['r1'].cmd('vtysh -c "show running bgpd" | grep "^bgp no-rib"').rstrip()
+    norib_cfg = (
+        tgen.net["r1"].cmd('vtysh -c "show running bgpd" | grep "^bgp no-rib"').rstrip()
+    )
 
     assertmsg = "'bgp no-rib' configuration applied, but not visible in configuration"
-    assert norib_cfg == 'bgp no-rib', assertmsg
+    assert norib_cfg == "bgp no-rib", assertmsg
 
 
 def test_bgp_norib_routes():
@@ -585,7 +648,11 @@ def test_bgp_norib_routes():
 
     # Check BGP Summary on local and remote routers
     for rtrNum in [1, 2, 4]:
-        logger.info("Checking BGP Summary after 'bgp no-rib' on router r1 on router r{}".format(rtrNum))
+        logger.info(
+            "Checking BGP Summary after 'bgp no-rib' on router r1 on router r{}".format(
+                rtrNum
+            )
+        )
 
         router = tgen.gears["r{}".format(rtrNum)]
         reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum))
@@ -595,7 +662,9 @@ def test_bgp_norib_routes():
             topotest.router_json_cmp, router, "show ip bgp summary json", expected
         )
         _, res = topotest.run_and_expect(test_func, None, count=30, wait=2)
-        assertmsg = "BGP sessions on router R{} has incorrect routes after adding 'bgp no-rib on r1'".format(rtrNum)
+        assertmsg = "BGP sessions on router R{} has incorrect routes after adding 'bgp no-rib on r1'".format(
+            rtrNum
+        )
         assert res is None, assertmsg
 
     # tgen.mininet_cli()
@@ -612,15 +681,21 @@ def test_bgp_disable_norib():
 
     logger.info("Configuring 'no bgp no-rib' on router r1")
 
-    tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"no bgp no-rib\"')
+    tgen.net["r1"].cmd('vtysh -c "conf t" -c "no bgp no-rib"')
 
     # Checking BGP config - should show the "bgp no-rib" under the router bgp section
     logger.info("Checking BGP configuration for 'bgp no-rib'")
 
-    norib_cfg = tgen.net['r1'].cmd('vtysh -c "show running bgpd" | grep "^ bgp no-rib"').rstrip()
+    norib_cfg = (
+        tgen.net["r1"]
+        .cmd('vtysh -c "show running bgpd" | grep "^ bgp no-rib"')
+        .rstrip()
+    )
 
-    assertmsg = "'no bgp no-rib'configuration applied, but still visible in configuration"
-    assert norib_cfg == '', assertmsg
+    assertmsg = (
+        "'no bgp no-rib'configuration applied, but still visible in configuration"
+    )
+    assert norib_cfg == "", assertmsg
 
 
 def test_bgp_disable_norib_routes():
@@ -648,7 +723,11 @@ def test_bgp_disable_norib_routes():
 
     # Check BGP Summary on local and remote routers
     for rtrNum in [1, 2, 4]:
-        logger.info("Checking BGP Summary after removing the 'bgp no-rib' on router r1 on router r{}".format(rtrNum))
+        logger.info(
+            "Checking BGP Summary after removing the 'bgp no-rib' on router r1 on router r{}".format(
+                rtrNum
+            )
+        )
 
         router = tgen.gears["r{}".format(rtrNum)]
         reffile = os.path.join(CWD, "r{}/bgp_summary.json".format(rtrNum))
@@ -658,13 +737,14 @@ def test_bgp_disable_norib_routes():
             topotest.router_json_cmp, router, "show ip bgp summary json", expected
         )
         _, res = topotest.run_and_expect(test_func, None, count=30, wait=2)
-        assertmsg = "BGP sessions on router R{} has incorrect routes after removing 'bgp no-rib on r1'".format(rtrNum)
+        assertmsg = "BGP sessions on router R{} has incorrect routes after removing 'bgp no-rib on r1'".format(
+            rtrNum
+        )
         assert res is None, assertmsg
 
     # tgen.mininet_cli()
 
 
-
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index 7e6bfc8b2b3727e8acce0f1eafaea5521a36e432..a772a2aab1fb046a51846d25cc4f263ecfb0f303 100644 (file)
@@ -200,6 +200,7 @@ def test_bgp_flowspec():
     else:
         logger.info("Check BGP FS entry for 3::3 with redirect IP OK")
 
+
 if __name__ == "__main__":
 
     args = ["-s"] + sys.argv[1:]
index fdbd3170933eb1592c4db076e1a699bc216ddac5..18d2ac59d2cd04f7b47f425f87bd3e14d99a2b6a 100644 (file)
@@ -135,7 +135,7 @@ from lib.common_config import (
     kill_mininet_routers_process,
     get_frr_ipv6_linklocal,
     create_route_maps,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 
 # Reading the data from JSON File for topology and configuration creation
@@ -188,7 +188,7 @@ def setup_module(mod):
     global ADDR_TYPES
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
index e1ec0ea81b205ab833011de51f878a8a67a9e2f8..da1a47cd29cddb0f8ece64497d1e18927fb04cbc 100644 (file)
@@ -135,7 +135,7 @@ from lib.common_config import (
     kill_mininet_routers_process,
     get_frr_ipv6_linklocal,
     create_route_maps,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 
 # Reading the data from JSON File for topology and configuration creation
@@ -185,7 +185,7 @@ def setup_module(mod):
     """
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
index 7f8cf17a5c9740bebca062a68469c606ad303a09..fe945a4565b76f0c8750537146e7b7926381fc87 100644 (file)
@@ -99,12 +99,14 @@ class TemplateTopo(Topo):
         switch.add_link(tgen.gears["r2"])
         switch.add_link(tgen.gears["r5"])
 
+
 def _run_cmd_and_check(router, cmd, results_file, retries=100, intvl=0.5):
     json_file = "{}/{}".format(CWD, results_file)
     expected = json.loads(open(json_file).read())
     test_func = partial(topotest.router_json_cmp, router, cmd, expected)
     return topotest.run_and_expect(test_func, None, retries, intvl)
 
+
 def setup_module(mod):
     tgen = Topogen(TemplateTopo, mod.__name__)
     tgen.start_topology()
@@ -134,12 +136,14 @@ def setup_module(mod):
     tgen.start_router()
 
     # Basic peering test to see if things are ok
-    _, result = _run_cmd_and_check(r2, 'show ip bgp summary json', 'r2/bgp_sum_1.json')
-    assertmsg = 'R2: Basic sanity test after init failed -- global peerings not up'
+    _, result = _run_cmd_and_check(r2, "show ip bgp summary json", "r2/bgp_sum_1.json")
+    assertmsg = "R2: Basic sanity test after init failed -- global peerings not up"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r2, 'show ip bgp vrf vrf1 summary json', 'r2/bgp_sum_2.json')
-    assertmsg = 'R2: Basic sanity test after init failed -- VRF peerings not up'
+    _, result = _run_cmd_and_check(
+        r2, "show ip bgp vrf vrf1 summary json", "r2/bgp_sum_2.json"
+    )
+    assertmsg = "R2: Basic sanity test after init failed -- VRF peerings not up"
     assert result is None, assertmsg
 
 
@@ -160,80 +164,104 @@ def test_bgp_gshut():
     r4 = tgen.gears["r4"]
     r5 = tgen.gears["r5"]
 
-
     # Verify initial route states
-    logger.info('\nVerify initial route states')
+    logger.info("\nVerify initial route states")
 
-    _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json')
-    assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
+    )
+    assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json')
-    assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
+    )
+    assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_1.json')
-    assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json"
+    )
+    assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    logger.info('\nInitial route states are as expected')
-
+    logger.info("\nInitial route states are as expected")
 
-    #"Test #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers"
-    logger.info('\nTest #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers')
+    # "Test #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers"
+    logger.info(
+        "\nTest #1: Enable BGP-wide graceful-shutdown on R2 and check routes on peers"
+    )
 
     r2.vtysh_cmd(
         """
           configure terminal
             bgp graceful-shutdown
         """
-        )
+    )
 
     # R1, R3 and R5 should see routes from R2 with GSHUT. In addition,
     # R1 should see LOCAL_PREF of 0
-    _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_2.json')
-    assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_2.json"
+    )
+    assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_2.json')
-    assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_2.json"
+    )
+    assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_2.json')
-    assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_2.json"
+    )
+    assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    logger.info('\nTest #1: Successful, routes have GSHUT and/or LPREF of 0 as expected')
-
+    logger.info(
+        "\nTest #1: Successful, routes have GSHUT and/or LPREF of 0 as expected"
+    )
 
-    #"Test #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers"
-    logger.info('\nTest #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers')
+    # "Test #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers"
+    logger.info(
+        "\nTest #2: Turn off BGP-wide graceful-shutdown on R2 and check routes on peers"
+    )
 
     r2.vtysh_cmd(
         """
           configure terminal
             no bgp graceful-shutdown
         """
-        )
+    )
 
     # R1, R3 and R5 should see routes from R2 with their original attributes
-    _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json')
-    assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
+    )
+    assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json')
-    assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
+    )
+    assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_1.json')
-    assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json"
+    )
+    assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    logger.info('\nTest #2: Successful, routes have their original attributes with default LPREF and without GSHUT')
+    logger.info(
+        "\nTest #2: Successful, routes have their original attributes with default LPREF and without GSHUT"
+    )
 
-
-    #"Test #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers"
-    logger.info('\nTest #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers')
+    # "Test #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers"
+    logger.info(
+        "\nTest #3: Enable graceful-shutdown on R2 only in VRF1 and check routes on peers"
+    )
 
     r2.vtysh_cmd(
         """
@@ -241,44 +269,56 @@ def test_bgp_gshut():
             router bgp 65001 vrf vrf1
               bgp graceful-shutdown
         """
-        )
+    )
 
     # R1 and R3 should see no change to their routes
-    _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json')
-    assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
+    )
+    assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json')
-    assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
+    )
+    assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
     # R5 should see routes from R2 with GSHUT.
-    _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_2.json')
-    assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_2.json"
+    )
+    assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    logger.info('\nTest #3: Successful, only VRF peers like R5 see routes with GSHUT')
+    logger.info("\nTest #3: Successful, only VRF peers like R5 see routes with GSHUT")
 
-
-    #"Test #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1"
-    logger.info('\nTest #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1')
+    # "Test #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1"
+    logger.info(
+        "\nTest #4: Try to enable BGP-wide graceful-shutdown on R2 while it is configured in VRF1"
+    )
 
     ret = r2.vtysh_cmd(
         """
           configure terminal
             bgp graceful-shutdown
         """
-        )
+    )
 
     # This should fail
-    assertmsg = 'R2: BGP-wide graceful-shutdown config not rejected even though it is enabled in VRF1'
-    assert re.search("global graceful-shutdown not permitted", ret) is not None, assertmsg
+    assertmsg = "R2: BGP-wide graceful-shutdown config not rejected even though it is enabled in VRF1"
+    assert (
+        re.search("global graceful-shutdown not permitted", ret) is not None
+    ), assertmsg
 
-    logger.info('\nTest #4: Successful, BGP-wide graceful-shutdown rejected as it is enabled in VRF')
+    logger.info(
+        "\nTest #4: Successful, BGP-wide graceful-shutdown rejected as it is enabled in VRF"
+    )
 
-
-    #"Test #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers"
-    logger.info('\nTest #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers')
+    # "Test #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers"
+    logger.info(
+        "\nTest #5: Turn off graceful-shutdown on R2 in VRF1 and check routes on peers"
+    )
 
     r2.vtysh_cmd(
         """
@@ -286,27 +326,34 @@ def test_bgp_gshut():
             router bgp 65001 vrf vrf1
               no bgp graceful-shutdown
         """
-        )
+    )
 
     # R1 and R3 should see no change to their routes
-    _, result = _run_cmd_and_check(r1, 'show ip bgp 13.1.1.1/32 json', 'r1/bgp_route_1.json')
-    assertmsg = 'R1: Route 13.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r1, "show ip bgp 13.1.1.1/32 json", "r1/bgp_route_1.json"
+    )
+    assertmsg = "R1: Route 13.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
-    _, result = _run_cmd_and_check(r3, 'show ip bgp 11.1.1.1/32 json', 'r3/bgp_route_1.json')
-    assertmsg = 'R3: Route 11.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r3, "show ip bgp 11.1.1.1/32 json", "r3/bgp_route_1.json"
+    )
+    assertmsg = "R3: Route 11.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
     # R5 should see routes from R2 with original attributes.
-    _, result = _run_cmd_and_check(r5, 'show ip bgp 14.1.1.1/32 json', 'r5/bgp_route_1.json')
-    assertmsg = 'R5: Route 14.1.1.1/32 not present or has unexpected params'
+    _, result = _run_cmd_and_check(
+        r5, "show ip bgp 14.1.1.1/32 json", "r5/bgp_route_1.json"
+    )
+    assertmsg = "R5: Route 14.1.1.1/32 not present or has unexpected params"
     assert result is None, assertmsg
 
+    logger.info(
+        "\nTest #5: Successful, routes have their original attributes with default LPREF and without GSHUT"
+    )
 
-    logger.info('\nTest #5: Successful, routes have their original attributes with default LPREF and without GSHUT')
-
+    # tgen.mininet_cli()
 
-    #tgen.mininet_cli()
 
 if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
index 6e6b9edde2da21cf0808ab24ea02e25aa03e88f1..ae574319b30fb93e6e5c54f66b02b746cac29bb0 100644 (file)
@@ -18,6 +18,8 @@ router bgp 5227
      network 5.1.0.0/24 route-map rm-nh
      network 5.1.1.0/24 route-map rm-nh
      redistribute sharp route-map sharp-nh
+     network 6.0.1.0/24 route-map rm-nh
+     network 6.0.2.0/24 route-map rm-nh-same
      neighbor 192.168.1.1 activate
  exit-address-family
 !
@@ -41,5 +43,13 @@ route-map sharp-nh permit 10
  set extcommunity rt 80:987
  set community 0:65
 !
-
+route-map rm-nh-same permit 10
+ match ip address al-any
+ set ip next-hop 99.0.0.1
+ set local-preference 100
+ set metric 100
+ set large-community 12:34:11
+ set extcommunity rt 89:123
+ set community 0:67
+!
 end
index 618acabd9f0fceae18fb88394a81207f628426d6..599e2ddc1eb497dd5ae2cb639463d781351196ec 100644 (file)
@@ -18,6 +18,8 @@ router bgp 5227
      network 5.1.0.0/24 route-map rm-nh
      network 5.1.1.0/24 route-map rm-nh
      redistribute sharp route-map sharp-nh
+     network 6.0.1.0/24 route-map rm-nh
+     network 6.0.2.0/24 route-map rm-nh-same
      neighbor 192.168.1.1 activate
  exit-address-family
 !
@@ -41,5 +43,13 @@ route-map sharp-nh permit 10
  set extcommunity rt 70:456
  set community 0:66
 !
-
+route-map rm-nh-same permit 10
+ match ip address al-any
+ set ip next-hop 99.0.0.2
+ set local-preference 100
+ set metric 100
+ set large-community 12:34:12
+ set extcommunity rt 89:123
+ set community 0:67
+!
 end
index 85c5973e6f3f4a60fcb271c24efe9a14611695d2..e316de569049487d0457d6230b84dd80952c0b3c 100644 (file)
@@ -17,6 +17,8 @@ router bgp 5227
      network 99.0.0.3/32
      network 5.1.2.0/24 route-map rm-nh
      network 5.1.3.0/24 route-map rm-nh
+     network 6.0.1.0/24 route-map rm-nh
+     network 6.0.2.0/24 route-map rm-nh-same
      neighbor 192.168.1.1 activate
  exit-address-family
 !
@@ -31,5 +33,13 @@ route-map rm-nh permit 10
  set extcommunity rt 89:123
  set community 0:67
 !
-
+route-map rm-nh-same permit 10
+ match ip address al-any
+ set ip next-hop 99.0.0.3
+ set local-preference 100
+ set metric 100
+ set large-community 12:34:13
+ set extcommunity rt 89:123
+ set community 0:67
+!
 end
index 6a5075a0002adcf8df0e19bff7552ec450400d01..60d9e931083fbf23a564f108d8c7c3947459b5b8 100644 (file)
@@ -17,6 +17,8 @@ router bgp 5228 vrf ce4-cust2
      network 99.0.0.4/32
      network 5.4.2.0/24 route-map rm-nh
      network 5.4.3.0/24 route-map rm-nh
+     network 6.0.1.0/24 route-map rm-nh
+     network 6.0.2.0/24 route-map rm-nh-same
      neighbor 192.168.2.1 activate
  exit-address-family
 !
@@ -31,5 +33,13 @@ route-map rm-nh permit 10
  set extcommunity rt 89:123
  set community 0:67
 !
-
+route-map rm-nh-same permit 10
+ match ip address al-any
+ set ip next-hop 99.0.0.4
+ set local-preference 100
+ set metric 100
+ set large-community 12:34:14
+ set extcommunity rt 89:123
+ set community 0:67
+!
 end
index f5a29b95c94dbef406c4baaf8a188c60bcadb377..98d2a3bafc3f2103eb76b20aecd607c4216adb86 100644 (file)
@@ -14,6 +14,8 @@ from bgprib import bgpribRequireVpnRoutes, bgpribRequireUnicastRoutes
 want = [
     {"p": "5.1.0.0/24", "n": "99.0.0.1"},
     {"p": "5.1.1.0/24", "n": "99.0.0.1"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.1"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.1"},
     {"p": "99.0.0.1/32", "n": "0.0.0.0"},
 ]
 bgpribRequireUnicastRoutes("ce1", "ipv4", "", "Cust 1 routes in ce1", want)
@@ -21,6 +23,8 @@ bgpribRequireUnicastRoutes("ce1", "ipv4", "", "Cust 1 routes in ce1", want)
 want = [
     {"p": "5.1.0.0/24", "n": "99.0.0.2"},
     {"p": "5.1.1.0/24", "n": "99.0.0.2"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.2"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.2"},
     {"p": "99.0.0.2/32", "n": "0.0.0.0"},
 ]
 bgpribRequireUnicastRoutes("ce2", "ipv4", "", "Cust 2 routes in ce1", want)
@@ -28,6 +32,8 @@ bgpribRequireUnicastRoutes("ce2", "ipv4", "", "Cust 2 routes in ce1", want)
 want = [
     {"p": "5.1.2.0/24", "n": "99.0.0.3"},
     {"p": "5.1.3.0/24", "n": "99.0.0.3"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.3"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.3"},
     {"p": "99.0.0.3/32", "n": "0.0.0.0"},
 ]
 bgpribRequireUnicastRoutes("ce3", "ipv4", "", "Cust 3 routes in ce1", want)
@@ -35,6 +41,8 @@ bgpribRequireUnicastRoutes("ce3", "ipv4", "", "Cust 3 routes in ce1", want)
 want = [
     {"p": "5.4.2.0/24", "n": "99.0.0.4"},
     {"p": "5.4.3.0/24", "n": "99.0.0.4"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.4"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.4"},
     {"p": "99.0.0.4/32", "n": "0.0.0.0"},
 ]
 bgpribRequireUnicastRoutes("ce4", "ipv4", "ce4-cust2", "Cust 4 routes in ce1", want)
@@ -49,6 +57,8 @@ bgpribRequireUnicastRoutes("ce4", "ipv4", "ce4-cust2", "Cust 4 routes in ce1", w
 want_r1_cust1_routes = [
     {"p": "5.1.0.0/24", "n": "99.0.0.1"},
     {"p": "5.1.1.0/24", "n": "99.0.0.1"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.1"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.1"},
     {"p": "99.0.0.1/32", "n": "192.168.1.2"},
 ]
 bgpribRequireUnicastRoutes(
@@ -58,6 +68,8 @@ bgpribRequireUnicastRoutes(
 want_r3_cust1_routes = [
     {"p": "5.1.0.0/24", "n": "99.0.0.2"},
     {"p": "5.1.1.0/24", "n": "99.0.0.2"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.2"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.2"},
     {"p": "99.0.0.2/32", "n": "192.168.1.2"},
 ]
 bgpribRequireUnicastRoutes(
@@ -67,6 +79,8 @@ bgpribRequireUnicastRoutes(
 want_r4_cust1_routes = [
     {"p": "5.1.2.0/24", "n": "99.0.0.3"},
     {"p": "5.1.3.0/24", "n": "99.0.0.3"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.3"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.3"},
     {"p": "99.0.0.3/32", "n": "192.168.1.2"},
 ]
 bgpribRequireUnicastRoutes(
@@ -76,6 +90,8 @@ bgpribRequireUnicastRoutes(
 want_r4_cust2_routes = [
     {"p": "5.4.2.0/24", "n": "99.0.0.4"},
     {"p": "5.4.3.0/24", "n": "99.0.0.4"},
+    {"p": "6.0.1.0/24", "n": "99.0.0.4"},
+    {"p": "6.0.2.0/24", "n": "99.0.0.4"},
     {"p": "99.0.0.4/32", "n": "192.168.2.2"},
 ]
 bgpribRequireUnicastRoutes(
@@ -152,23 +168,27 @@ else:
     luCommand(
         "r1",
         'vtysh -c "show bgp ipv4 vpn"',
-        r"Distinguisher:  *10:1.*5.1.0.0/24 *99.0.0.1\b.*5.1.1.0/24 *99.0.0.1\b.*99.0.0.1/32 *192.168.1.2\b",
+        r"Distinguisher:  *10:1.*5.1.0.0/24 *99.0.0.1\b.*5.1.1.0/24 *99.0.0.1\b.*6.0.1.0/24 *99.0.0.1\b.*6.0.2.0/24 *99.0.0.1\b.*99.0.0.1/32 *192.168.1.2\b",
         "pass",
         "vrf->vpn routes",
     )
     luCommand(
         "r3",
         'vtysh -c "show bgp ipv4 vpn"',
-        r"Distinguisher:  *10:3.*5.1.0.0/24 *99.0.0.2\b.*5.1.1.0/24 *99.0.0.2\b.*99.0.0.2/32 *192.168.1.2\b",
+        r"Distinguisher:  *10:3.*5.1.0.0/24 *99.0.0.2\b.*5.1.1.0/24 *99.0.0.2\b.*6.0.1.0/24 *99.0.0.2\b.*6.0.2.0/24 *99.0.0.2\b.*99.0.0.2/32 *192.168.1.2\b",
         "pass",
         "vrf->vpn routes",
     )
     want = [
         {"rd": "10:41", "p": "5.1.2.0/24", "n": "99.0.0.3"},
         {"rd": "10:41", "p": "5.1.3.0/24", "n": "99.0.0.3"},
+        {"rd": "10:41", "p": "6.0.1.0/24", "n": "99.0.0.3"},
+        {"rd": "10:41", "p": "6.0.2.0/24", "n": "99.0.0.3"},
         {"rd": "10:41", "p": "99.0.0.3/32", "n": "192.168.1.2"},
         {"rd": "10:42", "p": "5.4.2.0/24", "n": "99.0.0.4"},
         {"rd": "10:42", "p": "5.4.3.0/24", "n": "99.0.0.4"},
+        {"rd": "10:42", "p": "6.0.1.0/24", "n": "99.0.0.4"},
+        {"rd": "10:42", "p": "6.0.2.0/24", "n": "99.0.0.4"},
         {"rd": "10:42", "p": "99.0.0.4/32", "n": "192.168.2.2"},
     ]
     bgpribRequireVpnRoutes("r4", "vrf->vpn routes", want)
@@ -266,57 +286,114 @@ bgpribRequireVpnRoutes(
 # PE routers: VRFs contain routes from remote customer nets
 ########################################################################
 want_r1_remote_cust1_routes = [
-    {"p": "5.1.0.0/24", "n": "3.3.3.3"},
-    {"p": "5.1.1.0/24", "n": "3.3.3.3"},
-    {"p": "99.0.0.2/32", "n": "3.3.3.3"},
+    {"p": "5.1.0.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "5.1.0.0/24", "n": "99.0.0.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "5.1.1.0/24", "n": "99.0.0.1", "bp": True},
     {"p": "5.1.2.0/24", "n": "4.4.4.4"},
     {"p": "5.1.3.0/24", "n": "4.4.4.4"},
-    {"p": "99.0.0.3/32", "n": "4.4.4.4"},
     {"p": "5.4.2.0/24", "n": "4.4.4.4"},
     {"p": "5.4.3.0/24", "n": "4.4.4.4"},
+    {"p": "6.0.1.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "4.4.4.4", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.1", "bp": True},
+    {"p": "6.0.2.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.2.0/24", "n": "4.4.4.4", "bp": False},
+    {"p": "6.0.2.0/24", "n": "99.0.0.1", "bp": True},
+    {"p": "99.0.0.1/32", "n": "192.168.1.2", "bp": True},
+    {"p": "99.0.0.2/32", "n": "3.3.3.3"},
     {"p": "99.0.0.3/32", "n": "4.4.4.4"},
+    {"p": "99.0.0.4/32", "n": "4.4.4.4"},
 ]
 bgpribRequireUnicastRoutes(
-    "r1", "ipv4", "r1-cust1", "Customer 1 routes in r1 vrf", want_r1_remote_cust1_routes
+    "r1",
+    "ipv4",
+    "r1-cust1",
+    "Customer 1 routes in r1 vrf (2)",
+    want_r1_remote_cust1_routes,
+    debug=False,
 )
 
 want_r3_remote_cust1_routes = [
-    {"p": "5.1.0.0/24", "n": "1.1.1.1"},
-    {"p": "5.1.1.0/24", "n": "1.1.1.1"},
-    {"p": "99.0.0.1/32", "n": "1.1.1.1"},
-    {"p": "5.1.2.0/24", "n": "4.4.4.4"},
-    {"p": "5.1.3.0/24", "n": "4.4.4.4"},
-    {"p": "99.0.0.3/32", "n": "4.4.4.4"},
-    {"p": "5.4.2.0/24", "n": "4.4.4.4"},
-    {"p": "5.4.3.0/24", "n": "4.4.4.4"},
-    {"p": "99.0.0.3/32", "n": "4.4.4.4"},
+    {"p": "5.1.0.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "5.1.0.0/24", "n": "99.0.0.2", "bp": False},
+    {"p": "5.1.1.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "99.0.0.2", "bp": False},
+    {"p": "5.1.2.0/24", "n": "4.4.4.4", "bp": True},
+    {"p": "5.1.3.0/24", "n": "4.4.4.4", "bp": True},
+    {"p": "5.4.2.0/24", "n": "4.4.4.4", "bp": True},
+    {"p": "5.4.3.0/24", "n": "4.4.4.4", "bp": True},
+    {"p": "6.0.1.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "4.4.4.4", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.2", "bp": False},
+    {"p": "6.0.2.0/24", "n": "1.1.1.1", "bp": False},
+    {"p": "6.0.2.0/24", "n": "4.4.4.4", "bp": False},
+    {"p": "6.0.2.0/24", "n": "99.0.0.2", "bp": True},
+    {"p": "99.0.0.1/32", "n": "1.1.1.1", "bp": True},
+    {"p": "99.0.0.3/32", "n": "4.4.4.4", "bp": True},
+    {"p": "99.0.0.4/32", "n": "4.4.4.4", "bp": True},
 ]
 bgpribRequireUnicastRoutes(
-    "r3", "ipv4", "r3-cust1", "Customer 1 routes in r3 vrf", want_r3_remote_cust1_routes
+    "r3",
+    "ipv4",
+    "r3-cust1",
+    "Customer 1 routes in r3 vrf (2)",
+    want_r3_remote_cust1_routes,
+    debug=False,
 )
 
 want_r4_remote_cust1_routes = [
-    {"p": "5.1.0.0/24", "n": "1.1.1.1"},
-    {"p": "5.1.1.0/24", "n": "1.1.1.1"},
-    {"p": "5.1.0.0/24", "n": "3.3.3.3"},
-    {"p": "5.1.1.0/24", "n": "3.3.3.3"},
-    {"p": "99.0.0.1/32", "n": "1.1.1.1"},
-    {"p": "99.0.0.2/32", "n": "3.3.3.3"},
+    {"p": "5.1.0.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "5.1.0.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "5.1.1.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.4", "bp": False},
+    {"p": "6.0.2.0/24", "n": "1.1.1.1", "bp": False},
+    {"p": "6.0.2.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.2.0/24", "n": "99.0.0.3", "bp": False},
+    {"p": "6.0.2.0/24", "n": "99.0.0.4", "bp": True},
+    {"p": "99.0.0.1/32", "n": "1.1.1.1", "bp": True},
+    {"p": "99.0.0.2/32", "n": "3.3.3.3", "bp": True},
+    {"p": "99.0.0.3/32", "n": "192.168.1.2", "bp": True},
+    {"p": "99.0.0.4/32", "n": "192.168.2.2", "bp": True},
 ]
 bgpribRequireUnicastRoutes(
-    "r4", "ipv4", "r4-cust1", "Customer 1 routes in r4 vrf", want_r4_remote_cust1_routes
+    "r4",
+    "ipv4",
+    "r4-cust1",
+    "Customer 1 routes in r4 vrf (2)",
+    want_r4_remote_cust1_routes,
+    debug=False,
 )
 
 want_r4_remote_cust2_routes = [
-    {"p": "5.1.0.0/24", "n": "1.1.1.1"},
-    {"p": "5.1.1.0/24", "n": "1.1.1.1"},
-    {"p": "5.1.0.0/24", "n": "3.3.3.3"},
-    {"p": "5.1.1.0/24", "n": "3.3.3.3"},
-    {"p": "99.0.0.1/32", "n": "1.1.1.1"},
-    {"p": "99.0.0.2/32", "n": "3.3.3.3"},
+    {"p": "5.1.0.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "5.1.0.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "5.1.1.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "1.1.1.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.3", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.4", "bp": False},
+    {"p": "6.0.2.0/24", "n": "1.1.1.1", "bp": False},
+    {"p": "6.0.2.0/24", "n": "3.3.3.3", "bp": False},
+    {"p": "6.0.2.0/24", "n": "99.0.0.3", "bp": True},
+    {"p": "6.0.2.0/24", "n": "99.0.0.4", "bp": False},
+    {"p": "99.0.0.1/32", "n": "1.1.1.1", "bp": True},
+    {"p": "99.0.0.2/32", "n": "3.3.3.3", "bp": True},
+    {"p": "99.0.0.3/32", "n": "192.168.1.2", "bp": True},
+    {"p": "99.0.0.4/32", "n": "192.168.2.2", "bp": True},
 ]
 bgpribRequireUnicastRoutes(
-    "r4", "ipv4", "r4-cust2", "Customer 2 routes in r4 vrf", want_r4_remote_cust2_routes
+    "r4",
+    "ipv4",
+    "r4-cust2",
+    "Customer 2 routes in r4 vrf (2)",
+    want_r4_remote_cust2_routes,
+    debug=False,
 )
 
 
@@ -330,36 +407,49 @@ bgpribRequireUnicastRoutes(
 luCommand(
     "ce1",
     'vtysh -c "show bgp ipv4 uni"',
-    "10 routes and 10",
+    "12 routes and 12",
     "wait",
     "Local and remote routes",
     10,
 )
 want = [
-    {"p": "5.1.2.0/24", "n": "192.168.1.1"},
-    {"p": "5.1.3.0/24", "n": "192.168.1.1"},
-    {"p": "5.4.2.0/24", "n": "192.168.1.1"},
-    {"p": "5.4.3.0/24", "n": "192.168.1.1"},
+    {"p": "5.1.0.0/24", "n": "99.0.0.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "99.0.0.1", "bp": True},
+    {"p": "5.1.2.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.1.3.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.4.2.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.4.3.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "99.0.0.1", "bp": True},
+    {"p": "6.0.2.0/24", "n": "99.0.0.1", "bp": True},
 ]
-bgpribRequireUnicastRoutes("ce1", "ipv4", "", "Cust 1 routes from remote", want)
+bgpribRequireUnicastRoutes(
+    "ce1", "ipv4", "", "Cust 1 routes from remote", want, debug=False
+)
 
 luCommand(
     "ce2",
     'vtysh -c "show bgp ipv4 uni"',
-    "10 routes and 12",
+    "12 routes and 15",
     "wait",
     "Local and remote routes",
     10,
 )
 want = [
-    {"p": "5.1.0.0/24", "n": "192.168.1.1"},
-    {"p": "5.1.1.0/24", "n": "192.168.1.1"},
-    {"p": "5.1.2.0/24", "n": "192.168.1.1"},
-    {"p": "5.1.3.0/24", "n": "192.168.1.1"},
-    {"p": "5.4.2.0/24", "n": "192.168.1.1"},
-    {"p": "5.4.3.0/24", "n": "192.168.1.1"},
+    {"p": "5.1.0.0/24", "n": "192.168.1.1", "bp": False},
+    {"p": "5.1.0.0/24", "n": "99.0.0.2", "bp": True},
+    {"p": "5.1.1.0/24", "n": "192.168.1.1", "bp": False},
+    {"p": "5.1.1.0/24", "n": "99.0.0.2", "bp": True},
+    {"p": "5.1.2.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.1.3.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.4.2.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.4.3.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "192.168.1.1", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.2", "bp": True},
+    {"p": "6.0.2.0/24", "n": "99.0.0.2", "bp": True},
 ]
-bgpribRequireUnicastRoutes("ce2", "ipv4", "", "Cust 1 routes from remote", want)
+bgpribRequireUnicastRoutes(
+    "ce2", "ipv4", "", "Cust 1 routes from remote", want, debug=False
+)
 
 # human readable output for debugging
 luCommand("r4", 'vtysh -c "show bgp vrf r4-cust1 ipv4 uni"')
@@ -371,34 +461,159 @@ luCommand("r4", 'vtysh -c "show ip route vrf r4-cust2"')
 luCommand(
     "ce3",
     'vtysh -c "show bgp ipv4 uni"',
-    "10 routes and 10",
+    "12 routes and 14",
     "wait",
     "Local and remote routes",
     10,
 )
 # Requires bvl-bug-degenerate-no-label fix (FRR PR #2053)
 want = [
-    {"p": "5.1.0.0/24", "n": "192.168.1.1"},
-    {"p": "5.1.1.0/24", "n": "192.168.1.1"},
-    {"p": "5.4.2.0/24", "n": "192.168.1.1"},
-    {"p": "5.4.3.0/24", "n": "192.168.1.1"},
+    {"p": "5.1.0.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.4.2.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "5.4.3.0/24", "n": "192.168.1.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "192.168.1.1", "bp": False},
+    {"p": "6.0.2.0/24", "n": "192.168.1.1", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.3", "bp": True},
+    {"p": "6.0.2.0/24", "n": "99.0.0.3", "bp": True},
 ]
-bgpribRequireUnicastRoutes("ce3", "ipv4", "", "Cust 1 routes from remote", want)
+bgpribRequireUnicastRoutes(
+    "ce3", "ipv4", "", "Cust 1 routes from remote", want, debug=False
+)
 
 luCommand(
     "ce4",
     'vtysh -c "show bgp vrf ce4-cust2 ipv4 uni"',
-    "10 routes and 10",
+    "12 routes and 14",
     "wait",
     "Local and remote routes",
     10,
 )
 want = [
-    {"p": "5.1.0.0/24", "n": "192.168.2.1"},
-    {"p": "5.1.1.0/24", "n": "192.168.2.1"},
-    {"p": "5.1.2.0/24", "n": "192.168.2.1"},
-    {"p": "5.1.3.0/24", "n": "192.168.2.1"},
+    {"p": "5.1.0.0/24", "n": "192.168.2.1", "bp": True},
+    {"p": "5.1.1.0/24", "n": "192.168.2.1", "bp": True},
+    {"p": "5.1.2.0/24", "n": "192.168.2.1", "bp": True},
+    {"p": "5.1.3.0/24", "n": "192.168.2.1", "bp": True},
+    {"p": "6.0.1.0/24", "n": "192.168.2.1", "bp": False},
+    {"p": "6.0.2.0/24", "n": "192.168.2.1", "bp": False},
+    {"p": "6.0.1.0/24", "n": "99.0.0.4", "bp": True},
+    {"p": "6.0.2.0/24", "n": "99.0.0.4", "bp": True},
 ]
 bgpribRequireUnicastRoutes(
-    "ce4", "ipv4", "ce4-cust2", "Cust 2 routes from remote", want
+    "ce4", "ipv4", "ce4-cust2", "Cust 2 routes from remote", want, debug=False
+)
+
+# verify details of exported/imported routes
+luCommand(
+    "ce1",
+    'vtysh -c "show bgp ipv4 uni 6.0.1.0"',
+    "1 available.*192.168.1.1.*99.0.0.1.*Community: 0:67.*Extended Community: RT:89:123.*Large Community: 12:34:56",
+    "pass",
+    "Redundant route 1 details",
+)
+luCommand(
+    "ce2",
+    'vtysh -c "show bgp ipv4 uni 6.0.1.0"',
+    "2 available, best .*192.168.1.1.* Local.* 192.168.1.1 from 192.168.1.1 .192.168.1.1"
+    + ".* Origin IGP, metric 98, localpref 123, valid, internal"
+    + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:56",
+    "pass",
+    "Redundant route 1 details",
+)
+luCommand(
+    "ce2",
+    'vtysh -c "show bgp ipv4 uni 6.0.1.0"',
+    "2 available, best .*192.168.1.1.* Local.* 99.0.0.2 from 0.0.0.0 .99.0.0.2"
+    + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .Weight"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:56",
+    "pass",
+    "Redundant route 1 details",
+)
+luCommand(
+    "ce3",
+    'vtysh -c "show bgp ipv4 uni 6.0.1.0"',
+    "2 available, best "
+    ".* Local.* 99.0.0.3 from 0.0.0.0 .99.0.0.3"
+    + ".* Origin IGP, metric 200, localpref 50, weight 32768, valid, sourced, local, best .Weight"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:56",
+    "pass",
+    "Redundant route 1 details",
+)
+luCommand(
+    "ce3",
+    'vtysh -c "show bgp ipv4 uni 6.0.1.0"',
+    "2 available, best "
+    ".* Local.* 192.168.1.1 from 192.168.1.1 .192.168.1.1"
+    + ".* Origin IGP, metric 98, localpref 123, valid, internal"
+    + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:56",
+    "pass",
+    "Redundant route 1 details",
+)
+luCommand(
+    "ce4",
+    'vtysh -c "show bgp vrf ce4-cust2 ipv4 6.0.1.0"',
+    "2 available, best .*192.168.2.1.* Local.* 192.168.2.1 from 192.168.2.1 .192.168.2.1"
+    + ".* Origin IGP, metric 98, localpref 123, valid, internal"
+    + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:56"
+    + ".* Local.* 99.0.0.4 from 0.0.0.0 .99.0.0.4"
+    + ".* Origin IGP, metric 200, localpref 50, weight 32768, valid, sourced, local, best .Weight"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:56",
+    "pass",
+    "Redundant route 1 details",
+)
+
+luCommand(
+    "ce1",
+    'vtysh -c "show bgp ipv4 uni 6.0.2.0"',
+    "1 available, best .*192.168.1.1.* Local.* 99.0.0.1 from 0.0.0.0 .99.0.0.1"
+    + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .First path received"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:11",
+    "pass",
+    "Redundant route 2 details",
+)
+luCommand(
+    "ce2",
+    'vtysh -c "show bgp ipv4 uni 6.0.2.0"',
+    "1 available, best .*192.168.1.1.* Local.* 99.0.0.2 from 0.0.0.0 .99.0.0.2"
+    + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .First path received"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:12",
+    "pass",
+    "Redundant route 2 details",
+)
+luCommand(
+    "ce3",
+    'vtysh -c "show bgp ipv4 uni 6.0.2.0"',
+    "2 available, best .*192.168.1.1.* Local.* 99.0.0.3 from 0.0.0.0 .99.0.0.3"
+    + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .Weight"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:13",
+    "pass",
+    "Redundant route 2 details",
+)
+luCommand(
+    "ce3",
+    'vtysh -c "show bgp ipv4 uni 6.0.2.0"',
+    "2 available, best .*192.168.1.1.* Local.* 192.168.1.1 from 192.168.1.1 .192.168.1.1"
+    + ".* Origin IGP, metric 100, localpref 100, valid, internal"
+    + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:14",
+    "pass",
+    "Redundant route 2 details",
+)
+luCommand(
+    "ce4",
+    'vtysh -c "show bgp  vrf ce4-cust2 ipv4 6.0.2.0"',
+    "2 available, best .*192.168.2.1.* Local.* 192.168.2.1 from 192.168.2.1 .192.168.2.1"
+    + ".* Origin IGP, metric 100, localpref 100, valid, internal"
+    + ".* Community: 0:67.* Extended Community: RT:52:100 RT:89:123.* Large Community: 12:34:13",
+    "pass",
+    "Redundant route 2 details",
+)
+luCommand(
+    "ce4",
+    'vtysh -c "show bgp  vrf ce4-cust2 ipv4 6.0.2.0"',
+    "2 available, best .*192.168.2.1.* Local.* 99.0.0.4 from 0.0.0.0 .99.0.0.4"
+    + ".* Origin IGP, metric 100, localpref 100, weight 32768, valid, sourced, local, best .Weight"
+    + ".* Community: 0:67.* Extended Community: RT:89:123.* Large Community: 12:34:14",
+    "pass",
+    "Redundant route 2 details",
 )
+# done
index b4fa240495cef562b3b5f06ab5c50c6240479dda..7990533f3a4f3ebaa120228168ee52d2501ee738 100644 (file)
@@ -49,7 +49,7 @@ if ret != False and found != None:
             luCommand(
                 rtr,
                 'vtysh -c "show bgp ipv4 uni" | grep Display',
-                " 10 route",
+                " 12 route",
                 "wait",
                 "BGP routes removed",
                 wait,
index dc06b7131a5c336e05b50345132d785d1d501b2f..40489f438f6892916fc5c850eef6e0b5feed1dc9 100644 (file)
@@ -67,7 +67,7 @@ from lib.common_config import (
     verify_bgp_community,
     step,
     check_address_types,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
@@ -144,7 +144,7 @@ def setup_module(mod):
     * `mod`: module name
     """
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
index bb88e47415d3933bd30b1cc626e78ee34b08045f..9c0355a3e9b2bcbd0ae45b20a82768afc1ceddc4 100644 (file)
@@ -91,7 +91,7 @@ from lib.common_config import (
     verify_route_maps,
     create_static_routes,
     check_address_types,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 from lib.topolog import logger
 from lib.bgp import verify_bgp_convergence, create_router_bgp, clear_bgp_and_verify
@@ -135,7 +135,7 @@ def setup_module(mod):
     """
 
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
index dff69e3a27f89e4dcc7262287d7b91984840dc69..f09ff206516d07619bd976dd66d3a1c4ad3e42ac 100644 (file)
@@ -35,7 +35,7 @@ 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, '../'))
+sys.path.append(os.path.join(CWD, "../"))
 
 # pylint: disable=C0413
 # Import topogen and topotest helpers
@@ -63,8 +63,10 @@ this scenario, the servers are also routers as they have to announce
 anycast IP (VIP) addresses via BGP.
 """
 
+
 class BgpLinkBwTopo(Topo):
     "Test topology builder"
+
     def build(self, *_args, **_opts):
         "Build function"
         tgen = get_topogen(self)
@@ -73,45 +75,46 @@ class BgpLinkBwTopo(Topo):
         # and 4 servers
         routers = {}
         for i in range(1, 11):
-            routers[i] = tgen.add_router('r{}'.format(i))
+            routers[i] = tgen.add_router("r{}".format(i))
 
         # Create 13 "switches" - to interconnect the above routers
         switches = {}
         for i in range(1, 14):
-            switches[i] = tgen.add_switch('s{}'.format(i))
+            switches[i] = tgen.add_switch("s{}".format(i))
 
         # Interconnect R1 (super-spine) to R2 and R3 (the two spines)
-        switches[1].add_link(tgen.gears['r1'])
-        switches[1].add_link(tgen.gears['r2'])
-        switches[2].add_link(tgen.gears['r1'])
-        switches[2].add_link(tgen.gears['r3'])
+        switches[1].add_link(tgen.gears["r1"])
+        switches[1].add_link(tgen.gears["r2"])
+        switches[2].add_link(tgen.gears["r1"])
+        switches[2].add_link(tgen.gears["r3"])
 
         # Interconnect R2 (spine in pod-1) to R4 and R5 (the associated
         # leaf switches)
-        switches[3].add_link(tgen.gears['r2'])
-        switches[3].add_link(tgen.gears['r4'])
-        switches[4].add_link(tgen.gears['r2'])
-        switches[4].add_link(tgen.gears['r5'])
+        switches[3].add_link(tgen.gears["r2"])
+        switches[3].add_link(tgen.gears["r4"])
+        switches[4].add_link(tgen.gears["r2"])
+        switches[4].add_link(tgen.gears["r5"])
 
         # Interconnect R3 (spine in pod-2) to R6 (associated leaf)
-        switches[5].add_link(tgen.gears['r3'])
-        switches[5].add_link(tgen.gears['r6'])
+        switches[5].add_link(tgen.gears["r3"])
+        switches[5].add_link(tgen.gears["r6"])
 
         # Interconnect leaf switches to servers
-        switches[6].add_link(tgen.gears['r4'])
-        switches[6].add_link(tgen.gears['r7'])
-        switches[7].add_link(tgen.gears['r4'])
-        switches[7].add_link(tgen.gears['r8'])
-        switches[8].add_link(tgen.gears['r5'])
-        switches[8].add_link(tgen.gears['r9'])
-        switches[9].add_link(tgen.gears['r6'])
-        switches[9].add_link(tgen.gears['r10'])
+        switches[6].add_link(tgen.gears["r4"])
+        switches[6].add_link(tgen.gears["r7"])
+        switches[7].add_link(tgen.gears["r4"])
+        switches[7].add_link(tgen.gears["r8"])
+        switches[8].add_link(tgen.gears["r5"])
+        switches[8].add_link(tgen.gears["r9"])
+        switches[9].add_link(tgen.gears["r6"])
+        switches[9].add_link(tgen.gears["r10"])
 
         # Create empty networks for the servers
-        switches[10].add_link(tgen.gears['r7'])
-        switches[11].add_link(tgen.gears['r8'])
-        switches[12].add_link(tgen.gears['r9'])
-        switches[13].add_link(tgen.gears['r10'])
+        switches[10].add_link(tgen.gears["r7"])
+        switches[11].add_link(tgen.gears["r8"])
+        switches[12].add_link(tgen.gears["r9"])
+        switches[13].add_link(tgen.gears["r10"])
+
 
 def setup_module(mod):
     "Sets up the pytest environment"
@@ -121,395 +124,454 @@ def setup_module(mod):
     router_list = tgen.routers()
     for rname, router in router_list.items():
         router.load_config(
-            TopoRouter.RD_ZEBRA,
-            os.path.join(CWD, '{}/zebra.conf'.format(rname))
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
         )
         router.load_config(
-            TopoRouter.RD_BGP,
-            os.path.join(CWD, '{}/bgpd.conf'.format(rname))
+            TopoRouter.RD_BGP, os.path.join(CWD, "{}/bgpd.conf".format(rname))
         )
 
     # Initialize all routers.
     tgen.start_router()
 
-    #tgen.mininet_cli()
+    # tgen.mininet_cli()
+
 
 def teardown_module(mod):
     "Teardown the pytest environment"
     tgen = get_topogen()
     tgen.stop_topology()
 
+
 def test_bgp_linkbw_adv():
     "Test #1: Test BGP link-bandwidth advertisement based on number of multipaths"
-    logger.info('\nTest #1: Test BGP link-bandwidth advertisement based on number of multipaths')
+    logger.info(
+        "\nTest #1: Test BGP link-bandwidth advertisement based on number of multipaths"
+    )
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
-    r2 = tgen.gears['r2']
+    r1 = tgen.gears["r1"]
+    r2 = tgen.gears["r2"]
 
     # Configure anycast IP on server r7
-    logger.info('Configure anycast IP on server r7')
+    logger.info("Configure anycast IP on server r7")
 
-    tgen.net['r7'].cmd('ip addr add 198.10.1.1/32 dev r7-eth1')
+    tgen.net["r7"].cmd("ip addr add 198.10.1.1/32 dev r7-eth1")
 
     # Check on spine router r2 for link-bw advertisement by leaf router r4
-    logger.info('Check on spine router r2 for link-bw advertisement by leaf router r4')
+    logger.info("Check on spine router r2 for link-bw advertisement by leaf router r4")
 
-    json_file = '{}/r2/bgp-route-1.json'.format(CWD)
+    json_file = "{}/r2/bgp-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r2, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r2, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on spine router r2'
+    assertmsg = "JSON output mismatch on spine router r2"
     assert result is None, assertmsg
 
     # Check on spine router r2 that default weight is used as there is no multipath
-    logger.info('Check on spine router r2 that default weight is used as there is no multipath')
+    logger.info(
+        "Check on spine router r2 that default weight is used as there is no multipath"
+    )
 
-    json_file = '{}/r2/ip-route-1.json'.format(CWD)
+    json_file = "{}/r2/ip-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r2, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r2, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on spine router r2'
+    assertmsg = "JSON output mismatch on spine router r2"
     assert result is None, assertmsg
 
     # Check on super-spine router r1 that link-bw has been propagated by spine router r2
-    logger.info('Check on super-spine router r1 that link-bw has been propagated by spine router r2')
+    logger.info(
+        "Check on super-spine router r1 that link-bw has been propagated by spine router r2"
+    )
 
-    json_file = '{}/r1/bgp-route-1.json'.format(CWD)
+    json_file = "{}/r1/bgp-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
+
 def test_bgp_cumul_linkbw():
     "Test #2: Test cumulative link-bandwidth propagation"
-    logger.info('\nTest #2: Test cumulative link-bandwidth propagation')
+    logger.info("\nTest #2: Test cumulative link-bandwidth propagation")
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
-    r2 = tgen.gears['r2']
-    r4 = tgen.gears['r4']
+    r1 = tgen.gears["r1"]
+    r2 = tgen.gears["r2"]
+    r4 = tgen.gears["r4"]
 
     # Configure anycast IP on additional server r8
-    logger.info('Configure anycast IP on server r8')
+    logger.info("Configure anycast IP on server r8")
 
-    tgen.net['r8'].cmd('ip addr add 198.10.1.1/32 dev r8-eth1')
+    tgen.net["r8"].cmd("ip addr add 198.10.1.1/32 dev r8-eth1")
 
     # Check multipath on leaf router r4
-    logger.info('Check multipath on leaf router r4')
+    logger.info("Check multipath on leaf router r4")
 
-    json_file = '{}/r4/bgp-route-1.json'.format(CWD)
+    json_file = "{}/r4/bgp-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r4, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r4, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on leaf router r4'
+    assertmsg = "JSON output mismatch on leaf router r4"
     assert result is None, assertmsg
 
     # Check regular ECMP is in effect on leaf router r4
-    logger.info('Check regular ECMP is in effect on leaf router r4')
+    logger.info("Check regular ECMP is in effect on leaf router r4")
 
-    json_file = '{}/r4/ip-route-1.json'.format(CWD)
+    json_file = "{}/r4/ip-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r4, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r4, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on leaf router r4'
+    assertmsg = "JSON output mismatch on leaf router r4"
     assert result is None, assertmsg
 
     # Check on spine router r2 that leaf has propagated the cumulative link-bw based on num-multipaths
-    logger.info('Check on spine router r2 that leaf has propagated the cumulative link-bw based on num-multipaths')
+    logger.info(
+        "Check on spine router r2 that leaf has propagated the cumulative link-bw based on num-multipaths"
+    )
 
-    json_file = '{}/r2/bgp-route-2.json'.format(CWD)
+    json_file = "{}/r2/bgp-route-2.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r2, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r2, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on spine router r2'
+    assertmsg = "JSON output mismatch on spine router r2"
     assert result is None, assertmsg
 
+
 def test_weighted_ecmp():
     "Test #3: Test weighted ECMP - multipath with next hop weights"
-    logger.info('\nTest #3: Test weighted ECMP - multipath with next hop weights')
+    logger.info("\nTest #3: Test weighted ECMP - multipath with next hop weights")
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
-    r2 = tgen.gears['r2']
+    r1 = tgen.gears["r1"]
+    r2 = tgen.gears["r2"]
 
     # Configure anycast IP on additional server r9
-    logger.info('Configure anycast IP on server r9')
+    logger.info("Configure anycast IP on server r9")
 
-    tgen.net['r9'].cmd('ip addr add 198.10.1.1/32 dev r9-eth1')
+    tgen.net["r9"].cmd("ip addr add 198.10.1.1/32 dev r9-eth1")
 
     # Check multipath on spine router r2
-    logger.info('Check multipath on spine router r2')
-    json_file = '{}/r2/bgp-route-3.json'.format(CWD)
+    logger.info("Check multipath on spine router r2")
+    json_file = "{}/r2/bgp-route-3.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r2, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r2, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on spine router r2'
+    assertmsg = "JSON output mismatch on spine router r2"
     assert result is None, assertmsg
 
     # Check weighted ECMP is in effect on the spine router r2
-    logger.info('Check weighted ECMP is in effect on the spine router r2')
+    logger.info("Check weighted ECMP is in effect on the spine router r2")
 
-    json_file = '{}/r2/ip-route-2.json'.format(CWD)
+    json_file = "{}/r2/ip-route-2.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r2, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r2, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on spine router r2'
+    assertmsg = "JSON output mismatch on spine router r2"
     assert result is None, assertmsg
 
     # Configure anycast IP on additional server r10
-    logger.info('Configure anycast IP on server r10')
+    logger.info("Configure anycast IP on server r10")
 
-    tgen.net['r10'].cmd('ip addr add 198.10.1.1/32 dev r10-eth1')
+    tgen.net["r10"].cmd("ip addr add 198.10.1.1/32 dev r10-eth1")
 
     # Check multipath on super-spine router r1
-    logger.info('Check multipath on super-spine router r1')
-    json_file = '{}/r1/bgp-route-2.json'.format(CWD)
+    logger.info("Check multipath on super-spine router r1")
+    json_file = "{}/r1/bgp-route-2.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
     # Check weighted ECMP is in effect on the super-spine router r1
-    logger.info('Check weighted ECMP is in effect on the super-spine router r1')
-    json_file = '{}/r1/ip-route-1.json'.format(CWD)
+    logger.info("Check weighted ECMP is in effect on the super-spine router r1")
+    json_file = "{}/r1/ip-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
+
 def test_weighted_ecmp_link_flap():
     "Test #4: Test weighted ECMP rebalancing upon change (link flap)"
-    logger.info('\nTest #4: Test weighted ECMP rebalancing upon change (link flap)')
+    logger.info("\nTest #4: Test weighted ECMP rebalancing upon change (link flap)")
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
-    r2 = tgen.gears['r2']
+    r1 = tgen.gears["r1"]
+    r2 = tgen.gears["r2"]
 
     # Bring down link on server r9
-    logger.info('Bring down link on server r9')
+    logger.info("Bring down link on server r9")
 
-    tgen.net['r9'].cmd('ip link set dev r9-eth1 down')
+    tgen.net["r9"].cmd("ip link set dev r9-eth1 down")
 
     # Check spine router r2 has only one path
-    logger.info('Check spine router r2 has only one path')
+    logger.info("Check spine router r2 has only one path")
 
-    json_file = '{}/r2/ip-route-3.json'.format(CWD)
+    json_file = "{}/r2/ip-route-3.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r2, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r2, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on spine router r2'
+    assertmsg = "JSON output mismatch on spine router r2"
     assert result is None, assertmsg
 
     # Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1
-    logger.info('Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1')
+    logger.info(
+        "Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1"
+    )
 
-    json_file = '{}/r1/bgp-route-3.json'.format(CWD)
+    json_file = "{}/r1/bgp-route-3.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-    json_file = '{}/r1/ip-route-2.json'.format(CWD)
+    json_file = "{}/r1/ip-route-2.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
     # Bring up link on server r9
-    logger.info('Bring up link on server r9')
+    logger.info("Bring up link on server r9")
 
-    tgen.net['r9'].cmd('ip link set dev r9-eth1 up')
+    tgen.net["r9"].cmd("ip link set dev r9-eth1 up")
 
     # Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1
-    logger.info('Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1')
+    logger.info(
+        "Check link-bandwidth change and weighted ECMP rebalance on super-spine router r1"
+    )
 
-    json_file = '{}/r1/bgp-route-2.json'.format(CWD)
+    json_file = "{}/r1/bgp-route-2.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-    json_file = '{}/r1/ip-route-1.json'.format(CWD)
+    json_file = "{}/r1/ip-route-1.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
+
 def test_weighted_ecmp_second_anycast_ip():
     "Test #5: Test weighted ECMP for a second anycast IP"
-    logger.info('\nTest #5: Test weighted ECMP for a second anycast IP')
+    logger.info("\nTest #5: Test weighted ECMP for a second anycast IP")
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
-    r2 = tgen.gears['r2']
+    r1 = tgen.gears["r1"]
+    r2 = tgen.gears["r2"]
 
     # Configure anycast IP on additional server r7, r9 and r10
-    logger.info('Configure anycast IP on server r7, r9 and r10')
+    logger.info("Configure anycast IP on server r7, r9 and r10")
 
-    tgen.net['r7'].cmd('ip addr add 198.10.1.11/32 dev r7-eth1')
-    tgen.net['r9'].cmd('ip addr add 198.10.1.11/32 dev r9-eth1')
-    tgen.net['r10'].cmd('ip addr add 198.10.1.11/32 dev r10-eth1')
+    tgen.net["r7"].cmd("ip addr add 198.10.1.11/32 dev r7-eth1")
+    tgen.net["r9"].cmd("ip addr add 198.10.1.11/32 dev r9-eth1")
+    tgen.net["r10"].cmd("ip addr add 198.10.1.11/32 dev r10-eth1")
 
     # Check link-bandwidth and weighted ECMP on super-spine router r1
-    logger.info('Check link-bandwidth and weighted ECMP on super-spine router r1')
+    logger.info("Check link-bandwidth and weighted ECMP on super-spine router r1")
 
-    json_file = '{}/r1/bgp-route-4.json'.format(CWD)
+    json_file = "{}/r1/bgp-route-4.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show bgp ipv4 uni 198.10.1.11/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.11/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-    json_file = '{}/r1/ip-route-3.json'.format(CWD)
+    json_file = "{}/r1/ip-route-3.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.11/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
+
 def test_paths_with_and_without_linkbw():
     "Test #6: Test paths with and without link-bandwidth - receiver should resort to regular ECMP"
-    logger.info('\nTest #6: Test paths with and without link-bandwidth - receiver should resort to regular ECMP')
+    logger.info(
+        "\nTest #6: Test paths with and without link-bandwidth - receiver should resort to regular ECMP"
+    )
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
+    r1 = tgen.gears["r1"]
 
     # Configure leaf router r6 to not advertise any link-bandwidth
-    logger.info('Configure leaf router r6 to not advertise any link-bandwidth')
+    logger.info("Configure leaf router r6 to not advertise any link-bandwidth")
 
-    tgen.net['r6'].cmd('vtysh -c \"conf t\" -c \"router bgp 65303\" -c \"address-family ipv4 unicast\" -c \"no neighbor 11.1.3.1 route-map anycast_ip out\"')
+    tgen.net["r6"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65303" -c "address-family ipv4 unicast" -c "no neighbor 11.1.3.1 route-map anycast_ip out"'
+    )
 
     # Check link-bandwidth change on super-spine router r1
-    logger.info('Check link-bandwidth change on super-spine router r1')
+    logger.info("Check link-bandwidth change on super-spine router r1")
 
-    json_file = '{}/r1/bgp-route-5.json'.format(CWD)
+    json_file = "{}/r1/bgp-route-5.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show bgp ipv4 uni 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show bgp ipv4 uni 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
     # Check super-spine router r1 resorts to regular ECMP
-    logger.info('Check super-spine router r1 resorts to regular ECMP')
+    logger.info("Check super-spine router r1 resorts to regular ECMP")
 
-    json_file = '{}/r1/ip-route-4.json'.format(CWD)
+    json_file = "{}/r1/ip-route-4.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-    json_file = '{}/r1/ip-route-5.json'.format(CWD)
+    json_file = "{}/r1/ip-route-5.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.11/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=50, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
+
 def test_linkbw_handling_options():
     "Test #7: Test different options for processing link-bandwidth on the receiver"
-    logger.info('\nTest #7: Test different options for processing link-bandwidth on the receiver')
+    logger.info(
+        "\nTest #7: Test different options for processing link-bandwidth on the receiver"
+    )
 
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
-    r1 = tgen.gears['r1']
+    r1 = tgen.gears["r1"]
 
     # Configure super-spine r1 to skip multipaths without link-bandwidth
-    logger.info('Configure super-spine r1 to skip multipaths without link-bandwidth')
+    logger.info("Configure super-spine r1 to skip multipaths without link-bandwidth")
 
-    tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65101\" -c \"bgp bestpath bandwidth skip-missing\"')
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65101" -c "bgp bestpath bandwidth skip-missing"'
+    )
 
     # Check super-spine router r1 resorts to only one path as other path is skipped
-    logger.info('Check super-spine router r1 resorts to only one path as other path is skipped')
+    logger.info(
+        "Check super-spine router r1 resorts to only one path as other path is skipped"
+    )
 
-    json_file = '{}/r1/ip-route-6.json'.format(CWD)
+    json_file = "{}/r1/ip-route-6.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-    json_file = '{}/r1/ip-route-7.json'.format(CWD)
+    json_file = "{}/r1/ip-route-7.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.11/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
     # Configure super-spine r1 to use default-weight for multipaths without link-bandwidth
-    logger.info('Configure super-spine r1 to use default-weight for multipaths without link-bandwidth')
+    logger.info(
+        "Configure super-spine r1 to use default-weight for multipaths without link-bandwidth"
+    )
 
-    tgen.net['r1'].cmd('vtysh -c \"conf t\" -c \"router bgp 65101\" -c \"bgp bestpath bandwidth default-weight-for-missing\"')
+    tgen.net["r1"].cmd(
+        'vtysh -c "conf t" -c "router bgp 65101" -c "bgp bestpath bandwidth default-weight-for-missing"'
+    )
 
     # Check super-spine router r1 uses ECMP with weight 1 for path without link-bandwidth
-    logger.info('Check super-spine router r1 uses ECMP with weight 1 for path without link-bandwidth')
+    logger.info(
+        "Check super-spine router r1 uses ECMP with weight 1 for path without link-bandwidth"
+    )
 
-    json_file = '{}/r1/ip-route-8.json'.format(CWD)
+    json_file = "{}/r1/ip-route-8.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.1/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.1/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-    json_file = '{}/r1/ip-route-9.json'.format(CWD)
+    json_file = "{}/r1/ip-route-9.json".format(CWD)
     expected = json.loads(open(json_file).read())
-    test_func = partial(topotest.router_json_cmp,
-                        r1, 'show ip route 198.10.1.11/32 json', expected)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route 198.10.1.11/32 json", expected
+    )
     _, result = topotest.run_and_expect(test_func, None, count=200, wait=0.5)
-    assertmsg = 'JSON output mismatch on super-spine router r1'
+    assertmsg = "JSON output mismatch on super-spine router r1"
     assert result is None, assertmsg
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index c15b88d37100dfcc791eed966213da73433caebc..cf6b7cc53f24ccc4c91d7002cb39269d9c3a75e4 100644 (file)
@@ -132,7 +132,7 @@ from lib.common_config import (
     create_bgp_community_lists,
     check_router_status,
     apply_raw_config,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 
 from lib.topolog import logger
@@ -211,7 +211,7 @@ def setup_module(mod):
     * `mod`: module name
     """
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
@@ -693,10 +693,12 @@ def test_static_routes_associated_to_specific_vrfs_p0(request):
         )
 
     step(
-        "Verify that static routes 1.x.x.x/32 and 1::x/128 appear " "in VRF BLUE_A table"
+        "Verify that static routes 1.x.x.x/32 and 1::x/128 appear "
+        "in VRF BLUE_A table"
     )
     step(
-        "Verify that static routes 2.x.x.x/32 and 2::x/128 appear " "in VRF BLUE_B table"
+        "Verify that static routes 2.x.x.x/32 and 2::x/128 appear "
+        "in VRF BLUE_B table"
     )
 
     for addr_type in ADDR_TYPES:
index bb13d54019cd4fe2083493d5b848fd2bbfc55c45..cafe758209d7735a422e0878a77f4f14136f6b5d 100644 (file)
@@ -78,7 +78,7 @@ from lib.common_config import (
     get_frr_ipv6_linklocal,
     check_router_status,
     apply_raw_config,
-    required_linux_kernel_version
+    required_linux_kernel_version,
 )
 
 from lib.topolog import logger
@@ -143,7 +143,7 @@ def setup_module(mod):
     * `mod`: module name
     """
     # Required linux kernel version for this suite to run.
-    result = required_linux_kernel_version('4.15')
+    result = required_linux_kernel_version("4.15")
     if result is not True:
         pytest.skip("Kernel requirements are not met")
 
index fef6eb71dc20a1fdd684b0a5eb14e24f7fe9e813..3af944473de52226faaee47d2085bd0517ca34ab 100644 (file)
@@ -91,7 +91,7 @@ jsonFile = "{}/bgp_recursive_route_ebgp_multi_hop.json".format(CWD)
 try:
     with open(jsonFile, "r") as topoJson:
         topo = json.load(topoJson)
-except IOError :
+except IOError:
     logger.info("Could not read file:", jsonFile)
 
 # Global variables
@@ -284,7 +284,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             input_dict_4,
             next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step(
         "Configure a static routes for next hop IP on R2 via multiple"
@@ -317,7 +319,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             }
         }
         result = create_static_routes(tgen, input_dict_3)
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
         step("verify if redistributed routes are now installed in FIB of R2")
         result = verify_rib(
@@ -328,7 +332,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
             protocol="bgp",
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step("Delete 1 route from static recursive for the next-hop IP")
     dut = "r2"
@@ -345,7 +351,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             }
         }
         result = create_static_routes(tgen, input_dict_3)
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
         step("Verify that redistributed routes are withdrawn from FIB of R2")
         result = verify_rib(
@@ -355,7 +363,7 @@ def test_recursive_routes_iBGP_peer_p1(request):
             input_dict_4,
             next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
             protocol="bgp",
-            expected=False
+            expected=False,
         )
         assert result is not True, "Testcase  : Failed \n Error : {}".format(
             tc_name, result
@@ -375,7 +383,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             }
         }
         result = create_static_routes(tgen, input_dict_3)
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
         step("Verify that redistributed routes are again installed" "in FIB of R2")
         result = verify_rib(
@@ -386,7 +396,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             next_hop=topo["routers"]["r3"]["links"]["r1"][addr_type].split("/")[0],
             protocol="bgp",
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step("Configure static route with changed next-hop from same subnet")
     for addr_type in ADDR_TYPES:
@@ -410,7 +422,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             }
         }
         result = create_static_routes(tgen, input_dict_4)
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
         result = verify_rib(tgen, addr_type, "r1", input_dict_4, protocol="static")
         assert result is True, "Testcase {} : Failed \n Error : {}".format(
@@ -455,7 +469,9 @@ def test_recursive_routes_iBGP_peer_p1(request):
             }
         }
         result = create_static_routes(tgen, input_dict_4)
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
         result = verify_rib(tgen, addr_type, "r1", input_dict_4, protocol="static")
         assert result is True, "Testcase {} : Failed \n Error : {}".format(
@@ -578,7 +594,7 @@ def test_next_hop_as_self_ip_p1(request):
             "r2",
             input_dict_4,
             next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
-            expected=False
+            expected=False,
         )
         assert result is not True, "Testcase  : Failed \n Error : {}".format(
             tc_name, result
@@ -614,7 +630,9 @@ def test_next_hop_as_self_ip_p1(request):
             input_dict_4,
             next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step("No shutdown interface on R2 which was shut in previous step")
     intf_r2_r4 = topo["routers"]["r2"]["links"]["r4"]["interface"]
@@ -644,14 +662,16 @@ def test_next_hop_as_self_ip_p1(request):
             input_dict_4,
             next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
         result = verify_rib(
             tgen,
             addr_type,
             "r2",
             input_dict_4,
             next_hop=topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
-            expected=False
+            expected=False,
         )
         assert result is not True, "Testcase  : Failed \n Error : {}".format(
             tc_name, result
@@ -907,7 +927,9 @@ def test_next_hop_with_recursive_lookup_p1(request):
     result = verify_bgp_convergence_from_running_config(tgen, expected=False)
     assert (
         result is not True
-    ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(tc_name, result)
+    ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(
+        tc_name, result
+    )
     logger.info("Expected behaviour: {}".format(result))
 
     for addr_type in ADDR_TYPES:
@@ -1018,7 +1040,7 @@ def test_next_hop_with_recursive_lookup_p1(request):
             input_dict,
             protocol="bgp",
             next_hop=next_hop,
-            expected=False
+            expected=False,
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
@@ -1083,7 +1105,9 @@ def test_next_hop_with_recursive_lookup_p1(request):
     result = verify_bgp_convergence_from_running_config(tgen, expected=False)
     assert (
         result is not True
-    ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(tc_name, result)
+    ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(
+        tc_name, result
+    )
     logger.info("Expected behaviour: {}".format(result))
 
     for addr_type in ADDR_TYPES:
@@ -1099,7 +1123,7 @@ def test_next_hop_with_recursive_lookup_p1(request):
             input_dict,
             protocol="bgp",
             next_hop=next_hop,
-            expected=False
+            expected=False,
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
@@ -1138,7 +1162,9 @@ def test_next_hop_with_recursive_lookup_p1(request):
     result = verify_bgp_convergence_from_running_config(tgen, expected=False)
     assert (
         result is not True
-    ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(tc_name, result)
+    ), "Testcase {} : Failed \n" "BGP is converged \n Error : {}".format(
+        tc_name, result
+    )
     logger.info("Expected behaviour: {}".format(result))
 
     for addr_type in ADDR_TYPES:
@@ -1154,7 +1180,7 @@ def test_next_hop_with_recursive_lookup_p1(request):
             input_dict,
             protocol="bgp",
             next_hop=next_hop,
-            expected=False
+            expected=False,
         )
         assert result is not True, (
             "Testcase {} : Failed \n "
@@ -1237,7 +1263,9 @@ def test_BGP_path_attributes_default_values_p1(request):
                 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
             ],
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
         input_dict_4 = {
@@ -1256,7 +1284,9 @@ def test_BGP_path_attributes_default_values_p1(request):
             rmap_name="rmap_pf",
             input_dict=input_dict_4,
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step(
         "Configure a route-map to set below attribute value as 500"
@@ -1358,7 +1388,9 @@ def test_BGP_path_attributes_default_values_p1(request):
             rmap_name="rmap_pf",
             input_dict=input_dict_4,
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step("Remove the route-map from R4")
     input_dict_5 = {
@@ -1432,7 +1464,9 @@ def test_BGP_path_attributes_default_values_p1(request):
             input_dict=input_dict_4,
             nexthop=None,
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     write_test_footer(tc_name)
 
@@ -1670,7 +1704,7 @@ def test_BGP_peering_bw_loopback_and_physical_p1(request):
             input_dict_1,
             protocol="static",
             next_hop=topo["routers"]["r1"]["links"]["r3"][addr_type].split("/")[0],
-            expected=False
+            expected=False,
         )
         assert result is not True, "Testcase {} : Failed \n Error : {}".format(
             tc_name, result
@@ -1801,7 +1835,9 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request):
                 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
             ],
         )
-        assert result is True, "Testcase  : Failed \n Error : {}".format(tc_name, result)
+        assert result is True, "Testcase  : Failed \n Error : {}".format(
+            tc_name, result
+        )
 
     step(
         "Configure a route-map to set as-path attribute and"
@@ -2037,7 +2073,7 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request):
                 topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
                 topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
             ],
-            expected=False
+            expected=False,
         )
         assert result is not True, "Testcase {} : Failed \n Error : {}".format(
             tc_name, result
@@ -2084,7 +2120,7 @@ def test_BGP_active_standby_preemption_and_ecmp_p1(request):
             topo["routers"]["r2"]["links"]["r4"][addr_type].split("/")[0],
             topo["routers"]["r3"]["links"]["r4"][addr_type].split("/")[0],
         ],
-        expected=False
+        expected=False,
     )
     assert result is not True, "Testcase {} : Failed \n Error : {}".format(
         tc_name, result
index 4de7184c8e31fa10d78e2c50cd278433f8ba2558..71bd58bf7345602c05f9e9773200cb5bcda85cb7 100644 (file)
@@ -149,22 +149,21 @@ def test_bgp_update_delay():
 
     def _bgp_check_update_delay_in_progress(router):
         output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
-        expected = {"ipv4Unicast": {"updateDelayInProgress":True}}
+        expected = {"ipv4Unicast": {"updateDelayInProgress": True}}
 
         return topotest.json_cmp(output, expected)
 
     def _bgp_check_route_install(router):
         output = json.loads(router.vtysh_cmd("show ip route 172.16.253.254/32 json"))
-        expected = {"172.16.253.254/32": [ {"protocol": "bgp"}]}
+        expected = {"172.16.253.254/32": [{"protocol": "bgp"}]}
 
         return topotest.json_cmp(output, expected)
 
     def _bgp_check_update_delay_and_wait(router):
         output = json.loads(router.vtysh_cmd("show ip bgp sum json"))
         expected = {
-                "ipv4Unicast": {
-                    "updateDelayLimit": 20,
-                    "updateDelayEstablishWait": 10}}
+            "ipv4Unicast": {"updateDelayLimit": 20, "updateDelayEstablishWait": 10}
+        }
 
         return topotest.json_cmp(output, expected)
 
@@ -177,14 +176,11 @@ def test_bgp_update_delay():
     def _bgp_check_vrf_update_delay_and_wait(router):
         output = json.loads(router.vtysh_cmd("show ip bgp vrf vrf1 sum json"))
         expected = {
-                "ipv4Unicast": {
-                    "updateDelayLimit": 20,
-                    "updateDelayEstablishWait": 10}}
-
+            "ipv4Unicast": {"updateDelayLimit": 20, "updateDelayEstablishWait": 10}
+        }
 
         return topotest.json_cmp(output, expected)
 
-
     # Check r2 initial convergence in default table
     test_func = functools.partial(_bgp_converge, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
@@ -198,7 +194,7 @@ def test_bgp_update_delay():
             router bgp 65002
               update-delay 20
         """
-        )
+    )
 
     # Shutdown peering on r1 toward r2 so that delay timers can be exercised
     router1.vtysh_cmd(
@@ -207,7 +203,7 @@ def test_bgp_update_delay():
             router bgp 65001
               neighbor 192.168.255.1 shut
         """
-        )
+    )
 
     # Clear bgp neighbors on r2 and then check for the 'in progress' indicator
     router2.vtysh_cmd("""clear ip bgp *""")
@@ -215,13 +211,17 @@ def test_bgp_update_delay():
     test_func = functools.partial(_bgp_check_update_delay_in_progress, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format(router2)
+    assert result is None, 'Failed to set update-delay max-delay timer "{}"'.format(
+        router2
+    )
 
     # Check that r2 only installs route learned from r4 after the max-delay timer expires
     test_func = functools.partial(_bgp_check_route_install, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to install route after update-delay "{}"'.format(router2)
+    assert result is None, 'Failed to install route after update-delay "{}"'.format(
+        router2
+    )
 
     # Define update-delay with max-delay and estabish-wait and check json output showing set
     router2.vtysh_cmd(
@@ -230,12 +230,14 @@ def test_bgp_update_delay():
             router bgp 65002
               update-delay 20 10
         """
-        )
+    )
 
     test_func = functools.partial(_bgp_check_update_delay_and_wait, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to set max-delay and establish-weight timers in "{}"'.format(router2)
+    assert (
+        result is None
+    ), 'Failed to set max-delay and establish-weight timers in "{}"'.format(router2)
 
     # Define update-delay with max-delay and estabish-wait and check json output showing set
     router2.vtysh_cmd("""clear ip bgp *""")
@@ -243,7 +245,11 @@ def test_bgp_update_delay():
     test_func = functools.partial(_bgp_check_route_install, router3)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2)
+    assert (
+        result is None
+    ), 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(
+        router2
+    )
 
     # Remove update-delay timer on r2 to verify that it goes back to normal behavior
     router2.vtysh_cmd(
@@ -252,7 +258,7 @@ def test_bgp_update_delay():
             router bgp 65002
               no update-delay
         """
-        )
+    )
 
     # Clear neighbors on r2 and check that route install time on r2 does not delay
     router2.vtysh_cmd("""clear ip bgp *""")
@@ -260,7 +266,9 @@ def test_bgp_update_delay():
     test_func = functools.partial(_bgp_check_route_install, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to remove update-delay delay timing "{}"'.format(router2)
+    assert result is None, 'Failed to remove update-delay delay timing "{}"'.format(
+        router2
+    )
 
     # Define global bgp update-delay with max-delay and establish-wait on r2
     router2.vtysh_cmd(
@@ -268,13 +276,15 @@ def test_bgp_update_delay():
           configure terminal
             bgp update-delay 20 10
         """
-        )
+    )
 
     # Check that r2 default instance and vrf1 have the max-delay and establish set
     test_func = functools.partial(_bgp_check_update_delay_and_wait, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to set update-delay in default instance "{}"'.format(router2)
+    assert result is None, 'Failed to set update-delay in default instance "{}"'.format(
+        router2
+    )
 
     test_func = functools.partial(_bgp_check_vrf_update_delay_and_wait, router2)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
@@ -287,7 +297,11 @@ def test_bgp_update_delay():
     test_func = functools.partial(_bgp_check_route_install, router3)
     success, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
 
-    assert result is None, 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(router2)
+    assert (
+        result is None
+    ), 'Failed to installed advertised route after establish-wait timer espired "{}"'.format(
+        router2
+    )
 
 
 if __name__ == "__main__":
index 1947548b3e2da55c3fa09fcbd87473d2305981ac..63db393178c5d1da2b6e661ce6fa995ac3a38ca7 100644 (file)
@@ -40,8 +40,8 @@ import platform
 
 # Save the Current Working Directory to find configuration files.
 CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, '../'))
-sys.path.append(os.path.join(CWD, '../lib/'))
+sys.path.append(os.path.join(CWD, "../"))
+sys.path.append(os.path.join(CWD, "../lib/"))
 
 # Required to instantiate the topology builder class.
 
@@ -52,20 +52,32 @@ from lib.topotest import version_cmp
 from mininet.topo import Topo
 
 from lib.common_config import (
-    start_topology, write_test_header, check_address_types,
-    write_test_footer, reset_config_on_routers,
-    verify_rib, step, create_route_maps,
-    shutdown_bringup_interface, create_static_routes,
-    create_prefix_lists, create_bgp_community_lists,
+    start_topology,
+    write_test_header,
+    check_address_types,
+    write_test_footer,
+    reset_config_on_routers,
+    verify_rib,
+    step,
+    create_route_maps,
+    shutdown_bringup_interface,
+    create_static_routes,
+    create_prefix_lists,
+    create_bgp_community_lists,
     create_interface_in_kernel,
-    check_router_status, verify_cli_json,
-    get_frr_ipv6_linklocal, verify_fib_routes
+    check_router_status,
+    verify_cli_json,
+    get_frr_ipv6_linklocal,
+    verify_fib_routes,
 )
 
 from lib.topolog import logger
 from lib.bgp import (
-    verify_bgp_convergence, create_router_bgp,
-    clear_bgp, verify_bgp_community, verify_bgp_rib
+    verify_bgp_convergence,
+    create_router_bgp,
+    clear_bgp,
+    verify_bgp_community,
+    verify_bgp_rib,
 )
 from lib.topojson import build_topo_from_json, build_config_from_json
 
@@ -99,10 +111,18 @@ NETWORK4_3 = {"ipv4": "50.50.50.5/32", "ipv6": "50:50::5/128"}
 NETWORK4_4 = {"ipv4": "50.50.50.50/32", "ipv6": "50:50::50/128"}
 
 NEXT_HOP_IP = {"ipv4": "Null0", "ipv6": "Null0"}
-LOOPBACK_1 = {"ipv4": "10.0.0.7/24", "ipv6": "fd00:0:0:1::7/64",
-              "ipv4_mask": "255.255.255.0", "ipv6_mask": None}
-LOOPBACK_2 = {"ipv4": "10.0.0.16/24", "ipv6": "fd00:0:0:3::5/64",
-              "ipv4_mask": "255.255.255.0", "ipv6_mask": None}
+LOOPBACK_1 = {
+    "ipv4": "10.0.0.7/24",
+    "ipv6": "fd00:0:0:1::7/64",
+    "ipv4_mask": "255.255.255.0",
+    "ipv6_mask": None,
+}
+LOOPBACK_2 = {
+    "ipv4": "10.0.0.16/24",
+    "ipv6": "fd00:0:0:3::5/64",
+    "ipv4_mask": "255.255.255.0",
+    "ipv6_mask": None,
+}
 PREFERRED_NEXT_HOP = "global"
 
 
@@ -144,10 +164,11 @@ def setup_module(mod):
     start_topology(tgen)
 
     # Run these tests for kernel version 4.19 or above
-    if version_cmp(platform.release(), '4.19') < 0:
-        error_msg = ('BGP vrf dynamic route leak tests will not run '
-            '(have kernel "{}", but it requires >= 4.19)'.\
-            format(platform.release()))
+    if version_cmp(platform.release(), "4.19") < 0:
+        error_msg = (
+            "BGP vrf dynamic route leak tests will not run "
+            '(have kernel "{}", but it requires >= 4.19)'.format(platform.release())
+        )
         pytest.skip(error_msg)
 
     # Creating configuration from JSON
@@ -158,8 +179,9 @@ def setup_module(mod):
     ADDR_TYPES = check_address_types()
 
     BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
-    assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}". \
-        format(BGP_CONVERGENCE)
+    assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format(
+        BGP_CONVERGENCE
+    )
 
     logger.info("Running setup_module() done")
 
@@ -174,16 +196,19 @@ def teardown_module():
     # Stop toplogy and Remove tmp files
     tgen.stop_topology()
 
-    logger.info("Testsuite end time: {}".
-                format(time.asctime(time.localtime(time.time()))))
+    logger.info(
+        "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+    )
     logger.info("=" * 40)
 
+
 #####################################################
 #
 #   Local APIs
 #
 #####################################################
 
+
 def disable_route_map_to_prefer_global_next_hop(tgen, topo):
     """
     This API is to remove prefer global route-map applied on neighbors
@@ -202,8 +227,7 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
     logger.info("Remove prefer-global rmap applied on neighbors")
     input_dict = {
         "r1": {
-            "bgp":
-            [
+            "bgp": [
                 {
                     "local_as": "100",
                     "vrf": "ISR",
@@ -214,18 +238,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r2": {
                                         "dest_link": {
                                             "r1-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
+                    },
                 },
                 {
                     "local_as": "100",
@@ -236,18 +262,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r3": {
                                         "dest_link": {
                                             "r1-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
+                    },
                 },
                 {
                     "local_as": "100",
@@ -258,24 +286,25 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r4": {
                                         "dest_link": {
                                             "r1-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
-                }
+                    },
+                },
             ]
         },
         "r2": {
-            "bgp":
-            [
+            "bgp": [
                 {
                     "local_as": "100",
                     "vrf": "ISR",
@@ -286,18 +315,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r1": {
                                         "dest_link": {
                                             "r2-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
+                    },
                 },
                 {
                     "local_as": "100",
@@ -308,18 +339,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r3": {
                                         "dest_link": {
                                             "r2-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
+                    },
                 },
                 {
                     "local_as": "100",
@@ -330,24 +363,25 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r4": {
                                         "dest_link": {
                                             "r2-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
-                }
+                    },
+                },
             ]
         },
         "r3": {
-            "bgp":
-            [
+            "bgp": [
                 {
                     "local_as": "300",
                     "address_family": {
@@ -357,18 +391,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r1": {
                                         "dest_link": {
                                             "r3-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
+                    },
                 },
                 {
                     "local_as": "300",
@@ -379,24 +415,25 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r2": {
                                         "dest_link": {
                                             "r3-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
-                }
+                    },
+                },
             ]
         },
         "r4": {
-            "bgp":
-            [
+            "bgp": [
                 {
                     "local_as": "400",
                     "address_family": {
@@ -406,18 +443,20 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r1": {
                                         "dest_link": {
                                             "r4-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
+                    },
                 },
                 {
                     "local_as": "400",
@@ -428,26 +467,27 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
                                     "r2": {
                                         "dest_link": {
                                             "r4-link1": {
-                                                "route_maps": [{
-                                                    "name": "rmap_global",
-                                                    "direction": "in",
-                                                    "delete": True
-                                                }]
+                                                "route_maps": [
+                                                    {
+                                                        "name": "rmap_global",
+                                                        "direction": "in",
+                                                        "delete": True,
+                                                    }
+                                                ]
                                             }
                                         }
                                     }
                                 }
                             }
                         }
-                    }
-                }
+                    },
+                },
             ]
-        }
+        },
     }
 
     result = create_router_bgp(tgen, topo, input_dict)
-    assert result is True, "Testcase {} :Failed \n Error: {}". \
-        format(tc_name, result)
+    assert result is True, "Testcase {} :Failed \n Error: {}".format(tc_name, result)
 
     return True
 
@@ -458,6 +498,7 @@ def disable_route_map_to_prefer_global_next_hop(tgen, topo):
 #
 #####################################################
 
+
 def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
     """
     TC5_FUNC_5:
@@ -475,10 +516,11 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
 
     for addr_type in ADDR_TYPES:
 
-        step("Redistribute configured static routes into BGP process"
-                " on R1 and R3/R4")
+        step(
+            "Redistribute configured static routes into BGP process" " on R1 and R3/R4"
+        )
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1", "r3", "r4"]
         VRFS = ["default", "default", "default"]
         AS_NUM = [100, 300, 400]
@@ -493,47 +535,48 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
                     "vrf": vrf,
                     "address_family": {
                         addr_type: {
-                            "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static"
-                                }]
-                            }
+                            "unicast": {"redistribute": [{"redist_type": "static"}]}
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that R1 receives BGP routes from R3 and R4 in "
-             "vrf default.")
+        step("Verify that R1 receives BGP routes from R3 and R4 in " "vrf default.")
 
         input_routes_r3 = {
             "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_1[addr_type], \
-                        NETWORK3_2[addr_type], \
-                        NETWORK3_3[addr_type], \
-                        NETWORK3_4[addr_type]
-                    ]
-                }]
+                "static_routes": [
+                    {
+                        "network": [
+                            NETWORK3_1[addr_type],
+                            NETWORK3_2[addr_type],
+                            NETWORK3_3[addr_type],
+                            NETWORK3_4[addr_type],
+                        ]
+                    }
+                ]
             }
         }
 
         input_routes_r4 = {
             "r4": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK4_1[addr_type], \
-                        NETWORK4_2[addr_type], \
-                        NETWORK4_3[addr_type], \
-                        NETWORK4_4[addr_type]
-                    ]
-                }]
+                "static_routes": [
+                    {
+                        "network": [
+                            NETWORK4_1[addr_type],
+                            NETWORK4_2[addr_type],
+                            NETWORK4_3[addr_type],
+                            NETWORK4_4[addr_type],
+                        ]
+                    }
+                ]
             }
         }
 
@@ -542,20 +585,20 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
 
         for dut, routes in zip(DUT, INPUT_DICT):
             result = verify_bgp_rib(tgen, addr_type, dut, routes)
-            assert result is True, \
-                "Testcase {} : Failed \n Error {}". \
-                    format(tc_name, result)
+            assert result is True, "Testcase {} : Failed \n Error {}".format(
+                tc_name, result
+            )
 
             result = verify_fib_routes(tgen, addr_type, dut, routes)
-            assert result is True, \
-                "Testcase {} : Failed \n Error {}". \
-                    format(tc_name, result)
+            assert result is True, "Testcase {} : Failed \n Error {}".format(
+                tc_name, result
+            )
 
     for addr_type in ADDR_TYPES:
 
         step("Import from default vrf into vrf ISR on R1")
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1", "r2"]
         VRFS = ["ISR", "ISR"]
         AS_NUM = [100, 100]
@@ -569,50 +612,52 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "default"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "default"}}}
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that default vrf's imported routes are installed "
-             "in RIB/FIB of vrf ISR on R1:")
+        step(
+            "Verify that default vrf's imported routes are installed "
+            "in RIB/FIB of vrf ISR on R1:"
+        )
 
         input_routes_r3 = {
             "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_1[addr_type], \
-                        NETWORK3_2[addr_type], \
-                        NETWORK3_3[addr_type], \
-                        NETWORK3_4[addr_type]
-                    ],
-                    "vrf": "ISR"
-                }]
+                "static_routes": [
+                    {
+                        "network": [
+                            NETWORK3_1[addr_type],
+                            NETWORK3_2[addr_type],
+                            NETWORK3_3[addr_type],
+                            NETWORK3_4[addr_type],
+                        ],
+                        "vrf": "ISR",
+                    }
+                ]
             }
         }
 
         input_routes_r4 = {
             "r4": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK4_1[addr_type], \
-                        NETWORK4_2[addr_type], \
-                        NETWORK4_3[addr_type], \
-                        NETWORK4_4[addr_type]
-                    ],
-                    "vrf": "ISR"
-                }]
+                "static_routes": [
+                    {
+                        "network": [
+                            NETWORK4_1[addr_type],
+                            NETWORK4_2[addr_type],
+                            NETWORK4_3[addr_type],
+                            NETWORK4_4[addr_type],
+                        ],
+                        "vrf": "ISR",
+                    }
+                ]
             }
         }
 
@@ -620,87 +665,101 @@ def test_dynamic_imported_routes_advertised_to_iBGP_peer_p0(request):
 
         for routes in INPUT_DICT_VRF:
             result = verify_bgp_rib(tgen, addr_type, "r1", routes)
-            assert result is True, \
-                "Testcase {} : Failed \n Error {}". \
-                    format(tc_name, result)
+            assert result is True, "Testcase {} : Failed \n Error {}".format(
+                tc_name, result
+            )
 
-            result =  verify_fib_routes(tgen, addr_type, "r1", routes)
-            assert result is True, \
-                "Testcase {} : Failed \n Error {}". \
-                    format(tc_name, result)
+            result = verify_fib_routes(tgen, addr_type, "r1", routes)
+            assert result is True, "Testcase {} : Failed \n Error {}".format(
+                tc_name, result
+            )
 
     intf_r2_r1 = topo["routers"]["r2"]["links"]["r1-link1"]
     for addr_type in ADDR_TYPES:
 
-        step("Create a loopback10 interface on R1 with below IP address and "
-            "associate with vrf ISR:")
+        step(
+            "Create a loopback10 interface on R1 with below IP address and "
+            "associate with vrf ISR:"
+        )
 
-        create_interface_in_kernel(tgen, "r1", "loopback2",
-                                   LOOPBACK_2[addr_type],
-                                   "ISR",
-                                   LOOPBACK_2["{}_mask".\
-                                   format(addr_type)])
+        create_interface_in_kernel(
+            tgen,
+            "r1",
+            "loopback2",
+            LOOPBACK_2[addr_type],
+            "ISR",
+            LOOPBACK_2["{}_mask".format(addr_type)],
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("On router R1 Change the next-hop of static routes in vrf "
-                "ISR to LOOPBACK_1")
+        step(
+            "On router R1 Change the next-hop of static routes in vrf "
+            "ISR to LOOPBACK_1"
+        )
 
-        input_routes_r1= {
+        input_routes_r1 = {
             "r1": {
-                "static_routes":[
+                "static_routes": [
                     {
                         "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]],
-                        "next_hop":"Null0",
-                        "delete": True
+                        "next_hop": "Null0",
+                        "delete": True,
                     }
                 ]
             }
         }
 
         result = create_static_routes(tgen, input_routes_r1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        input_routes_r1= {
+        input_routes_r1 = {
             "r1": {
-                "static_routes":[
+                "static_routes": [
                     {
                         "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]],
-                        "next_hop": (intf_r2_r1[addr_type]).split("/")[0]
+                        "next_hop": (intf_r2_r1[addr_type]).split("/")[0],
                     }
                 ]
             }
         }
 
         result = create_static_routes(tgen, input_routes_r1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that, though R1 originating BGP routes with next-hop"
+        step(
+            "Verify that, though R1 originating BGP routes with next-hop"
             " 24.1.1.2/24::1:2, which is local to R2(but in default vrf)"
-            ", R2 must receives and install all routes from R1 in vrf ISR.")
-        step("Verify on R2, that it now rejects 10.10.10.x routes originated "
-            "from R1. As next-hop IP is local to R2's vrf ISR.")
+            ", R2 must receives and install all routes from R1 in vrf ISR."
+        )
+        step(
+            "Verify on R2, that it now rejects 10.10.10.x routes originated "
+            "from R1. As next-hop IP is local to R2's vrf ISR."
+        )
 
-        input_routes_r1= {
+        input_routes_r1 = {
             "r1": {
-                "static_routes":[
+                "static_routes": [
                     {
                         "network": [NETWORK1_3[addr_type], NETWORK1_4[addr_type]],
-                        "vrf": "ISR"
+                        "vrf": "ISR",
                     }
                 ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Routes are still present \n Error {}". \
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Routes are still present \n Error {}".format(
+            tc_name, result
+        )
 
     write_test_footer(tc_name)
 
@@ -722,71 +781,77 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
 
     for addr_type in ADDR_TYPES:
 
-        step("Configure route-map to set community attribute for a specific"
-            "prefix on R1 in vrf ISR")
+        step(
+            "Configure route-map to set community attribute for a specific"
+            "prefix on R1 in vrf ISR"
+        )
 
         input_dict_pf = {
             "r1": {
                 "prefix_lists": {
                     addr_type: {
-                        "pflist_ABC_{}".format(addr_type): [{
-                            "seqid": 10,
-                            "network": NETWORK1_1[addr_type],
-                            "action": "permit"
-                        }]
+                        "pflist_ABC_{}".format(addr_type): [
+                            {
+                                "seqid": 10,
+                                "network": NETWORK1_1[addr_type],
+                                "action": "permit",
+                            }
+                        ]
                     }
                 }
             }
         }
         result = create_prefix_lists(tgen, input_dict_pf)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     input_dict_cl = {
         "r1": {
             "bgp_community_lists": [
-            {
-                "community_type": "expanded",
-                "action": "permit",
-                "name": "COMM",
-                "value": "100:100"
+                {
+                    "community_type": "expanded",
+                    "action": "permit",
+                    "name": "COMM",
+                    "value": "100:100",
                 }
             ]
         }
     }
     result = create_bgp_community_lists(tgen, input_dict_cl)
-    assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-        tc_name, result)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
 
     for addr_type in ADDR_TYPES:
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_XYZ_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pflist_ABC_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "community": {"num": "100:100"}
+                    "rmap_XYZ_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pflist_ABC_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"community": {"num": "100:100"}},
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Apply this route-map on R1 to vrf ISR while redistributing the"
-            " prefixes into BGP")
+        step(
+            "Apply this route-map on R1 to vrf ISR while redistributing the"
+            " prefixes into BGP"
+        )
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1"]
         VRFS = ["ISR"]
         AS_NUM = [100]
@@ -802,53 +867,58 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                     "address_family": {
                         addr_type: {
                             "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static",
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
                                         "attribute": {
-                                            "route-map" : "rmap_XYZ_{}".\
-                                                format(addr_type)
-                                        }
+                                            "route-map": "rmap_XYZ_{}".format(addr_type)
+                                        },
                                     }
                                 ]
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Configure another route-map for filtering the prefixes based on"
-            " community attribute while importing into default vrf")
+        step(
+            "Configure another route-map for filtering the prefixes based on"
+            " community attribute while importing into default vrf"
+        )
 
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            "community_list": {"id": "COMM"}
-                        },
-                        "set": {
-                            "community": {"num": "none"}
+                    "rmap_IMP_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {"community_list": {"id": "COMM"}},
+                            "set": {"community": {"num": "none"}},
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Apply the route-map while Importing vrf ISR's prefixes into "
-            "default vrf on router R1:")
+        step(
+            "Apply the route-map while Importing vrf ISR's prefixes into "
+            "default vrf on router R1:"
+        )
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -862,15 +932,10 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -884,50 +949,57 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify on R1 that only prefixes with community value 100:100"
+        step(
+            "Verify on R1 that only prefixes with community value 100:100"
             "in vrf ISR are imported to vrf default. While importing, the"
-            " community value has been stripped off:")
+            " community value has been stripped off:"
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
-
-        input_dict_comm = {
-            "community": "100:100"
-        }
-
-        result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]],
-                                      input_dict_comm, expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error: Commnunity is not stipped off, {}".format(
-            tc_name, result))
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
+
+        input_dict_comm = {"community": "100:100"}
+
+        result = verify_bgp_community(
+            tgen,
+            addr_type,
+            dut,
+            [NETWORK1_1[addr_type]],
+            input_dict_comm,
+            expected=False,
+        )
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error: Commnunity is not stipped off, {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         step("Remove/re-add route-map XYZ from redistribution.")
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1"]
         VRFS = ["ISR"]
         AS_NUM = [100]
@@ -943,49 +1015,52 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                     "address_family": {
                         addr_type: {
                             "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static",
-                                    "attribute": {
-                                        "route-map" : "rmap_XYZ_{}".\
-                                            format(addr_type)
-                                    },
-                                    "delete": True
-                                }]
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
+                                        "attribute": {
+                                            "route-map": "rmap_XYZ_{}".format(addr_type)
+                                        },
+                                        "delete": True,
+                                    }
+                                ]
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that all the routes disappear from vrf default when "
+        step(
+            "Verify that all the routes disappear from vrf default when "
             "route-map is removed from redistribution, and appear again "
-            "when route-map is re-added to redistribution in vrf ISR.")
+            "when route-map is re-added to redistribution in vrf ISR."
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error : Routes are still present \n {}".\
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1"]
         VRFS = ["ISR"]
         AS_NUM = [100]
@@ -1001,45 +1076,45 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                     "address_family": {
                         addr_type: {
                             "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static",
-                                    "attribute": {
-                                        "route-map" : "rmap_XYZ_{}".\
-                                            format(addr_type)
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
+                                        "attribute": {
+                                            "route-map": "rmap_XYZ_{}".format(addr_type)
+                                        },
                                     }
-                                }]
+                                ]
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         step("Remove/re-add route-map IMP form import statement.")
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -1053,15 +1128,10 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -1072,43 +1142,44 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                             "unicast": {
                                 "import": {
                                     "vrf": "route-map rmap_IMP_{}".format(addr_type),
-                                    "delete": True
+                                    "delete": True,
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that when route-map IMP is removed all the prefixes of"
+        step(
+            "Verify that when route-map IMP is removed all the prefixes of"
             " vrf ISR are imported to vrf default. However when route-map "
             "IMP is re-added only 11.11.11.1 and 11:11::1 (with community "
-            "value) are imported.")
+            "value) are imported."
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -1122,15 +1193,10 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -1144,30 +1210,29 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
@@ -1177,165 +1242,178 @@ def test_dynamic_imported_matching_prefix_based_on_community_list_p0(request):
             "r1": {
                 "prefix_lists": {
                     addr_type: {
-                        "pflist_ABC_{}".format(addr_type): [{
-                            "seqid": 10,
-                            "network": NETWORK1_1[addr_type],
-                            "action": "permit",
-                            "delete": True
-                        }]
+                        "pflist_ABC_{}".format(addr_type): [
+                            {
+                                "seqid": 10,
+                                "network": NETWORK1_1[addr_type],
+                                "action": "permit",
+                                "delete": True,
+                            }
+                        ]
                     }
                 }
             }
         }
         result = create_prefix_lists(tgen, input_dict_pf)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error : Routes are still present \n {}".\
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format(
+            tc_name, result
+        )
 
-        input_dict_pf["r1"]["prefix_lists"][addr_type]["pflist_ABC_{}".\
-            format(addr_type)][0]["delete"]=False
+        input_dict_pf["r1"]["prefix_lists"][addr_type][
+            "pflist_ABC_{}".format(addr_type)
+        ][0]["delete"] = False
 
         result = create_prefix_lists(tgen, input_dict_pf)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
         step("Delete/Re-add community-list COMM.")
 
         input_dict_cl = {
             "r1": {
                 "bgp_community_lists": [
-                {
-                    "community_type": "expanded",
-                    "action": "permit",
-                    "name": "COMM",
-                    "value": "100:100",
-                    "delete": True
+                    {
+                        "community_type": "expanded",
+                        "action": "permit",
+                        "name": "COMM",
+                        "value": "100:100",
+                        "delete": True,
                     }
                 ]
             }
         }
         result = create_bgp_community_lists(tgen, input_dict_cl)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error : Routes are still present \n {}".\
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format(
+            tc_name, result
+        )
 
-        input_dict_cl["r1"]["bgp_community_lists"][0]["delete"]=False
+        input_dict_cl["r1"]["bgp_community_lists"][0]["delete"] = False
 
         result = create_bgp_community_lists(tgen, input_dict_cl)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
         step("Delete/Re-add route-map XYZ.")
 
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_XYZ_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pflist_ABC_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "community": {"num": "100:100"}
-                        },
-                        "delete": True
-                    }]
+                    "rmap_XYZ_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pflist_ABC_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"community": {"num": "100:100"}},
+                            "delete": True,
+                        }
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error : Routes are still present \n {}".\
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format(
+            tc_name, result
+        )
 
-        input_dict_rm["r1"]["route_maps"]["rmap_XYZ_{}".format(addr_type)][0]["delete"]=False
+        input_dict_rm["r1"]["route_maps"]["rmap_XYZ_{}".format(addr_type)][0][
+            "delete"
+        ] = False
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
         step("Delete/Re-add route-map IMP.")
 
         input_dict_rm2 = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            "community_list": {"id": "COMM"}
-                        },
-                        "set": {
-                            "community": {"num": "none"}
-                        },
-                        "delete": True
-                    }]
+                    "rmap_IMP_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {"community_list": {"id": "COMM"}},
+                            "set": {"community": {"num": "none"}},
+                            "delete": True,
+                        }
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm2)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error : Routes are still present \n {}".\
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format(
+            tc_name, result
+        )
 
-        input_dict_rm2["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0]["delete"]=False
+        input_dict_rm2["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0][
+            "delete"
+        ] = False
 
         result = create_route_maps(tgen, input_dict_rm2)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     write_test_footer(tc_name)
 
@@ -1356,71 +1434,77 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
 
     for addr_type in ADDR_TYPES:
 
-        step("Configure route-map to set community attribute for a specific"
-            "prefix on R1 in vrf ISR")
+        step(
+            "Configure route-map to set community attribute for a specific"
+            "prefix on R1 in vrf ISR"
+        )
 
         input_dict_pf = {
             "r1": {
                 "prefix_lists": {
                     addr_type: {
-                        "pflist_ABC_{}".format(addr_type): [{
-                            "seqid": 10,
-                            "network": NETWORK1_1[addr_type],
-                            "action": "permit"
-                        }]
+                        "pflist_ABC_{}".format(addr_type): [
+                            {
+                                "seqid": 10,
+                                "network": NETWORK1_1[addr_type],
+                                "action": "permit",
+                            }
+                        ]
                     }
                 }
             }
         }
         result = create_prefix_lists(tgen, input_dict_pf)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     input_dict_cl = {
         "r1": {
             "bgp_community_lists": [
-            {
-                "community_type": "expanded",
-                "action": "permit",
-                "name": "COMM",
-                "value": "100:100"
+                {
+                    "community_type": "expanded",
+                    "action": "permit",
+                    "name": "COMM",
+                    "value": "100:100",
                 }
             ]
         }
     }
     result = create_bgp_community_lists(tgen, input_dict_cl)
-    assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-        tc_name, result)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
 
     for addr_type in ADDR_TYPES:
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_XYZ_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pflist_ABC_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "community": {"num": "100:100"}
+                    "rmap_XYZ_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pflist_ABC_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"community": {"num": "100:100"}},
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Apply this route-map on R1 to vrf ISR while redistributing the"
-            " prefixes into BGP")
+        step(
+            "Apply this route-map on R1 to vrf ISR while redistributing the"
+            " prefixes into BGP"
+        )
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1"]
         VRFS = ["ISR"]
         AS_NUM = [100]
@@ -1436,53 +1520,58 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                     "address_family": {
                         addr_type: {
                             "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static",
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
                                         "attribute": {
-                                            "route-map" : "rmap_XYZ_{}".\
-                                                format(addr_type)
-                                        }
+                                            "route-map": "rmap_XYZ_{}".format(addr_type)
+                                        },
                                     }
                                 ]
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Configure another route-map for filtering the prefixes based on"
-            " community attribute while importing into default vrf")
+        step(
+            "Configure another route-map for filtering the prefixes based on"
+            " community attribute while importing into default vrf"
+        )
 
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            "community_list": {"id": "COMM"}
-                        },
-                        "set": {
-                            "community": {"num": "500:500"}
+                    "rmap_IMP_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {"community_list": {"id": "COMM"}},
+                            "set": {"community": {"num": "500:500"}},
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Apply the route-map while Importing vrf ISR's prefixes into "
-            "default vrf on router R1:")
+        step(
+            "Apply the route-map while Importing vrf ISR's prefixes into "
+            "default vrf on router R1:"
+        )
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -1496,15 +1585,10 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -1518,42 +1602,45 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify on R1 that only prefixes with community value 100:100"
+        step(
+            "Verify on R1 that only prefixes with community value 100:100"
             "in vrf ISR are imported to vrf default. While importing, the"
-            " community value has been stripped off:")
+            " community value has been stripped off:"
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         step("Applying route-map first followed by import VRF command.")
-        step("Apply the route-map while Importing vrf ISR's prefixes into "
-            "default vrf on router R1:")
+        step(
+            "Apply the route-map while Importing vrf ISR's prefixes into "
+            "default vrf on router R1:"
+        )
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -1568,15 +1655,11 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                     "vrf": vrf,
                     "address_family": {
                         addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR",
-                                    "delete": True
-                                }
-                            }
+                            "unicast": {"import": {"vrf": "ISR", "delete": True}}
                         }
-                    }
-                })
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -1590,39 +1673,41 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that until 'import VRF command' is not configured, "
+        step(
+            "Verify that until 'import VRF command' is not configured, "
             "routes are not imported. After configuring 'import VRF command'"
-            " repeat step-4 for verification")
+            " repeat step-4 for verification"
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Error : Routes are still present \n {}".\
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Error : Routes are still present \n {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -1636,15 +1721,10 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -1658,37 +1738,35 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Delete/re-add import vrf ISR command multiple times in default"
-            "vrf.")
+        step("Delete/re-add import vrf ISR command multiple times in default" "vrf.")
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -1703,112 +1781,111 @@ def test_routemap_operatons_with_dynamic_import_p0(request):
                     "vrf": vrf,
                     "address_family": {
                         addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR",
-                                    "delete": True
-                                }
-                            }
+                            "unicast": {"import": {"vrf": "ISR", "delete": True}}
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        step("Verify that when import vrf ISR command is deleted, "
-             "all routes of vrf ISR disappear from default vrf and "
-             "when it's re-configured, repeat step-4 for verification.")
+        step(
+            "Verify that when import vrf ISR command is deleted, "
+            "all routes of vrf ISR disappear from default vrf and "
+            "when it's re-configured, repeat step-4 for verification."
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Routes are still present, Error {}". \
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Routes are still present, Error {}".format(
+            tc_name, result
+        )
 
         input_dict_isr["r1"]["bgp"][0]["address_family"][addr_type]["unicast"][
-            "import"]["delete"]=False
+            "import"
+        ]["delete"] = False
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, (
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result))
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Delete and re-configure route-map IMP from global config when "
-            "import and route-maps are applied in a ISR vrf.")
+        step(
+            "Delete and re-configure route-map IMP from global config when "
+            "import and route-maps are applied in a ISR vrf."
+        )
 
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            "community_list": {"id": "COMM"}
-                        },
-                        "set": {
-                            "community": {"num": "500:500"}
-                        },
-                        "delete": True
-                    }]
+                    "rmap_IMP_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {"community_list": {"id": "COMM"}},
+                            "set": {"community": {"num": "500:500"}},
+                            "delete": True,
+                        }
+                    ]
                 }
             }
         }
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                                expected=False)
-        assert result is not True, (
-            "Testcase {} : Failed \n Routes are still present, Error {}". \
-                format(tc_name, result))
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
+        assert (
+            result is not True
+        ), "Testcase {} : Failed \n Routes are still present, Error {}".format(
+            tc_name, result
+        )
 
-        input_dict_rm["r1"]["route_maps"]["rmap_IMP_{}".\
-            format(addr_type)][0]["delete"]=False
+        input_dict_rm["r1"]["route_maps"]["rmap_IMP_{}".format(addr_type)][0][
+            "delete"
+        ] = False
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        input_dict_comm = {
-            "community": "500:500"
-        }
+        input_dict_comm = {"community": "500:500"}
 
-        result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]],
-                                      input_dict_comm)
-        assert result is True, (
-            "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result))
+        result = verify_bgp_community(
+            tgen, addr_type, dut, [NETWORK1_1[addr_type]], input_dict_comm
+        )
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     write_test_footer(tc_name)
 
@@ -1828,21 +1905,21 @@ def test_verify_cli_json_p1(request):
         check_router_status(tgen)
 
     input_dict = {
-        "r1":{
-            "cli": ["show bgp vrf default ipv4 summary",
-                    "show bgp vrf all ipv6 summary",
-                    "show bgp neighbors"
+        "r1": {
+            "cli": [
+                "show bgp vrf default ipv4 summary",
+                "show bgp vrf all ipv6 summary",
+                "show bgp neighbors",
             ]
         }
     }
 
     result = verify_cli_json(tgen, input_dict)
-    assert result is True, "Testcase {} : Failed \n Error: {}".format(
-        tc_name, result)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
 
     write_test_footer(tc_name)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index 6c106060b8feb2021a0d8548f18a769c38d46218..9106c163cd27ae1dfd7fbe297c6da237d0610ea5 100644 (file)
@@ -38,8 +38,8 @@ import platform
 
 # Save the Current Working Directory to find configuration files.
 CWD = os.path.dirname(os.path.realpath(__file__))
-sys.path.append(os.path.join(CWD, '../'))
-sys.path.append(os.path.join(CWD, '../lib/'))
+sys.path.append(os.path.join(CWD, "../"))
+sys.path.append(os.path.join(CWD, "../lib/"))
 
 # Required to instantiate the topology builder class.
 
@@ -50,22 +50,31 @@ from lib.topotest import version_cmp
 from mininet.topo import Topo
 
 from lib.common_config import (
-    start_topology, write_test_header, check_address_types,
+    start_topology,
+    write_test_header,
+    check_address_types,
     write_test_footer,
-    verify_rib, step, create_route_maps,
-    create_static_routes, stop_router, start_router,
+    verify_rib,
+    step,
+    create_route_maps,
+    create_static_routes,
+    stop_router,
+    start_router,
     create_prefix_lists,
     create_bgp_community_lists,
     check_router_status,
     get_frr_ipv6_linklocal,
-    shutdown_bringup_interface
+    shutdown_bringup_interface,
 )
 
 from lib.topolog import logger
 from lib.bgp import (
-    verify_bgp_convergence, create_router_bgp,
-    verify_bgp_community, verify_bgp_attributes,
-    verify_best_path_as_per_bgp_attribute, verify_bgp_rib
+    verify_bgp_convergence,
+    create_router_bgp,
+    verify_bgp_community,
+    verify_bgp_attributes,
+    verify_best_path_as_per_bgp_attribute,
+    verify_bgp_rib,
 )
 from lib.topojson import build_topo_from_json, build_config_from_json
 
@@ -123,10 +132,11 @@ def setup_module(mod):
     start_topology(tgen)
 
     # Run these tests for kernel version 4.19 or above
-    if version_cmp(platform.release(), '4.19') < 0:
-        error_msg = ('BGP vrf dynamic route leak tests will not run '
-            '(have kernel "{}", but it requires >= 4.19)'.\
-            format(platform.release()))
+    if version_cmp(platform.release(), "4.19") < 0:
+        error_msg = (
+            "BGP vrf dynamic route leak tests will not run "
+            '(have kernel "{}", but it requires >= 4.19)'.format(platform.release())
+        )
         pytest.skip(error_msg)
 
     # Creating configuration from JSON
@@ -137,8 +147,9 @@ def setup_module(mod):
     ADDR_TYPES = check_address_types()
 
     BGP_CONVERGENCE = verify_bgp_convergence(tgen, topo)
-    assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}". \
-        format(BGP_CONVERGENCE)
+    assert BGP_CONVERGENCE is True, "setup_module : Failed \n Error: {}".format(
+        BGP_CONVERGENCE
+    )
 
     logger.info("Running setup_module() done")
 
@@ -153,8 +164,9 @@ def teardown_module():
     # Stop toplogy and Remove tmp files
     tgen.stop_topology()
 
-    logger.info("Testsuite end time: {}".
-                format(time.asctime(time.localtime(time.time()))))
+    logger.info(
+        "Testsuite end time: {}".format(time.asctime(time.localtime(time.time())))
+    )
     logger.info("=" * 40)
 
 
@@ -164,6 +176,7 @@ def teardown_module():
 #
 #####################################################
 
+
 def test_bgp_best_path_with_dynamic_import_p0(request):
     """
     TC6_FUNC_6:
@@ -181,10 +194,11 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
 
     for addr_type in ADDR_TYPES:
 
-        step("Redistribute configured static routes into BGP process"
-             " on R1/R2 and R3")
+        step(
+            "Redistribute configured static routes into BGP process" " on R1/R2 and R3"
+        )
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1", "r2", "r3", "r4"]
         VRFS = ["ISR", "ISR", "default", "default"]
         AS_NUM = [100, 100, 300, 400]
@@ -199,24 +213,22 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
                     "vrf": vrf,
                     "address_family": {
                         addr_type: {
-                            "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static"
-                                }]
-                            }
+                            "unicast": {"redistribute": [{"redist_type": "static"}]}
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
         step("Import from default vrf into vrf ISR on R1 and R2 as below")
 
-        input_dict_vrf={}
+        input_dict_vrf = {}
         DUT = ["r1", "r2"]
         VRFS = ["ISR", "ISR"]
         AS_NUM = [100, 100]
@@ -230,21 +242,17 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "default"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "default"}}}
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_vrf)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        input_dict_default={}
+        input_dict_default = {}
         DUT = ["r1", "r2"]
         VRFS = ["default", "default"]
         AS_NUM = [100, 100]
@@ -258,36 +266,28 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_default)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-    step("Verify ECMP/Next-hop/Imported routes Vs Locally originated "
-         "routes/eBGP routes vs iBGP routes --already covered in almost"
-         " all tests")
+    step(
+        "Verify ECMP/Next-hop/Imported routes Vs Locally originated "
+        "routes/eBGP routes vs iBGP routes --already covered in almost"
+        " all tests"
+    )
 
     for addr_type in ADDR_TYPES:
 
         step("Verify Pre-emption")
 
         input_routes_r3 = {
-            "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_3[addr_type]
-                    ]
-                }]
-            }
+            "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]}
         }
 
         intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
@@ -297,30 +297,27 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
             nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
             nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
         else:
-            nh_r3_r1 = topo["routers"]["r3"]["links"]\
-                ["r1-link1"][addr_type].split("/")[0]
-            nh_r4_r1 = topo["routers"]["r4"]["links"]\
-                ["r1-link1"][addr_type].split("/")[0]
+            nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[
+                0
+            ]
+            nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[
+                0
+            ]
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3,
-                                next_hop=[nh_r4_r1])
-        assert result is True, (
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result))
+        result = verify_bgp_rib(
+            tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r4_r1]
+        )
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     step("Shutdown interface connected to r1 from r4:")
-    shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, False)
+    shutdown_bringup_interface(tgen, "r4", intf_r4_r1, False)
 
     for addr_type in ADDR_TYPES:
 
         input_routes_r3 = {
-            "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_3[addr_type]
-                    ]
-                }]
-            }
+            "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]}
         }
 
         intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
@@ -330,31 +327,28 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
             nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
             nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
         else:
-            nh_r3_r1 = topo["routers"]["r3"]["links"]\
-                ["r1-link1"][addr_type].split("/")[0]
-            nh_r4_r1 = topo["routers"]["r4"]["links"]\
-                ["r1-link1"][addr_type].split("/")[0]
+            nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[
+                0
+            ]
+            nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[
+                0
+            ]
 
         step("Verify next-hop is changed")
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3,
-                                next_hop=[nh_r3_r1])
-        assert result is True, (
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result))
+        result = verify_bgp_rib(
+            tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1]
+        )
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     step("Bringup interface connected to r1 from r4:")
-    shutdown_bringup_interface(tgen, 'r4', intf_r4_r1, True)
+    shutdown_bringup_interface(tgen, "r4", intf_r4_r1, True)
 
     for addr_type in ADDR_TYPES:
 
         input_routes_r3 = {
-            "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_3[addr_type]
-                    ]
-                }]
-            }
+            "r3": {"static_routes": [{"network": [NETWORK3_3[addr_type]]}]}
         }
 
         intf_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"]["interface"]
@@ -364,17 +358,20 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
             nh_r3_r1 = get_frr_ipv6_linklocal(tgen, "r3", intf=intf_r3_r1)
             nh_r4_r1 = get_frr_ipv6_linklocal(tgen, "r4", intf=intf_r4_r1)
         else:
-            nh_r3_r1 = topo["routers"]["r3"]["links"]\
-                ["r1-link1"][addr_type].split("/")[0]
-            nh_r4_r1 = topo["routers"]["r4"]["links"]\
-                ["r1-link1"][addr_type].split("/")[0]
+            nh_r3_r1 = topo["routers"]["r3"]["links"]["r1-link1"][addr_type].split("/")[
+                0
+            ]
+            nh_r4_r1 = topo["routers"]["r4"]["links"]["r1-link1"][addr_type].split("/")[
+                0
+            ]
 
         step("Verify next-hop is not chnaged aftr shutdown:")
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r3,
-                                next_hop=[nh_r3_r1])
-        assert result is True, (
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result))
+        result = verify_bgp_rib(
+            tgen, addr_type, "r1", input_routes_r3, next_hop=[nh_r3_r1]
+        )
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     step("Active-Standby scenario(as-path prepend and Local pref)")
 
@@ -386,18 +383,21 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
             "r1": {
                 "prefix_lists": {
                     addr_type: {
-                        "pf_ls_{}".format(addr_type): [{
-                            "seqid": 10,
-                            "network": NETWORK3_4[addr_type],
-                            "action": "permit"
-                        }]
+                        "pf_ls_{}".format(addr_type): [
+                            {
+                                "seqid": 10,
+                                "network": NETWORK3_4[addr_type],
+                                "action": "permit",
+                            }
+                        ]
                     }
                 }
             }
         }
         result = create_prefix_lists(tgen, input_dict_pf)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
@@ -406,57 +406,56 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_PATH1_{}".format(addr_type): [{
-                        "action": "permit",
-                        "seq_id": 10,
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pf_ls_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "locPrf": 500
+                    "rmap_PATH1_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "seq_id": 10,
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pf_ls_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"locPrf": 500},
                         }
-                    }]
+                    ]
                 }
             }
         }
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
         step("Create route-map to match prefix-list and set localpref 600")
 
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_PATH2_{}".format(addr_type): [{
-                        "action": "permit",
-                        "seq_id": 20,
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pf_ls_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "locPrf": 600
+                    "rmap_PATH2_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "seq_id": 20,
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pf_ls_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"locPrf": 600},
                         }
-                    }]
+                    ]
                 }
             }
         }
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
-        input_dict_rma={
+        input_dict_rma = {
             "r1": {
-                "bgp":
-                [
+                "bgp": [
                     {
                         "local_as": "100",
                         "address_family": {
@@ -466,36 +465,44 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
                                         "r3": {
                                             "dest_link": {
                                                 "r1-link1": {
-                                                    "route_maps": [{
-                                                        "name": "rmap_PATH1_{}".\
-                                                            format(addr_type),
-                                                        "direction": "in"
-                                                    }]
+                                                    "route_maps": [
+                                                        {
+                                                            "name": "rmap_PATH1_{}".format(
+                                                                addr_type
+                                                            ),
+                                                            "direction": "in",
+                                                        }
+                                                    ]
                                                 }
                                             }
                                         },
                                         "r4": {
                                             "dest_link": {
                                                 "r1-link1": {
-                                                    "route_maps": [{
-                                                        "name": "rmap_PATH2_{}".\
-                                                            format(addr_type),
-                                                        "direction": "in"
-                                                    }]
+                                                    "route_maps": [
+                                                        {
+                                                            "name": "rmap_PATH2_{}".format(
+                                                                addr_type
+                                                            ),
+                                                            "direction": "in",
+                                                        }
+                                                    ]
                                                 }
                                             }
-                                        }
+                                        },
                                     }
                                 }
                             }
-                        }
+                        },
                     }
-                ]}
+                ]
             }
+        }
 
         result = create_router_bgp(tgen, topo, input_dict_rma)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     dut = "r1"
     attribute = "locPrf"
@@ -506,20 +513,18 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
 
         input_routes_r3 = {
             "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_3[addr_type], \
-                        NETWORK3_4[addr_type]
-                    ]
-                }]
+                "static_routes": [
+                    {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]}
+                ]
             }
         }
 
-        result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
-                                                        input_routes_r3,
-                                                        attribute)
+        result = verify_best_path_as_per_bgp_attribute(
+            tgen, addr_type, dut, input_routes_r3, attribute
+        )
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
@@ -528,26 +533,26 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_PATH1_{}".format(addr_type): [{
-                        "action": "permit",
-                        "seq_id": 10,
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pf_ls_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "locPrf": 700
+                    "rmap_PATH1_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "seq_id": 10,
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pf_ls_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"locPrf": 700},
                         }
-                    }]
+                    ]
                 }
             }
         }
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
@@ -555,20 +560,18 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
 
         input_routes_r3 = {
             "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_3[addr_type], \
-                        NETWORK3_4[addr_type]
-                    ]
-                }]
+                "static_routes": [
+                    {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]}
+                ]
             }
         }
 
-        result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
-                                                        input_routes_r3,
-                                                        attribute)
+        result = verify_best_path_as_per_bgp_attribute(
+            tgen, addr_type, dut, input_routes_r3, attribute
+        )
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
@@ -577,30 +580,29 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_PATH2_{}".format(addr_type): [{
-                        "action": "permit",
-                        "seq_id": 20,
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pf_ls_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "localpref": 700,
-                            "path": {
-                                "as_num": "111",
-                                "as_action": "prepend"
-                            }
+                    "rmap_PATH2_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "seq_id": 20,
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pf_ls_{}".format(addr_type)
+                                }
+                            },
+                            "set": {
+                                "localpref": 700,
+                                "path": {"as_num": "111", "as_action": "prepend"},
+                            },
                         }
-                    }]
+                    ]
                 }
             }
         }
 
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     attribute = "path"
 
@@ -610,20 +612,18 @@ def test_bgp_best_path_with_dynamic_import_p0(request):
 
         input_routes_r3 = {
             "r3": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK3_3[addr_type], \
-                        NETWORK3_4[addr_type]
-                    ]
-                }]
+                "static_routes": [
+                    {"network": [NETWORK3_3[addr_type], NETWORK3_4[addr_type]]}
+                ]
             }
         }
 
-        result = verify_best_path_as_per_bgp_attribute(tgen, addr_type, dut,
-                                                        input_routes_r3,
-                                                        attribute)
+        result = verify_best_path_as_per_bgp_attribute(
+            tgen, addr_type, dut, input_routes_r3, attribute
+        )
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     write_test_footer(tc_name)
 
@@ -645,71 +645,77 @@ def test_modify_route_map_match_set_clauses_p1(request):
 
     for addr_type in ADDR_TYPES:
 
-        step("Configure route-map to set community attribute for a specific"
-            "prefix on R1 in vrf ISR")
+        step(
+            "Configure route-map to set community attribute for a specific"
+            "prefix on R1 in vrf ISR"
+        )
 
         input_dict_pf = {
             "r1": {
                 "prefix_lists": {
                     addr_type: {
-                        "pflist_ABC_{}".format(addr_type): [{
-                            "seqid": 10,
-                            "network": NETWORK1_1[addr_type],
-                            "action": "permit"
-                        }]
+                        "pflist_ABC_{}".format(addr_type): [
+                            {
+                                "seqid": 10,
+                                "network": NETWORK1_1[addr_type],
+                                "action": "permit",
+                            }
+                        ]
                     }
                 }
             }
         }
         result = create_prefix_lists(tgen, input_dict_pf)
         assert result is True, "Testcase {} : Failed \n Error: {}".format(
-            tc_name, result)
+            tc_name, result
+        )
 
     input_dict_cl = {
         "r1": {
             "bgp_community_lists": [
-            {
-                "community_type": "expanded",
-                "action": "permit",
-                "name": "COMM",
-                "value": "100:100"
+                {
+                    "community_type": "expanded",
+                    "action": "permit",
+                    "name": "COMM",
+                    "value": "100:100",
                 }
             ]
         }
     }
     result = create_bgp_community_lists(tgen, input_dict_cl)
-    assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-        tc_name, result)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
 
     for addr_type in ADDR_TYPES:
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_XYZ_{}".format(addr_type): [{
-                        "action": "permit",
-                        "match": {
-                            addr_type: {
-                                "prefix_lists":
-                                    "pflist_ABC_{}".format(addr_type)
-                            }
-                        },
-                        "set": {
-                            "community": {"num": "100:100"}
+                    "rmap_XYZ_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "match": {
+                                addr_type: {
+                                    "prefix_lists": "pflist_ABC_{}".format(addr_type)
+                                }
+                            },
+                            "set": {"community": {"num": "100:100"}},
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Apply this route-map on R1 to vrf ISR while redistributing the"
-            " prefixes into BGP")
+        step(
+            "Apply this route-map on R1 to vrf ISR while redistributing the"
+            " prefixes into BGP"
+        )
 
-        input_dict_1={}
+        input_dict_1 = {}
         DUT = ["r1"]
         VRFS = ["ISR"]
         AS_NUM = [100]
@@ -725,54 +731,59 @@ def test_modify_route_map_match_set_clauses_p1(request):
                     "address_family": {
                         addr_type: {
                             "unicast": {
-                                "redistribute": [{
-                                    "redist_type": "static",
+                                "redistribute": [
+                                    {
+                                        "redist_type": "static",
                                         "attribute": {
-                                            "route-map" : "rmap_XYZ_{}".\
-                                                format(addr_type)
-                                        }
+                                            "route-map": "rmap_XYZ_{}".format(addr_type)
+                                        },
                                     }
                                 ]
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_1)
-        assert result is True, "Testcase {} :Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} :Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Configure another route-map for filtering the prefixes based on"
-            " community attribute while importing into default vrf")
+        step(
+            "Configure another route-map for filtering the prefixes based on"
+            " community attribute while importing into default vrf"
+        )
 
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [{
-                        "action": "permit",
-                        "seq_id": 10,
-                        "match": {
-                            "community_list": {"id": "COMM"}
-                        },
-                        "set": {
-                            "community": {"num": "none"}
+                    "rmap_IMP_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "seq_id": 10,
+                            "match": {"community_list": {"id": "COMM"}},
+                            "set": {"community": {"num": "none"}},
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Apply the route-map while Importing vrf ISR's prefixes into "
-            "default vrf on router R1:")
+        step(
+            "Apply the route-map while Importing vrf ISR's prefixes into "
+            "default vrf on router R1:"
+        )
 
-        input_dict_isr={}
+        input_dict_isr = {}
         DUT = ["r1"]
         VRFS = ["default"]
         AS_NUM = [100]
@@ -786,15 +797,10 @@ def test_modify_route_map_match_set_clauses_p1(request):
                     "local_as": as_num,
                     "vrf": vrf,
                     "address_family": {
-                        addr_type: {
-                            "unicast": {
-                                "import": {
-                                    "vrf": "ISR"
-                                }
-                            }
-                        }
-                    }
-                })
+                        addr_type: {"unicast": {"import": {"vrf": "ISR"}}}
+                    },
+                }
+            )
 
             temp[dut]["bgp"].append(
                 {
@@ -808,34 +814,35 @@ def test_modify_route_map_match_set_clauses_p1(request):
                                 }
                             }
                         }
-                    }
-                })
+                    },
+                }
+            )
 
         result = create_router_bgp(tgen, topo, input_dict_isr)
-        assert result is True, "Testcase {} : Failed \n Error: {}". \
-            format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify on R1 that only prefixes with community value 100:100"
+        step(
+            "Verify on R1 that only prefixes with community value 100:100"
             "in vrf ISR are imported to vrf default. While importing, the"
-            " community value has been stripped off:")
+            " community value has been stripped off:"
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
         result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1)
-        assert result is True, \
-            "Testcase {} : Failed \n Error {}". \
-                format(tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
@@ -844,119 +851,106 @@ def test_modify_route_map_match_set_clauses_p1(request):
         input_dict_rm = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [{
-                        "action": "permit",
-                        "seq_id": 10,
-                        "match": {
-                            "community_list": {"id": "COMM"}
-                        },
-                        "set": {
-                            "large_community": {"num": "100:100:100"},
-                            "locPrf": 500,
-                            "path": {
-                                "as_num": "100 100",
-                                "as_action": "prepend"
-                            }
+                    "rmap_IMP_{}".format(addr_type): [
+                        {
+                            "action": "permit",
+                            "seq_id": 10,
+                            "match": {"community_list": {"id": "COMM"}},
+                            "set": {
+                                "large_community": {"num": "100:100:100"},
+                                "locPrf": 500,
+                                "path": {"as_num": "100 100", "as_action": "prepend"},
+                            },
                         }
-                    }]
+                    ]
                 }
             }
         }
         result = create_route_maps(tgen, input_dict_rm)
-        assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-            tc_name, result)
+        assert result is True, "Testcase {} : Failed \n Error: {}".format(
+            tc_name, result
+        )
 
     for addr_type in ADDR_TYPES:
 
-        step("Verify that as we continue adding different attributes "
+        step(
+            "Verify that as we continue adding different attributes "
             "step-by-step in route-map IMP those attributes gets "
-            "attached to prefixes:")
+            "attached to prefixes:"
+        )
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        input_dict_comm = {
-            "largeCommunity": "100:100:100"
-        }
+        input_dict_comm = {"largeCommunity": "100:100:100"}
 
-        result = verify_bgp_community(tgen, addr_type, dut, [NETWORK1_1[addr_type]],
-                                      input_dict_comm)
-        assert result is True, (
-            "Testcase {} : Failed \n Error {}".format(
-            tc_name, result))
+        result = verify_bgp_community(
+            tgen, addr_type, dut, [NETWORK1_1[addr_type]], input_dict_comm
+        )
+        assert result is True, "Testcase {} : Failed \n Error {}".format(
+            tc_name, result
+        )
 
         input_rmap = {
             "r1": {
                 "route_maps": {
-                    "rmap_IMP_{}".format(addr_type): [
-                        {
-                            "set": {
-                                "locPrf": 500
-                            }
-                        }
-                    ]
+                    "rmap_IMP_{}".format(addr_type): [{"set": {"locPrf": 500}}]
                 }
             }
         }
 
-        result = verify_bgp_attributes(tgen, addr_type, "r1",\
-                                       [NETWORK1_1[addr_type]],
-                                       rmap_name="rmap_IMP_{}".format(addr_type),\
-                                       input_dict=input_rmap)
-        assert result is True, "Testcase  : Failed \n Error: {}".format(
-                tc_name, result)
+        result = verify_bgp_attributes(
+            tgen,
+            addr_type,
+            "r1",
+            [NETWORK1_1[addr_type]],
+            rmap_name="rmap_IMP_{}".format(addr_type),
+            input_dict=input_rmap,
+        )
+        assert result is True, "Testcase  : Failed \n Error: {}".format(tc_name, result)
 
-    step("Change community-list to match a different value then "
-            "100:100.")
+    step("Change community-list to match a different value then " "100:100.")
 
     input_dict_cl = {
         "r1": {
             "bgp_community_lists": [
-            {
-                "community_type": "expanded",
-                "action": "permit",
-                "name": "COMM",
-                "value": "100:100",
-                "delete": True
+                {
+                    "community_type": "expanded",
+                    "action": "permit",
+                    "name": "COMM",
+                    "value": "100:100",
+                    "delete": True,
                 }
             ]
         }
     }
     result = create_bgp_community_lists(tgen, input_dict_cl)
-    assert result is True, 'Testcase {} : Failed \n Error: {}'.format(
-        tc_name, result)
+    assert result is True, "Testcase {} : Failed \n Error: {}".format(tc_name, result)
 
     for addr_type in ADDR_TYPES:
 
         input_routes_r1 = {
             "r1": {
-                "static_routes": [{
-                    "network": [
-                        NETWORK1_1[addr_type]
-                    ],
-                    "vrf": "default"
-                }]
+                "static_routes": [
+                    {"network": [NETWORK1_1[addr_type]], "vrf": "default"}
+                ]
             }
         }
 
-        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1,
-                            expected=False)
+        result = verify_bgp_rib(tgen, addr_type, "r1", input_routes_r1, expected=False)
         assert result is not True, (
             "Testcase {} : Failed \n Error : Routes are still "
-            "present {}".\
-                format(tc_name, result))
+            "present {}".format(tc_name, result)
+        )
 
     write_test_footer(tc_name)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index e913105e4394f6f3a25bd165a11a8ec4f927928f..46e21857c8e137e121c77156f69b06bec2ed01b5 100644 (file)
@@ -71,7 +71,7 @@ from lib.common_config import (
     configure_brctl,
     apply_raw_config,
     verify_vrf_vni,
-    verify_cli_json
+    verify_cli_json,
 )
 
 from lib.topolog import logger
@@ -81,7 +81,7 @@ from lib.bgp import (
     clear_bgp,
     verify_best_path_as_per_bgp_attribute,
     verify_attributes_for_evpn_routes,
-    verify_evpn_routes
+    verify_evpn_routes,
 )
 from lib.topojson import build_topo_from_json, build_config_from_json
 
@@ -177,9 +177,11 @@ def setup_module(mod):
     # Creating configuration from JSON
     build_config_from_json(tgen, topo)
 
-    if version_cmp(platform.release(), '4.19') < 0:
-        error_msg = ('EVPN tests will not run (have kernel "{}", '
-            'but it requires >= 4.19)'.format(platform.release()))
+    if version_cmp(platform.release(), "4.19") < 0:
+        error_msg = (
+            'EVPN tests will not run (have kernel "{}", '
+            "but it requires >= 4.19)".format(platform.release())
+        )
         pytest.skip(error_msg)
 
     global BGP_CONVERGENCE
@@ -389,9 +391,9 @@ def test_verify_overlay_index_p1(request):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -463,7 +465,7 @@ def test_evpn_cli_json_available_p1(request):
             "cli": [
                 "show evpn vni detail",
                 "show bgp l2vpn evpn all overlay",
-                "show bgp l2vpn evpn vni"
+                "show bgp l2vpn evpn vni",
             ]
         }
     }
@@ -516,9 +518,9 @@ def test_RT_verification_auto_p0(request):
                         "network": NETWORK4_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
index c1eb7d68bb1833b2d83cd75f76e09157e5654586..87f391ae49f0b507d35ff47e528dbb95cca5107d 100644 (file)
@@ -77,7 +77,7 @@ from lib.common_config import (
     configure_vxlan,
     configure_brctl,
     verify_vrf_vni,
-    create_interface_in_kernel
+    create_interface_in_kernel,
 )
 
 from lib.topolog import logger
@@ -87,7 +87,7 @@ from lib.bgp import (
     clear_bgp,
     verify_best_path_as_per_bgp_attribute,
     verify_attributes_for_evpn_routes,
-    verify_evpn_routes
+    verify_evpn_routes,
 )
 from lib.topojson import build_topo_from_json, build_config_from_json
 
@@ -179,9 +179,11 @@ def setup_module(mod):
     # Creating configuration from JSON
     build_config_from_json(tgen, topo)
 
-    if version_cmp(platform.release(), '4.19') < 0:
-        error_msg = ('EVPN tests will not run (have kernel "{}", '
-            'but it requires >= 4.19)'.format(platform.release()))
+    if version_cmp(platform.release(), "4.19") < 0:
+        error_msg = (
+            'EVPN tests will not run (have kernel "{}", '
+            "but it requires >= 4.19)".format(platform.release())
+        )
         pytest.skip(error_msg)
 
     global BGP_CONVERGENCE
@@ -387,9 +389,9 @@ def test_RD_verification_manual_and_auto_p0(request):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -453,7 +455,7 @@ def test_RD_verification_manual_and_auto_p0(request):
                     "vrf": "RED",
                     "address_family": {
                         "l2vpn": {"evpn": {"rd": "100.100.100.100:100"}}
-                    }
+                    },
                 }
             ]
         }
@@ -620,9 +622,9 @@ def test_RT_verification_manual_p0(request):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -652,7 +654,7 @@ def test_RT_verification_manual_p0(request):
                         "l2vpn": {
                             "evpn": {"route-target": {"export": [{"value": "100:100"}]}}
                         },
-                    }
+                    },
                 }
             ]
         }
@@ -995,9 +997,9 @@ def test_active_standby_evpn_implementation_p1(request):
                         "network": NETWORK1_4[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -1249,9 +1251,9 @@ def test_evpn_routes_from_VNFs_p1(request):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -1382,9 +1384,9 @@ def test_evpn_routes_from_VNFs_p1(request):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -1617,9 +1619,9 @@ def test_route_map_operations_for_evpn_address_family_p1(request, attribute):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
@@ -1811,9 +1813,9 @@ def test_bgp_attributes_for_evpn_address_family_p1(request, attribute):
                         "network": NETWORK3_1[addr_type],
                         "next_hop": NEXT_HOP_IP[addr_type],
                         "vrf": "GREEN",
-                    }
+                    },
                 ]
-            }
+            },
         }
 
         result = create_static_routes(tgen, input_dict_1)
index 26ec4eb26169aecda1ca06b32a71d53e1ad744a4..f44152759786b2730d7f12841381a98edfd4de5e 100644 (file)
@@ -19,9 +19,9 @@ interface eth-sw1
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0001.00
  is-type level-1
- lsp-gen-interval 2
  topology ipv6-unicast
  segment-routing on
  segment-routing global-block 16000 23999
index 6b4a59011a6a4c399e3434648dc84d6b3595feaf..53bf8cb4458b7d8155d0bec95434a71ba462acc2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 773f5e3d439abff551e7cda4a36cac491b8463e7..5b1950d8cb245cc0897bcf65e5dff9357b703845 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 69dcc91b1d622ae84586548e512a7799ebd1c8bd..26f0dffa7ae24197ecdef2e26f0cbccabcdd269f 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 2,
                   "hold-timer": 9,
                   "neighbor-priority": 64,
                   "state": "up"
@@ -19,7 +18,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 2,
                   "hold-timer": 9,
                   "neighbor-priority": 64,
                   "state": "up"
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 25a48c2bfc1e22162f61b364497877c06576ceea..7e6c72627aa3bbfffe3edc702c13da914fac0c31 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 773f5e3d439abff551e7cda4a36cac491b8463e7..5b1950d8cb245cc0897bcf65e5dff9357b703845 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 05a8498693b1414f89954b5d5c87d86255c156a3..71f9ebddfbd2d43c5e3e4c281468e1ab8de92586 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index d50952c6c4b5bbfb07946ec588f08138489500b4..304c0a475bb8ffdd72bb9eaad963239179326c09 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 73f517a6e529d954799a0ecd970f6d240528a483..94b3cb6d1a4812e469133eb864a33e77e2edc384 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index ac39920ee5d41d7b43e5e06fc180c0464e43bb40..6500a47fbf8c5727357f371d3da8c93af1470d69 100644 (file)
     "nexthops":[
       {
         "type":"SR (IS-IS)",
-        "outLabel":16060,
+        "outLabel":17060,
         "installed":true,
-        "nexthop":"10.0.1.2"
+        "nexthop":"10.0.1.3"
       },
       {
         "type":"SR (IS-IS)",
-        "outLabel":17060,
+        "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.1.3"
+        "nexthop":"10.0.1.2"
       }
     ]
   },
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 59213686f250768f83abde9cb31d909d0027c888..16d9358468a919f45c8e50aa12ae5a4ba2df8311 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index cdfae284ba8cf15643154f5979a2678c21d9bbdd..f2093a3fc0443e84df60dbcd6a8125d11b9f9cac 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 73f517a6e529d954799a0ecd970f6d240528a483..94b3cb6d1a4812e469133eb864a33e77e2edc384 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 773f5e3d439abff551e7cda4a36cac491b8463e7..5b1950d8cb245cc0897bcf65e5dff9357b703845 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 773f5e3d439abff551e7cda4a36cac491b8463e7..5b1950d8cb245cc0897bcf65e5dff9357b703845 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 773f5e3d439abff551e7cda4a36cac491b8463e7..5b1950d8cb245cc0897bcf65e5dff9357b703845 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 6b34d5e4ffdbf607f7a73ebd55d70d162c419fbd..c712538c00b3a190153aa97a65fd8d9a458aaeb2 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index c507688f5b4957ce68312bed2738d84e537a6a5a..0b39584717f608e11bf0b335cf1ee716640dc7a9 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            17101
+          ]
+        }
+      ]
+    }
   ]
 }
index 25a48c2bfc1e22162f61b364497877c06576ceea..7e6c72627aa3bbfffe3edc702c13da914fac0c31 100644 (file)
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17101,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
   }
 }
index 8704a28b6c33e2d4bdbc0f986bb4d96de2fb49fe..796b6ed32c9a870f9b958238ebf8d2f5f81a7148 100644 (file)
@@ -30,9 +30,9 @@ interface eth-rt4-2
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0002.00
  is-type level-1
- lsp-gen-interval 2
  topology ipv6-unicast
  segment-routing on
  segment-routing global-block 16000 23999
index be037aba8bb0fea5290af939a0634ab6aadd9a58..109b94f7a1982dd54e4cc8c112ee8d50a217455f 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index a888198ac8861f4f6a19e83897ff50849f1b0698..eae700ee4791ab85c4c7a3bd2e714b38871c6776 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 42fde2d77fc01500590c83178ffc8ac82a6ff8ab..a32cd1d1bfb0b980cd212553f0f0033ce681fa69 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
     "nexthops":[
       {
         "type":"SR (IS-IS)",
-        "outLabel":17050,
+        "outLabel":16050,
         "installed":true,
-        "nexthop":"10.0.1.3"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
       },
       {
         "type":"SR (IS-IS)",
-        "outLabel":16050,
+        "outLabel":17050,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.1.3"
       }
     ]
   },
     "nexthops":[
       {
         "type":"SR (IS-IS)",
-        "outLabel":17051,
+        "outLabel":16051,
         "installed":true,
-        "interface":"eth-sw1"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
       },
       {
         "type":"SR (IS-IS)",
-        "outLabel":16051,
+        "outLabel":17051,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-sw1"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index be018fd59fb85dd579f03d0496f24baf7795cd7a..07f43e599928db93706fd17b76ffe5c92c549263 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0004",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0004",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 2,
                   "hold-timer": 9,
                   "neighbor-priority": 64,
                   "state": "up"
@@ -59,7 +56,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0001",
-                  "neighbor-extended-circuit-id": 2,
                   "hold-timer": 9,
                   "neighbor-priority": 64,
                   "state": "up"
index 33fbdba28f8aca3bfdbe57da080f99aa96a46f93..387d3b43d76a844da421eafbaa57d07add143846 100644 (file)
       ]
     }
   ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1"
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true
+        }
+      ]
+    }
+  ],
   "10.0.3.0\/24":[
     {
       "prefix":"10.0.3.0\/24",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 19837bc70040db721370c3083494b1a6a6a2ae2f..355436cbfccc090e63107121dac463beef089c6f 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 29ec55a589561e0accaf54f3cb87aca2d374f0e7..4cbdb9fda9d24739791cde55a12897b3b08de303 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index a110c51077491c9d5c7cfecc47ecbb6fc00e7a3c..159392f7f7681ec54811558f5597bf40049e616c 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index cb426897ce2176160ccb1b66a81c678563120bf2..e9f63849d8f8176cd6bdfe8d9026046a29234766 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 118ec89b5c90c86d57574615c8f2cb058fc48bc8..0692553808edfe5f7974cb92d7044a08748a4611 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index d31affeb5935927c8368ae6e5e1cadda0e7c0d5c..16f49ffe464e5dbcf77d661f8e70a92bb1df3440 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index d92df1918c9a3a9081fd7698aa7028b50996fd9e..bde83c30d0d5ee5a3d3f2aecbc21cdf85a9b8c93 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index f1e18be26beb293be4374541303185c8d2488d1e..cbb0d5c69594752c1961d67c42e21d71372595f4 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
   }
 }
index a110c51077491c9d5c7cfecc47ecbb6fc00e7a3c..159392f7f7681ec54811558f5597bf40049e616c 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index cb426897ce2176160ccb1b66a81c678563120bf2..e9f63849d8f8176cd6bdfe8d9026046a29234766 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 118ec89b5c90c86d57574615c8f2cb058fc48bc8..0692553808edfe5f7974cb92d7044a08748a4611 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index f378e41d8de9e3a7bb20b903391b0c7cb21baf9f..fbfcce10aabb62aa50fb58f2ed3cbb47cbb44932 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index d63e7ceba553c66754a5e94ed70c98233c20f660..f747a965181e35f3b58ef11b52612e03fa92fbf0 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index f1e18be26beb293be4374541303185c8d2488d1e..cbb0d5c69594752c1961d67c42e21d71372595f4 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "interface":"eth-sw1"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
   }
 }
index a110c51077491c9d5c7cfecc47ecbb6fc00e7a3c..159392f7f7681ec54811558f5597bf40049e616c 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index cb426897ce2176160ccb1b66a81c678563120bf2..e9f63849d8f8176cd6bdfe8d9026046a29234766 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 118ec89b5c90c86d57574615c8f2cb058fc48bc8..0692553808edfe5f7974cb92d7044a08748a4611 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index a9b086a248dc4296563fc5cb65f6a9aae8f7bf48..09ab6d4f8a6489378a33af7a012fd26d33dc12f6 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 1c61f91451bef01bd6942b6f38dc65ae557690ba..851275fbf75903eebcc04804a87394bfa950c6a6 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 0f0d24bbfbf9b74f6f270d8edcd8385dd894e8b0..87946aa7b94c56b4e986f944d3f17c244fa41a12 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index a110c51077491c9d5c7cfecc47ecbb6fc00e7a3c..159392f7f7681ec54811558f5597bf40049e616c 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index cb426897ce2176160ccb1b66a81c678563120bf2..e9f63849d8f8176cd6bdfe8d9026046a29234766 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 118ec89b5c90c86d57574615c8f2cb058fc48bc8..0692553808edfe5f7974cb92d7044a08748a4611 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index 2e4c20257f9fc991b688ef3ece4306a8b521b473..fc82ada7e3782d4ff6833de32676688d6be532cf 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 19837bc70040db721370c3083494b1a6a6a2ae2f..355436cbfccc090e63107121dac463beef089c6f 100644 (file)
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 7c910fc6f6f3e8550e3209e2fece14897e56e93b..05201724f48730d6044f14e77f3eccd5d642569b 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.2.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.3.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
         "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4-2"
       }
     ]
   }
index 5a0add22a9560e33151379dd8727896b2c407927..cc2aa1782b5741b30cf08a99ed90fee278ce558a 100644 (file)
@@ -30,9 +30,9 @@ interface eth-rt5-2
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0003.00
  is-type level-1
- lsp-gen-interval 2
  topology ipv6-unicast
  segment-routing on
  segment-routing global-block 17000 24999
index 8d4fbec4b5dd887e97ba26a6ac06924104d273b3..241f76885969c30e506c6b164a0d1bac0ee0bb2e 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 4e4961eaf076a5918e397afc9286d55d3dafc775..dd78c7d3184c1255057c9100bf680ae833f1669d 100644 (file)
@@ -56,7 +56,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-sw1",
           "active":true,
           "labels":[
             16041
@@ -65,7 +65,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-sw1",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16041
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16041
@@ -96,7 +96,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index b7bdc3e4afb36ac6d5570f0dfb8bb26d6b9e2411..8c6fca7b578ab92f1dc9b9a48602e3833048a4fd 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.1.2"
+        "nexthop":"10.0.5.5"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.5.5"
+        "nexthop":"10.0.4.5"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.4.5"
+        "nexthop":"10.0.1.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-sw1"
+        "interface":"eth-rt5-2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt5-2"
+        "interface":"eth-rt5-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt5-1"
+        "interface":"eth-sw1"
       }
     ]
   },
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 82069cec4800e05140eac8ec2f1db26162b150b9..7fa6f5cf476a3a278a871e39f77123ab7598e291 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0005",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0005",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0001",
-                  "neighbor-extended-circuit-id": 2,
                   "hold-timer": 9,
                   "neighbor-priority": 64,
                   "state": "up"
@@ -59,7 +56,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 2,
                   "hold-timer": 9,
                   "neighbor-priority": 64,
                   "state": "up"
index 9522b141b078e89470b598f58a66d6950931372a..40a98ab7c68361c54e115ee8002982204daf9bde 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index fb630bc68f04a499eb5f17011e39099d61ec4042..1fb50407bd74ff143114ab7908b3bbf1ef85da5e 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 4aec3b6904c6264d72f0acec09cd193134f8ba01..44ddc4bc146bcde3824bc0c2ac1b9052b7bdefd2 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 46ebeb8ab977269b5b6069ce4203e25ddd559131..55d8213c4ed1e1a46b4088af50e7e953e02b8f5f 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index b2c774d49393bc30c8a8a236431a7acd5fc1f479..4f6441e7b9a4eab62025a8c20bff34a6894cb1ac 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a1e64afd67c1ae3a460c743738dc4d8fe4bfeb10..db8253f83d5fd5357ccdae0457b02d2416bf9899 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 738aa174067ee8255dad66c2c1fa8528c46ae5ea..ed5cef8a5bb81ab1a27cb129333f86a04ed5073b 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index b6423cd2b8d5bf00b53dcf41af0895bb3b4153e3..b33058c3bda22fb2426be2e49661eacc7c2fc20c 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 1a2b8728e69c8b243403033cceb3f16d01587886..70cccc0f0ba7f289cbdd4306399f8b5305ae72de 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 46ebeb8ab977269b5b6069ce4203e25ddd559131..55d8213c4ed1e1a46b4088af50e7e953e02b8f5f 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index b2c774d49393bc30c8a8a236431a7acd5fc1f479..4f6441e7b9a4eab62025a8c20bff34a6894cb1ac 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a1e64afd67c1ae3a460c743738dc4d8fe4bfeb10..db8253f83d5fd5357ccdae0457b02d2416bf9899 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 489b495bb1490eaa2e537e9569aa9d39e32116e2..3adcdce58cb80ec49603f59eba0aeca7ea04f722 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 46ee7ba28ea45f4000cf8c404d90d8bf86152fca..863e26c30ef18d6cef4f902cfa4d5d47f658bbc4 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true
         },
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 1a2b8728e69c8b243403033cceb3f16d01587886..70cccc0f0ba7f289cbdd4306399f8b5305ae72de 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 46ebeb8ab977269b5b6069ce4203e25ddd559131..55d8213c4ed1e1a46b4088af50e7e953e02b8f5f 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index b2c774d49393bc30c8a8a236431a7acd5fc1f479..4f6441e7b9a4eab62025a8c20bff34a6894cb1ac 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a1e64afd67c1ae3a460c743738dc4d8fe4bfeb10..db8253f83d5fd5357ccdae0457b02d2416bf9899 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 1e8c27c01f7896690e2145eb7c337dffcf4353c5..7f6e05f08b4e9bcb0bdb0c6a24d7e39f6b1a5f01 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index d21700d407531cc4168b29f578efb5dc628abbf2..f4770e2ac9537d8d0c9a67de9dfca06129525ee3 100644 (file)
@@ -75,7 +75,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -84,7 +84,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index e97e0d017b9a35a0c6431cc5fb92244ca6bc4f4a..cb49505f55a238d45879a4df8062c8389d89dc71 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 46ebeb8ab977269b5b6069ce4203e25ddd559131..55d8213c4ed1e1a46b4088af50e7e953e02b8f5f 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index b2c774d49393bc30c8a8a236431a7acd5fc1f479..4f6441e7b9a4eab62025a8c20bff34a6894cb1ac 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a1e64afd67c1ae3a460c743738dc4d8fe4bfeb10..db8253f83d5fd5357ccdae0457b02d2416bf9899 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 9522b141b078e89470b598f58a66d6950931372a..40a98ab7c68361c54e115ee8002982204daf9bde 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index fb630bc68f04a499eb5f17011e39099d61ec4042..1fb50407bd74ff143114ab7908b3bbf1ef85da5e 100644 (file)
@@ -78,7 +78,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16051
@@ -87,7 +87,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16061
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16061
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 4aec3b6904c6264d72f0acec09cd193134f8ba01..44ddc4bc146bcde3824bc0c2ac1b9052b7bdefd2 100644 (file)
         "interface":"eth-rt5-1"
       }
     ]
+  },
+  "17100":{
+    "inLabel":17100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      }
+    ]
+  },
+  "17101":{
+    "inLabel":17101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      }
+    ]
   }
 }
index 39003b9d7b02eb06d1bdad778ced2cac97ee098e..3852b1962b72dc25b055cd6a5a66d5a303c980cc 100644 (file)
@@ -37,13 +37,15 @@ interface eth-rt6
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0004.00
  is-type level-1
- lsp-gen-interval 2
  topology ipv6-unicast
  segment-routing on
  segment-routing global-block 16000 23999
  segment-routing node-msd 8
  segment-routing prefix 4.4.4.4/32 index 40 no-php-flag
+ segment-routing prefix 10.10.10.10/32 index 100 no-php-flag n-flag-clear
  segment-routing prefix 2001:db8:1000::4/128 index 41 no-php-flag
+ segment-routing prefix 2001:db8:1000::10/128 index 101 no-php-flag n-flag-clear
 !
index f06182b088bc4ffd2a597ef42c7a65747699eee9..493f3ab60dcdd57edaad907fc7503c3a70e0c74d 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index f5772f27261871a01e0eb8ca9bdeb10ba945c5bd..217a4a5379bbabc2adc04b62a816b76419bb0417 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
@@ -92,7 +92,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16031
index b7fb69dcde497a49a54be83f9285c45294de59be..307403964aea8a586b313ecd48195611287b19f3 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       },
       {
         "type":"SR (IS-IS)",
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       },
       {
         "type":"SR (IS-IS)",
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.6.5"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 9d7a19e86833a7359bbbd063214daacb8aedd2dc..2eb64b6fc98dd42fd2cef1f9dca1c7eb4b5f578c 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0005",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -71,7 +68,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0006",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index d7d42120a082de9f41b9b3cdd079e6d68666c675..11bc9483193d9a375f669f239646e929fa98153d 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index 235c1facc6d5fc408b2477fc43986f4fb7b0648d..844f6becf930747e978cad2a8e76e1f21760bb3b 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 86ceaf4883812cf8e5f77d07b1f210bacc52a2ef..f2750560703431859c8db51f9876fcfa7769e4f7 100644 (file)
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 4789f7268f1a166d506bb48b9bb65dda74aaab53..c2fbdeb30ea77b749efcfadeaa4d9cdaa8936b9c 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 871b303cabc29ebad8425745ae5d091ab4877196..7f823b6896e7f9c1132d965f0f4baaeb12546e6e 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index ff83c374f05473c9ff4a69d1e601b1602a2a2325..8dd37880d0e2f46c08640dee9ed274381dfd88bb 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 5fb8a361ac485a7909ae8cb60d92e067aaf0e58b..be1e00b8a259a3fb9a145cb07be1c6b61fccc4f8 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0006",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index d86562deb982d1331e113ca9ae0d2939c9fbb6da..4dc0dd7cacac06df5a195be8f02e8b0fe1cae8cc 100644 (file)
       "metric":40,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.2.2",
           "afi":"ipv4",
           "interfaceName":"eth-rt2-1",
           "active":true
         },
         {
+          "fib":true,
           "ip":"10.0.3.2",
           "afi":"ipv4",
           "interfaceName":"eth-rt2-2",
       ]
     }
   ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6"
+        }
+      ]
+    }
+  ],
   "10.0.8.0\/24":[
     {
       "prefix":"10.0.8.0\/24",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":40,
+      "nexthops":[
+        {
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index c09f584641b494163a690a49c35872e8c77b0442..34afda1966a226e545dc0320378615fb88cb8979 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16051
index 85c6c055c947c969ebf436c81767c1004120795a..65336d88d1559725f0ec58bb95b400b6313727b5 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16050,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16050,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16051,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16051,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
+      }
+    ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.2.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.3.2"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
       }
     ]
   }
index 2a56f54e1613f8a1b6a47821345bb0ff1bb752db..bcade1ca908538b9b7f3f7db5c4af337230836da 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0002",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index 3c7dfda0a371a55c237b8e9ffe74e966d331f20f..e930657f8dc38ee59587c0179fcb49ae12eba0fe 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index 38b51822ddf70c05e28a83604a0d7c9c9be1c806..ca61c6e81f03602a30d623517d2b2e95ece6960a 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 4e5638f34f3891008a6590a9d3209fa787806d8e..eb95fa94c99981b01d29b41b936b1915393c1db6 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 90f69c06b8a3b543fd58c191575f5d54a89ddb8c..8b0ddd4ee522496c5cda2b7425353582fabb8883 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
   ]
 }
index 04056ed87317b615edd3143ff401fda37c703561..94e1fac45065bfc3793aa6268366016735ea3d16 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 4df722be4fec19085cccd79a370e8d4c1059a102..cd47cfa3a720e0dd9bf8c9aa10208706192697e4 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "installed":true
       }
     ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 3c7dfda0a371a55c237b8e9ffe74e966d331f20f..e930657f8dc38ee59587c0179fcb49ae12eba0fe 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index 38b51822ddf70c05e28a83604a0d7c9c9be1c806..ca61c6e81f03602a30d623517d2b2e95ece6960a 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 4e5638f34f3891008a6590a9d3209fa787806d8e..eb95fa94c99981b01d29b41b936b1915393c1db6 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index a3ac4ac10934da704622576a5276bd79574b4ba8..f5ac45504e27448fb83d471a6468cd75c7a1f4d3 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index c59abbd2f5d7ca2d3e78a4e729f1988eed0cfeac..1599c88122dc245c50f3933a820ccae46c26b654 100644 (file)
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true
         },
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true
         }
       ]
@@ -37,7 +37,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -46,7 +46,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -68,7 +68,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -77,7 +77,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 512c057b3168d6f7685d2dff1adac33de937571b..19b0beb1641f8669dfd1f55c47aa591411a98440 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 3c7dfda0a371a55c237b8e9ffe74e966d331f20f..e930657f8dc38ee59587c0179fcb49ae12eba0fe 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index 38b51822ddf70c05e28a83604a0d7c9c9be1c806..ca61c6e81f03602a30d623517d2b2e95ece6960a 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 4e5638f34f3891008a6590a9d3209fa787806d8e..eb95fa94c99981b01d29b41b936b1915393c1db6 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 73598e4605e181e04a7791dbfef965059c078079..a2b939a41828f3e9c6ffc3f1f421a3c5d87ea97a 100644 (file)
       "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index 235c1facc6d5fc408b2477fc43986f4fb7b0648d..844f6becf930747e978cad2a8e76e1f21760bb3b 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16011
@@ -43,7 +43,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16021
@@ -52,7 +52,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16021
@@ -74,7 +74,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
@@ -83,7 +83,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
index 5cdd99e4254f95f2c3dc14d9e6ba57acc0e9613c..5805bf35562490ffdf2fcccb4fb0ece17e7acf9d 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16020,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16021,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.3.2"
+        "nexthop":"10.0.2.2"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16030,
         "installed":true,
-        "nexthop":"10.0.2.2"
+        "nexthop":"10.0.3.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-2"
+        "interface":"eth-rt2-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16031,
         "installed":true,
-        "interface":"eth-rt2-1"
+        "interface":"eth-rt2-2"
       }
     ]
   },
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 4945897e9d4027d8a70de751b8dca149f3eeecdb..5889901c5693e7f084368f8aeadc6226f377a2fc 100644 (file)
@@ -8,7 +8,9 @@ debug zebra mpls
 !
 interface lo
  ip address 4.4.4.4/32
+ ip address 10.10.10.10/32
  ipv6 address 2001:db8:1000::4/128
+ ipv6 address 2001:db8:1000::10/128
 !
 interface eth-rt2-1
  ip address 10.0.2.4/24
index e693ca156c7ea1f53ddeb46a12f19f220fe0e265..f7beea796cc91f0eed9aa23c22a5d77d26dfe93c 100644 (file)
@@ -37,13 +37,15 @@ interface eth-rt6
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0005.00
  is-type level-1
- lsp-gen-interval 2
  topology ipv6-unicast
  segment-routing on
  segment-routing global-block 16000 23999
  segment-routing node-msd 8
  segment-routing prefix 5.5.5.5/32 index 50 no-php-flag
+ segment-routing prefix 10.10.10.10/32 index 100 no-php-flag n-flag-clear
  segment-routing prefix 2001:db8:1000::5/128 index 51 no-php-flag
+ segment-routing prefix 2001:db8:1000::10/128 index 101 no-php-flag n-flag-clear
 !
index 8eaf40f236f3331448d4afa1320915bf094c07b7..0497bd8399bcee02f8b0f1ab07b7eea3616d5eca 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 9054c9c4af23683fd27109617cd748651d61258a..99d1f773b75c0dea66687e152d93fcee43f84ebd 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.6.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 4a3e626123049cfccb8622e76a6c5acf1fd8230b..1ff8c2cd4e77f6616905c1aa048756f52e05368d 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0004",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -71,7 +68,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0006",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index a5a0bacaadc7bd30749e946d9b170babd241d61b..620f5eac67adf3c27d8d3eeb6d7763712c47cf67 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
+        }
+      ]
+    }
   ]
 }
index e43ef6671d20604949010f5d6ff51f8cfac5e97c..7cfea2a3291a7ea93dfde4b1065c1e773b1dbd6a 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 101b811d3b72f119b9c415458694aa346668ad08..19cdf9d89672ac58494688daa45d82b9ebc5e170 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":30,
+      "nexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 660e319a50358442db1aff903e539c96b7f40f93..08f1635a395d079dc653ccddc7811c900cef89bb 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index ae26b5be99bef9c16cffe9b0f9564f6f41a7bb9c..d9ac0a8d004589ad2d5b54803e642deea31151e8 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0006",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index dff6c5f7ebde128964e58952ffc43fd21e7d6b00..48b5e6491eadafeb92f5164e6e45bfb3e90bc320 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "distance":115,
+      "metric":40,
+      "nexthops":[
+        {
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        },
+        {
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "labels":[
+            17100
+          ]
+        }
+      ]
+    }
   ]
 }
index 9df3fc9ef6884b52a14fcf9982cb3df1bf790a64..9980058b128bc32a88b14dc8189671411b39ad45 100644 (file)
         "installed":true
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.5.3"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":17100,
+        "installed":true,
+        "nexthop":"10.0.4.3"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 7e62a65ea116c68a286280a04f45b905fe28e0cb..0b8e6ba5b94fb71adbd11f95fa6f6876d8ca9139 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index 6b29ff2d443f1ce6bcea92a829b509088b85b5bc..156beef0f1017d0a773d5d718f2817764aac7ccf 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
       ]
     }
   ],
-  "10.0.8.0\/24":[
+  "10.10.10.10\/32":[
     {
-      "prefix":"10.0.8.0\/24",
+      "prefix":"10.10.10.10\/32",
       "protocol":"isis",
       "distance":115,
-      "metric":20,
+      "metric":30,
       "nexthops":[
         {
           "ip":"10.0.8.6",
           "afi":"ipv4",
-          "interfaceName":"eth-rt6"
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
         }
       ]
     }
index 4d13108d7d1a0210490b951a94f308b712a11b74..a84ed90b255fa3aed95a24d45688c96e83339463 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index ae26b5be99bef9c16cffe9b0f9564f6f41a7bb9c..d9ac0a8d004589ad2d5b54803e642deea31151e8 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0003",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -51,7 +49,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0006",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index cadb674ba37ae7b2f3e2b1b1e45771244c6c2adf..dba5e8d8a2d79cac9646b869ca921fa8dc56da14 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
       ]
     }
   ],
-  "10.0.8.0\/24":[
+  "10.10.10.10\/32":[
     {
-      "prefix":"10.0.8.0\/24",
+      "prefix":"10.10.10.10\/32",
       "protocol":"isis",
       "distance":115,
-      "metric":20,
+      "metric":30,
       "nexthops":[
         {
+          "fib":true,
           "ip":"10.0.8.6",
           "afi":"ipv4",
-          "interfaceName":"eth-rt6"
+          "interfaceName":"eth-rt6",
+          "active":true
         }
       ]
     }
index c60383093f775f128ff2f20da2231fbbc4680712..36c21b041fa34e74e03c46b8b6dd44d3c3bd8041 100644 (file)
         "installed":true
       }
     ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 6b29ff2d443f1ce6bcea92a829b509088b85b5bc..156beef0f1017d0a773d5d718f2817764aac7ccf 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
       ]
     }
   ],
-  "10.0.8.0\/24":[
+  "10.10.10.10\/32":[
     {
-      "prefix":"10.0.8.0\/24",
+      "prefix":"10.10.10.10\/32",
       "protocol":"isis",
       "distance":115,
-      "metric":20,
+      "metric":30,
       "nexthops":[
         {
           "ip":"10.0.8.6",
           "afi":"ipv4",
-          "interfaceName":"eth-rt6"
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
         }
       ]
     }
index 4d13108d7d1a0210490b951a94f308b712a11b74..a84ed90b255fa3aed95a24d45688c96e83339463 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 72b89ccf69327b430a135a164afa3d0882091fca..ece747bdac0fa4aa1a2d452d9880e2e952fd1812 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
       ]
     }
   ],
-  "10.0.8.0\/24":[
+  "10.10.10.10\/32":[
     {
-      "prefix":"10.0.8.0\/24",
+      "prefix":"10.10.10.10\/32",
       "protocol":"isis",
       "distance":115,
-      "metric":20,
+      "metric":30,
       "nexthops":[
         {
           "ip":"10.0.8.6",
           "afi":"ipv4",
-          "interfaceName":"eth-rt6"
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
         }
       ]
     }
index 2b1e67ea71b9e800419b7457565ce3a2a078d9da..c98da7effd2a9214092c3057b1e482ecb8531913 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 6b29ff2d443f1ce6bcea92a829b509088b85b5bc..156beef0f1017d0a773d5d718f2817764aac7ccf 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
       ]
     }
   ],
-  "10.0.8.0\/24":[
+  "10.10.10.10\/32":[
     {
-      "prefix":"10.0.8.0\/24",
+      "prefix":"10.10.10.10\/32",
       "protocol":"isis",
       "distance":115,
-      "metric":20,
+      "metric":30,
       "nexthops":[
         {
           "ip":"10.0.8.6",
           "afi":"ipv4",
-          "interfaceName":"eth-rt6"
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
         }
       ]
     }
index 4d13108d7d1a0210490b951a94f308b712a11b74..a84ed90b255fa3aed95a24d45688c96e83339463 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index cc37894d6781e45039c453515cc0054550a48c83..90588c6708d533a122b40a70eebf9d68d1f43e20 100644 (file)
       ]
     }
   ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4"
+        }
+      ]
+    }
+  ],
   "10.0.7.0\/24":[
     {
       "prefix":"10.0.7.0\/24",
       ]
     }
   ],
-  "10.0.8.0\/24":[
+  "10.10.10.10\/32":[
     {
-      "prefix":"10.0.8.0\/24",
+      "prefix":"10.10.10.10\/32",
       "protocol":"isis",
       "distance":115,
-      "metric":20,
+      "metric":30,
       "nexthops":[
         {
           "ip":"10.0.8.6",
           "afi":"ipv4",
-          "interfaceName":"eth-rt6"
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "labels":[
+            18100
+          ]
         }
       ]
     }
index e43ef6671d20604949010f5d6ff51f8cfac5e97c..7cfea2a3291a7ea93dfde4b1065c1e773b1dbd6a 100644 (file)
         "interface":"eth-rt6"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":18100,
+        "installed":true,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true
+      }
+    ]
   }
 }
index 4cfea1a59f86751448c199f9383c2fc548acfff0..a0c8f2cd7e4c2013e20b28265ae5de9c4e2fbe65 100644 (file)
@@ -8,7 +8,9 @@ debug zebra mpls
 !
 interface lo
  ip address 5.5.5.5/32
+ ip address 10.10.10.10/32
  ipv6 address 2001:db8:1000::5/128
+ ipv6 address 2001:db8:1000::10/128
 !
 interface eth-rt3-1
  ip address 10.0.4.5/24
index 3b85dbae4e97dd5b80f12e1780d8596685036d32..a29b78f0a43c60c198828c74d8f0e24471bbdf47 100644 (file)
@@ -25,9 +25,9 @@ interface eth-rt5
  isis hello-multiplier 3
 !
 router isis 1
+ lsp-gen-interval 2
  net 49.0000.0000.0000.0006.00
  is-type level-1
- lsp-gen-interval 2
  topology ipv6-unicast
  segment-routing on
  segment-routing global-block 16000 23999
index 324b71f7b8605be5dd6cd9b1d14399cd68faea53..7b62b0a9c6168151fc24098c9d2be044990af59a 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 970251fe8ac751f91cb0541b6fb78388e0c38446..2c526e74f01a1b064775c56bc5176c4bb1caa9fa 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index 49c40a471c6770550e0f75da6632a13924d613d8..734832358f70cca20a5a590ed89cfe08fecf30bd 100644 (file)
@@ -11,7 +11,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0004",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
@@ -31,7 +30,6 @@
                 {
                   "neighbor-sys-type": "level-1",
                   "neighbor-sysid": "0000.0000.0005",
-                  "neighbor-extended-circuit-id": 0,
                   "hold-timer": 9,
                   "neighbor-priority": 0,
                   "state": "up"
index 9d0c331ff2810262dade2964abc28d89827e9aaa..d430ef5a331a9515e58523c9d895331e2ad7e6bb 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a79406b300a8bf2132e0659b245848c469532f87..be87ed90a0d2b27cd3617a44f8663bfd8f041740 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index e4df0d846e0be47622f61d1586da77378500a4d1..4b204dbc4c1025459d32f287060f9d2276aacd0b 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 970251fe8ac751f91cb0541b6fb78388e0c38446..2c526e74f01a1b064775c56bc5176c4bb1caa9fa 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "16100":{
+    "inLabel":16100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "16101":{
+    "inLabel":16101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index e4df0d846e0be47622f61d1586da77378500a4d1..4b204dbc4c1025459d32f287060f9d2276aacd0b 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a79406b300a8bf2132e0659b245848c469532f87..be87ed90a0d2b27cd3617a44f8663bfd8f041740 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index c200a9f476a7d561c7c1b495fdf927aec3299ac7..4b204dbc4c1025459d32f287060f9d2276aacd0b 100644 (file)
           "ip":"10.0.7.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4",
-          "active":true
+          "active":true,
+          "labels":[
+            16010
+          ]
         },
         {
           "fib":true,
           "ip":"10.0.8.5",
           "afi":"ipv4",
           "interfaceName":"eth-rt5",
-          "active":true
+          "active":true,
+          "labels":[
+            16010
+          ]
         }
       ]
     }
           "ip":"10.0.7.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4",
-          "active":true
+          "active":true,
+          "labels":[
+            16020
+          ]
         }
       ]
     }
           "ip":"10.0.8.5",
           "afi":"ipv4",
           "interfaceName":"eth-rt5",
-          "active":true
+          "active":true,
+          "labels":[
+            16030
+          ]
         }
       ]
     }
           "ip":"10.0.7.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4",
-          "active":true
+          "active":true,
+          "labels":[
+            16040
+          ]
         }
       ]
     }
           "ip":"10.0.8.5",
           "afi":"ipv4",
           "interfaceName":"eth-rt5",
-          "active":true
+          "active":true,
+          "labels":[
+            16050
+          ]
         }
       ]
     }
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index 2bf4b70be84a84f92555ce42a0f7c2281544bb95..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
-          "active":true
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16011
+          ]
         },
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
-          "active":true
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16011
+          ]
         }
       ]
     }
           "fib":true,
           "afi":"ipv6",
           "interfaceName":"eth-rt4",
-          "active":true
+          "active":true,
+          "labels":[
+            16021
+          ]
         }
       ]
     }
           "fib":true,
           "afi":"ipv6",
           "interfaceName":"eth-rt5",
-          "active":true
+          "active":true,
+          "labels":[
+            16031
+          ]
         }
       ]
     }
           "fib":true,
           "afi":"ipv6",
           "interfaceName":"eth-rt4",
-          "active":true
+          "active":true,
+          "labels":[
+            16041
+          ]
         }
       ]
     }
           "fib":true,
           "afi":"ipv6",
           "interfaceName":"eth-rt5",
-          "active":true
+          "active":true,
+          "labels":[
+            16051
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
         }
       ]
     }
index 2c63c0851048d8f7bff41ecf0f8cee05f52fd120..be87ed90a0d2b27cd3617a44f8663bfd8f041740 100644 (file)
@@ -1,2 +1,170 @@
 {
+  "18010":{
+    "inLabel":18010,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18011":{
+    "inLabel":18011,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "18020":{
+    "inLabel":18020,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16020,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18021":{
+    "inLabel":18021,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16021,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "18030":{
+    "inLabel":18030,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16030,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      }
+    ]
+  },
+  "18031":{
+    "inLabel":18031,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16031,
+        "installed":true,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "18040":{
+    "inLabel":18040,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18041":{
+    "inLabel":18041,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "18050":{
+    "inLabel":18050,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      }
+    ]
+  },
+  "18051":{
+    "inLabel":18051,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "installed":true,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
+  }
 }
index e4df0d846e0be47622f61d1586da77378500a4d1..4b204dbc4c1025459d32f287060f9d2276aacd0b 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a79406b300a8bf2132e0659b245848c469532f87..be87ed90a0d2b27cd3617a44f8663bfd8f041740 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index b21e5db9281b5adab1deec471f44dbfd3a199159..178798820740abe67a48cd1f308116d2066a1b23 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index dfbb1954b8abc106dc3fca6d8479873f05c204db..367d0ed1730aa5e12485b8c7a7f8543c335f004d 100644 (file)
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true
         },
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true
         }
       ]
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index 43d771bcbd4cee5321b2d5450443c6ccde542231..b44dda298e23a9749c394a7734f51b35223ddc57 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index e4df0d846e0be47622f61d1586da77378500a4d1..4b204dbc4c1025459d32f287060f9d2276aacd0b 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a79406b300a8bf2132e0659b245848c469532f87..be87ed90a0d2b27cd3617a44f8663bfd8f041740 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index e4df0d846e0be47622f61d1586da77378500a4d1..4b204dbc4c1025459d32f287060f9d2276aacd0b 100644 (file)
         }
       ]
     }
+  ],
+  "10.10.10.10\/32":[
+    {
+      "prefix":"10.10.10.10\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16100
+          ]
+        }
+      ]
+    }
   ]
 }
index eee9dea4d32b15c4130799cf868fad7134ea1ec7..834cdfe6cac5523ffb00cc8b18a9841710d13e88 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
         }
       ]
     }
+  ],
+  "2001:db8:1000::10\/128":[
+    {
+      "prefix":"2001:db8:1000::10\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16101
+          ]
+        }
+      ]
+    }
   ]
 }
index a79406b300a8bf2132e0659b245848c469532f87..be87ed90a0d2b27cd3617a44f8663bfd8f041740 100644 (file)
         "interface":"eth-rt5"
       }
     ]
+  },
+  "18100":{
+    "inLabel":18100,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16100,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "18101":{
+    "inLabel":18101,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16101,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
   }
 }
index d4ebe52bf6f0b2c0c0312a263ed4bd361de3e80f..34eb6d90f69aa1087996ba56b4502a856ade3592 100644 (file)
@@ -73,7 +73,7 @@ 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, '../'))
+sys.path.append(os.path.join(CWD, "../"))
 
 # pylint: disable=C0413
 # Import topogen and topotest helpers
@@ -84,8 +84,10 @@ from lib.topolog import logger
 # Required to instantiate the topology builder class.
 from mininet.topo import Topo
 
+
 class TemplateTopo(Topo):
     "Test topology builder"
+
     def build(self, *_args, **_opts):
         "Build function"
         tgen = get_topogen(self)
@@ -93,44 +95,45 @@ class TemplateTopo(Topo):
         #
         # Define FRR Routers
         #
-        for router in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        for router in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
             tgen.add_router(router)
 
         #
         # Define connections
         #
-        switch = tgen.add_switch('s1')
-        switch.add_link(tgen.gears['rt1'], nodeif="eth-sw1")
-        switch.add_link(tgen.gears['rt2'], nodeif="eth-sw1")
-        switch.add_link(tgen.gears['rt3'], nodeif="eth-sw1")
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["rt1"], nodeif="eth-sw1")
+        switch.add_link(tgen.gears["rt2"], nodeif="eth-sw1")
+        switch.add_link(tgen.gears["rt3"], nodeif="eth-sw1")
+
+        switch = tgen.add_switch("s2")
+        switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-1")
+        switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-1")
 
-        switch = tgen.add_switch('s2')
-        switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-1")
-        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-1")
+        switch = tgen.add_switch("s3")
+        switch.add_link(tgen.gears["rt2"], nodeif="eth-rt4-2")
+        switch.add_link(tgen.gears["rt4"], nodeif="eth-rt2-2")
 
-        switch = tgen.add_switch('s3')
-        switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-2")
-        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-2")
+        switch = tgen.add_switch("s4")
+        switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-1")
+        switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-1")
 
-        switch = tgen.add_switch('s4')
-        switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-1")
-        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-1")
+        switch = tgen.add_switch("s5")
+        switch.add_link(tgen.gears["rt3"], nodeif="eth-rt5-2")
+        switch.add_link(tgen.gears["rt5"], nodeif="eth-rt3-2")
 
-        switch = tgen.add_switch('s5')
-        switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-2")
-        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-2")
+        switch = tgen.add_switch("s6")
+        switch.add_link(tgen.gears["rt4"], nodeif="eth-rt5")
+        switch.add_link(tgen.gears["rt5"], nodeif="eth-rt4")
 
-        switch = tgen.add_switch('s6')
-        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt5")
-        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt4")
+        switch = tgen.add_switch("s7")
+        switch.add_link(tgen.gears["rt4"], nodeif="eth-rt6")
+        switch.add_link(tgen.gears["rt6"], nodeif="eth-rt4")
 
-        switch = tgen.add_switch('s7')
-        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt6")
-        switch.add_link(tgen.gears['rt6'], nodeif="eth-rt4")
+        switch = tgen.add_switch("s8")
+        switch.add_link(tgen.gears["rt5"], nodeif="eth-rt6")
+        switch.add_link(tgen.gears["rt6"], nodeif="eth-rt5")
 
-        switch = tgen.add_switch('s8')
-        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt6")
-        switch.add_link(tgen.gears['rt6'], nodeif="eth-rt5")
 
 def setup_module(mod):
     "Sets up the pytest environment"
@@ -142,16 +145,15 @@ def setup_module(mod):
     # For all registered routers, load the zebra configuration file
     for rname, router in router_list.items():
         router.load_config(
-            TopoRouter.RD_ZEBRA,
-            os.path.join(CWD, '{}/zebra.conf'.format(rname))
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
         )
         router.load_config(
-            TopoRouter.RD_ISIS,
-            os.path.join(CWD, '{}/isisd.conf'.format(rname))
+            TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
         )
 
     tgen.start_router()
 
+
 def teardown_module(mod):
     "Teardown the pytest environment"
     tgen = get_topogen()
@@ -159,22 +161,23 @@ def teardown_module(mod):
     # This function tears down the whole topology.
     tgen.stop_topology()
 
+
 def router_compare_json_output(rname, command, reference):
     "Compare router JSON output"
 
     logger.info('Comparing router "%s" "%s" output', rname, command)
 
     tgen = get_topogen()
-    filename = '{}/{}/{}'.format(CWD, rname, reference)
+    filename = "{}/{}/{}".format(CWD, rname, reference)
     expected = json.loads(open(filename).read())
 
     # Run test function until we get an result. Wait at most 60 seconds.
-    test_func = partial(topotest.router_json_cmp,
-        tgen.gears[rname], command, expected)
+    test_func = partial(topotest.router_json_cmp, tgen.gears[rname], command, expected)
     _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
     assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
     assert diff is None, assertmsg
 
+
 #
 # Step 1
 #
@@ -188,9 +191,13 @@ def test_isis_adjacencies_step1():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step1/show_yang_interface_isis_adjacencies.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step1/show_yang_interface_isis_adjacencies.ref",
+        )
+
 
 def test_rib_ipv4_step1():
     logger.info("Test (step 1): verify IPv4 RIB")
@@ -200,9 +207,11 @@ def test_rib_ipv4_step1():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step1/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step1/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step1():
     logger.info("Test (step 1): verify IPv6 RIB")
@@ -212,9 +221,11 @@ def test_rib_ipv6_step1():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step1/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step1/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step1():
     logger.info("Test (step 1): verify MPLS LIB")
@@ -224,9 +235,11 @@ def test_mpls_lib_step1():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step1/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step1/show_mpls_table.ref"
+        )
+
 
 #
 # Step 2
@@ -252,13 +265,21 @@ def test_isis_adjacencies_step2():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Disabling IS-IS on the eth-rt5 interface on rt4')
-    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no ip router isis 1"')
-    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no ipv6 router isis 1"')
+    logger.info("Disabling IS-IS on the eth-rt5 interface on rt4")
+    tgen.net["rt4"].cmd(
+        'vtysh -c "conf t" -c "interface eth-rt5" -c "no ip router isis 1"'
+    )
+    tgen.net["rt4"].cmd(
+        'vtysh -c "conf t" -c "interface eth-rt5" -c "no ipv6 router isis 1"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step2/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step2/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step2():
     logger.info("Test (step 2): verify IPv4 RIB")
@@ -268,9 +289,11 @@ def test_rib_ipv4_step2():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step2/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step2/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step2():
     logger.info("Test (step 2): verify IPv6 RIB")
@@ -280,9 +303,11 @@ def test_rib_ipv6_step2():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step2/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step2/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step2():
     logger.info("Test (step 2): verify MPLS LIB")
@@ -292,9 +317,11 @@ def test_mpls_lib_step2():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step2/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step2/show_mpls_table.ref"
+        )
+
 
 #
 # Step 3
@@ -318,14 +345,18 @@ def test_isis_adjacencies_step3():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Shutting down the eth-rt4 interface on rt6')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "shutdown"')
-    logger.info('Shutting down the eth-rt5 interface on rt6')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "shutdown"')
+    logger.info("Shutting down the eth-rt4 interface on rt6")
+    tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "shutdown"')
+    logger.info("Shutting down the eth-rt5 interface on rt6")
+    tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "shutdown"')
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step3/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step3/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step3():
     logger.info("Test (step 3): verify IPv4 RIB")
@@ -335,9 +366,11 @@ def test_rib_ipv4_step3():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step3/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step3/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step3():
     logger.info("Test (step 3): verify IPv6 RIB")
@@ -347,9 +380,11 @@ def test_rib_ipv6_step3():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step3/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step3/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step3():
     logger.info("Test (step 3): verify MPLS LIB")
@@ -359,9 +394,11 @@ def test_mpls_lib_step3():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step3/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step3/show_mpls_table.ref"
+        )
+
 
 #
 # Step 4
@@ -386,16 +423,22 @@ def test_isis_adjacencies_step4():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Bringing up the eth-rt4 interface on rt6')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "no shutdown"')
-    logger.info('Bringing up the eth-rt5 interface on rt6')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no shutdown"')
-    logger.info('Changing rt6\'s SRGB')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 18000 25999"')
+    logger.info("Bringing up the eth-rt4 interface on rt6")
+    tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt4" -c "no shutdown"')
+    logger.info("Bringing up the eth-rt5 interface on rt6")
+    tgen.net["rt6"].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "no shutdown"')
+    logger.info("Changing rt6's SRGB")
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 18000 25999"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step4/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step4/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step4():
     logger.info("Test (step 4): verify IPv4 RIB")
@@ -405,9 +448,11 @@ def test_rib_ipv4_step4():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step4/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step4/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step4():
     logger.info("Test (step 4): verify IPv6 RIB")
@@ -417,9 +462,11 @@ def test_rib_ipv6_step4():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step4/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step4/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step4():
     logger.info("Test (step 4): verify MPLS LIB")
@@ -429,9 +476,11 @@ def test_mpls_lib_step4():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step4/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step4/show_mpls_table.ref"
+        )
+
 
 #
 # Step 5
@@ -453,12 +502,18 @@ def test_isis_adjacencies_step5():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Disabling SR on rt6')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing on"')
+    logger.info("Disabling SR on rt6")
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "no segment-routing on"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step5/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step5/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step5():
     logger.info("Test (step 5): verify IPv4 RIB")
@@ -468,9 +523,11 @@ def test_rib_ipv4_step5():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step5/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step5/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step5():
     logger.info("Test (step 5): verify IPv6 RIB")
@@ -480,9 +537,11 @@ def test_rib_ipv6_step5():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step5/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step5/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step5():
     logger.info("Test (step 5): verify MPLS LIB")
@@ -492,9 +551,11 @@ def test_mpls_lib_step5():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step5/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step5/show_mpls_table.ref"
+        )
+
 
 #
 # Step 6
@@ -516,12 +577,16 @@ def test_isis_adjacencies_step6():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Enabling SR on rt6')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing on"')
+    logger.info("Enabling SR on rt6")
+    tgen.net["rt6"].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing on"')
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step6/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step6/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step6():
     logger.info("Test (step 6): verify IPv4 RIB")
@@ -531,9 +596,11 @@ def test_rib_ipv4_step6():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step6/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step6/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step6():
     logger.info("Test (step 6): verify IPv6 RIB")
@@ -543,9 +610,11 @@ def test_rib_ipv6_step6():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step6/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step6/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step6():
     logger.info("Test (step 6): verify MPLS LIB")
@@ -555,9 +624,11 @@ def test_mpls_lib_step6():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step6/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step6/show_mpls_table.ref"
+        )
+
 
 #
 # Step 7
@@ -576,13 +647,21 @@ def test_isis_adjacencies_step7():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Deleting rt1\'s Prefix-SIDs')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 1.1.1.1/32 index 10"')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 2001:db8:1000::1/128 index 11"')
+    logger.info("Deleting rt1's Prefix-SIDs")
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 1.1.1.1/32 index 10"'
+    )
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 2001:db8:1000::1/128 index 11"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step7/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step7/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step7():
     logger.info("Test (step 7): verify IPv4 RIB")
@@ -592,9 +671,11 @@ def test_rib_ipv4_step7():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step7/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step7/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step7():
     logger.info("Test (step 7): verify IPv6 RIB")
@@ -604,9 +685,11 @@ def test_rib_ipv6_step7():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step7/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step7/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step7():
     logger.info("Test (step 7): verify MPLS LIB")
@@ -616,9 +699,11 @@ def test_mpls_lib_step7():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step7/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step7/show_mpls_table.ref"
+        )
+
 
 #
 # Step 8
@@ -637,13 +722,21 @@ def test_isis_adjacencies_step8():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Re-adding rt1\'s Prefix-SIDs')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"')
+    logger.info("Re-adding rt1's Prefix-SIDs")
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"'
+    )
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step8/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step8/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step8():
     logger.info("Test (step 8): verify IPv4 RIB")
@@ -653,9 +746,11 @@ def test_rib_ipv4_step8():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step8/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step8/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step8():
     logger.info("Test (step 8): verify IPv6 RIB")
@@ -665,9 +760,11 @@ def test_rib_ipv6_step8():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step8/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step8/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step8():
     logger.info("Test (step 8): verify MPLS LIB")
@@ -677,9 +774,11 @@ def test_mpls_lib_step8():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step8/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step8/show_mpls_table.ref"
+        )
+
 
 #
 # Step 9
@@ -700,16 +799,28 @@ def test_isis_adjacencies_step9():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Changing rt1\'s Prefix-SIDs to use the no-php option')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10 no-php-flag"')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11 no-php-flag"')
-    logger.info('Change rt6\'s Prefix-SIDs to stop using the explicit-null option')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60"')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61"')
+    logger.info("Changing rt1's Prefix-SIDs to use the no-php option")
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10 no-php-flag"'
+    )
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11 no-php-flag"'
+    )
+    logger.info("Change rt6's Prefix-SIDs to stop using the explicit-null option")
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60"'
+    )
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step9/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step9/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step9():
     logger.info("Test (step 9): verify IPv4 RIB")
@@ -719,9 +830,11 @@ def test_rib_ipv4_step9():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step9/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step9/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step9():
     logger.info("Test (step 9): verify IPv6 RIB")
@@ -731,9 +844,11 @@ def test_rib_ipv6_step9():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step9/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step9/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step9():
     logger.info("Test (step 9): verify MPLS LIB")
@@ -743,9 +858,11 @@ def test_mpls_lib_step9():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step9/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step9/show_mpls_table.ref"
+        )
+
 
 #
 # Step 10
@@ -766,12 +883,18 @@ def test_isis_adjacencies_step10():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Removing the IPv4 address from rt4\'s eth-rt2-1 interface')
-    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt2-1" -c "no ip address 10.0.2.4/24"')
+    logger.info("Removing the IPv4 address from rt4's eth-rt2-1 interface")
+    tgen.net["rt4"].cmd(
+        'vtysh -c "conf t" -c "interface eth-rt2-1" -c "no ip address 10.0.2.4/24"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step10/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step10/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step10():
     logger.info("Test (step 10): verify IPv4 RIB")
@@ -781,9 +904,11 @@ def test_rib_ipv4_step10():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step10/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step10/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step10():
     logger.info("Test (step 10): verify IPv6 RIB")
@@ -793,9 +918,11 @@ def test_rib_ipv6_step10():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step10/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step10/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step10():
     logger.info("Test (step 10): verify MPLS LIB")
@@ -805,9 +932,11 @@ def test_mpls_lib_step10():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step10/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step10/show_mpls_table.ref"
+        )
+
 
 #
 # Step 11
@@ -826,13 +955,26 @@ def test_isis_invalid_config_step11():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Entering invalid Segment Routing configuration...')
-    ret = tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10000"')
-    assert re.search("Configuration failed", ret) is not None, "Invalid SR configuration wasn't rejected"
-    ret = tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 14999"')
-    assert re.search("Configuration failed", ret) is not None, "Invalid SR configuration wasn't rejected"
-    ret = tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 16001"')
-    assert re.search("Configuration failed", ret) is not None, "Invalid SR configuration wasn't rejected"
+    logger.info("Entering invalid Segment Routing configuration...")
+    ret = tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10000"'
+    )
+    assert (
+        re.search("Configuration failed", ret) is not None
+    ), "Invalid SR configuration wasn't rejected"
+    ret = tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 14999"'
+    )
+    assert (
+        re.search("Configuration failed", ret) is not None
+    ), "Invalid SR configuration wasn't rejected"
+    ret = tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 16001"'
+    )
+    assert (
+        re.search("Configuration failed", ret) is not None
+    ), "Invalid SR configuration wasn't rejected"
+
 
 #
 # Step 12
@@ -851,19 +993,39 @@ def test_isis_adjacencies_step12():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    logger.info('Restoring the original network setup')
-    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "ip router isis 1"')
-    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt5" -c "ipv6 router isis 1"')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 23999"')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"')
-    tgen.net['rt1'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60 explicit-null"')
-    tgen.net['rt6'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61 explicit-null"')
-    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "interface eth-rt2-1" -c "ip address 10.0.2.4/24"')
+    logger.info("Restoring the original network setup")
+    tgen.net["rt4"].cmd(
+        'vtysh -c "conf t" -c "interface eth-rt5" -c "ip router isis 1"'
+    )
+    tgen.net["rt4"].cmd(
+        'vtysh -c "conf t" -c "interface eth-rt5" -c "ipv6 router isis 1"'
+    )
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 16000 23999"'
+    )
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 1.1.1.1/32 index 10"'
+    )
+    tgen.net["rt1"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::1/128 index 11"'
+    )
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 6.6.6.6/32 index 60 explicit-null"'
+    )
+    tgen.net["rt6"].cmd(
+        'vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::6/128 index 61 explicit-null"'
+    )
+    tgen.net["rt4"].cmd(
+        'vtysh -c "conf t" -c "interface eth-rt2-1" -c "ip address 10.0.2.4/24"'
+    )
+
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname,
+            "show yang operational-data /frr-interface:lib isisd",
+            "step1/show_yang_interface_isis_adjacencies.ref",
+        )
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
-                                   "step1/show_yang_interface_isis_adjacencies.ref")
 
 def test_rib_ipv4_step12():
     logger.info("Test (step 12): verify IPv4 RIB")
@@ -873,9 +1035,11 @@ def test_rib_ipv4_step12():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ip route isis json",
-                                   "step1/show_ip_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ip route isis json", "step1/show_ip_route.ref"
+        )
+
 
 def test_rib_ipv6_step12():
     logger.info("Test (step 12): verify IPv6 RIB")
@@ -885,9 +1049,11 @@ def test_rib_ipv6_step12():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show ipv6 route isis json",
-                                   "step1/show_ipv6_route.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show ipv6 route isis json", "step1/show_ipv6_route.ref"
+        )
+
 
 def test_mpls_lib_step12():
     logger.info("Test (step 12): verify MPLS LIB")
@@ -897,19 +1063,22 @@ def test_mpls_lib_step12():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
-    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
-        router_compare_json_output(rname, "show mpls table json",
-                                   "step1/show_mpls_table.ref")
+    for rname in ["rt1", "rt2", "rt3", "rt4", "rt5", "rt6"]:
+        router_compare_json_output(
+            rname, "show mpls table json", "step1/show_mpls_table.ref"
+        )
+
 
 # Memory leak test template
 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')
+        pytest.skip("Memory leak test/report is disabled")
 
     tgen.report_memory_leaks()
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
diff --git a/tests/topotests/isis-tilfa-topo1/__init__.py b/tests/topotests/isis-tilfa-topo1/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt1/isisd.conf
new file mode 100644 (file)
index 0000000..a447a2a
--- /dev/null
@@ -0,0 +1,33 @@
+password 1
+hostname rt1
+log file isisd.log
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis sr-events
+debug isis lsp-gen
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-sw1
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis priority 100
+ isis fast-reroute ti-lfa
+!
+router isis 1
+ net 49.0000.0000.0000.0001.00
+ is-type level-1
+ lsp-gen-interval 2
+ topology ipv6-unicast
+ segment-routing on
+ segment-routing global-block 16000 23999
+ segment-routing node-msd 8
+ segment-routing prefix 1.1.1.1/32 index 10
+ segment-routing prefix 2001:db8:1000::1/128 index 11
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..92b7437
--- /dev/null
@@ -0,0 +1,294 @@
+{
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            3
+          ]
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            3
+          ]
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "6.6.6.6\/32":[
+    {
+      "prefix":"6.6.6.6\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":40,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16060
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16060
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.1.0\/24":[
+    {
+      "prefix":"10.0.1.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1"
+        },
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1"
+        }
+      ]
+    }
+  ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.3.0\/24":[
+    {
+      "prefix":"10.0.3.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.4.0\/24":[
+    {
+      "prefix":"10.0.4.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.5.0\/24":[
+    {
+      "prefix":"10.0.5.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.8.0\/24":[
+    {
+      "prefix":"10.0.8.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..3232121
--- /dev/null
@@ -0,0 +1,121 @@
+{
+  "2001:db8:1000::2\/128":[
+    {
+      "prefix":"2001:db8:1000::2\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            3
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::3\/128":[
+    {
+      "prefix":"2001:db8:1000::3\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            3
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::4\/128":[
+    {
+      "prefix":"2001:db8:1000::4\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16041
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::5\/128":[
+    {
+      "prefix":"2001:db8:1000::5\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16051
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::6\/128":[
+    {
+      "prefix":"2001:db8:1000::6\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":40,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16061
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16061
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_mpls_table.ref
new file mode 100644 (file)
index 0000000..e3ed7c2
--- /dev/null
@@ -0,0 +1,134 @@
+{
+  "16020":{
+    "inLabel":16020,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      }
+    ]
+  },
+  "16021":{
+    "inLabel":16021,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16030":{
+    "inLabel":16030,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16031":{
+    "inLabel":16031,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16040":{
+    "inLabel":16040,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      }
+    ]
+  },
+  "16041":{
+    "inLabel":16041,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16050":{
+    "inLabel":16050,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16051":{
+    "inLabel":16051,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16060":{
+    "inLabel":16060,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16060,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16060,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16061":{
+    "inLabel":16061,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16061,
+        "installed":true,
+        "interface":"eth-sw1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16061,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt1/step1/show_yang_interface_isis_adjacencies.ref
new file mode 100644 (file)
index 0000000..26f0dff
--- /dev/null
@@ -0,0 +1,32 @@
+{
+  "frr-interface:lib": {
+    "interface": [
+      {
+        "name": "eth-sw1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0003",
+                  "hold-timer": 9,
+                  "neighbor-priority": 64,
+                  "state": "up"
+                },
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0002",
+                  "hold-timer": 9,
+                  "neighbor-priority": 64,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step2/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step3/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..1a9307d
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step3/show_ip_route.ref        2020-09-25 17:48:05.062911204 -0300
++++ rt1/step4/show_ip_route.ref        2020-09-25 17:49:01.563647190 -0300
+@@ -60,10 +60,7 @@
+           "ip":"10.0.1.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..f5036ae
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step3/show_ipv6_route.ref      2020-09-25 17:48:06.358928078 -0300
++++ rt1/step4/show_ipv6_route.ref      2020-09-25 17:49:02.791663194 -0300
+@@ -57,10 +57,7 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16041
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..30c612b
--- /dev/null
@@ -0,0 +1,33 @@
+--- rt1/step3/show_mpls_table.ref      2020-09-25 17:48:03.782894539 -0300
++++ rt1/step4/show_mpls_table.ref      2020-09-25 17:49:00.343631290 -0300
+@@ -47,30 +47,6 @@
+       }
+     ]
+   },
+-  "16040":{
+-    "inLabel":16040,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "installed":true,
+-        "nexthop":"10.0.1.2"
+-      }
+-    ]
+-  },
+-  "16041":{
+-    "inLabel":16041,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "installed":true,
+-        "interface":"eth-sw1"
+-      }
+-    ]
+-  },
+   "16050":{
+     "inLabel":16050,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..79a452e
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step4/show_ip_route.ref        2020-09-25 17:49:01.563647190 -0300
++++ rt1/step5/show_ip_route.ref        2020-09-25 17:50:12.144567593 -0300
+@@ -60,7 +60,10 @@
+           "ip":"10.0.1.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16040
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..805266a
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step4/show_ipv6_route.ref      2020-09-25 17:49:02.791663194 -0300
++++ rt1/step5/show_ipv6_route.ref      2020-09-25 17:50:13.428584346 -0300
+@@ -57,7 +57,10 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16041
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..d7ab66e
--- /dev/null
@@ -0,0 +1,33 @@
+--- rt1/step4/show_mpls_table.ref      2020-09-25 17:49:00.343631290 -0300
++++ rt1/step5/show_mpls_table.ref      2020-09-25 17:50:10.868550944 -0300
+@@ -47,6 +47,30 @@
+       }
+     ]
+   },
++  "16040":{
++    "inLabel":16040,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "installed":true,
++        "nexthop":"10.0.1.2"
++      }
++    ]
++  },
++  "16041":{
++    "inLabel":16041,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "installed":true,
++        "interface":"eth-sw1"
++      }
++    ]
++  },
+   "16050":{
+     "inLabel":16050,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step6/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..9aa0cd2
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step6/show_ip_route.ref        2020-09-25 17:51:15.105389461 -0300
++++ rt1/step7/show_ip_route.ref        2020-09-25 17:52:02.014002243 -0300
+@@ -83,10 +83,7 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..52fd7ca
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step6/show_ipv6_route.ref      2020-09-25 17:51:16.345405655 -0300
++++ rt1/step7/show_ipv6_route.ref      2020-09-25 17:52:03.230018133 -0300
+@@ -79,10 +79,7 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16051
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..53332be
--- /dev/null
@@ -0,0 +1,33 @@
+--- rt1/step6/show_mpls_table.ref      2020-09-25 17:51:13.861373215 -0300
++++ rt1/step7/show_mpls_table.ref      2020-09-25 17:52:00.769985988 -0300
+@@ -71,30 +71,6 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.1.3"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-sw1"
+-      }
+-    ]
+-  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..af9f72e
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step7/show_ip_route.ref        2020-09-25 17:52:02.014002243 -0300
++++ rt1/step8/show_ip_route.ref        2020-09-25 17:53:20.003021800 -0300
+@@ -83,7 +83,10 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..b733b33
--- /dev/null
@@ -0,0 +1,14 @@
+--- rt1/step7/show_ipv6_route.ref      2020-09-25 17:52:03.230018133 -0300
++++ rt1/step8/show_ipv6_route.ref      2020-09-25 17:53:21.239037966 -0300
+@@ -79,7 +79,10 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16051
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b6f8c96
--- /dev/null
@@ -0,0 +1,33 @@
+--- rt1/step7/show_mpls_table.ref      2020-09-25 17:52:00.769985988 -0300
++++ rt1/step8/show_mpls_table.ref      2020-09-25 17:53:18.671004379 -0300
+@@ -71,6 +71,30 @@
+       }
+     ]
+   },
++  "16050":{
++    "inLabel":16050,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "installed":true,
++        "nexthop":"10.0.1.3"
++      }
++    ]
++  },
++  "16051":{
++    "inLabel":16051,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "installed":true,
++        "interface":"eth-sw1"
++      }
++    ]
++  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..1d96341
--- /dev/null
@@ -0,0 +1,11 @@
+--- rt1/step8/show_ip_route.ref        2020-09-25 17:53:20.003021800 -0300
++++ rt1/step9/show_ip_route.ref        2020-09-25 17:54:37.700038367 -0300
+@@ -85,7 +85,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..232b823
--- /dev/null
@@ -0,0 +1,11 @@
+--- rt1/step8/show_ipv6_route.ref      2020-09-25 17:53:21.239037966 -0300
++++ rt1/step9/show_ipv6_route.ref      2020-09-25 17:54:38.912054230 -0300
+@@ -81,7 +81,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16051
++            16501
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..7f0d50f
--- /dev/null
@@ -0,0 +1,64 @@
+--- rt1/step8/show_mpls_table.ref      2020-09-25 17:53:18.671004379 -0300
++++ rt1/step9/show_mpls_table.ref      2020-09-25 17:54:36.428021718 -0300
+@@ -71,30 +71,6 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.1.3"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-sw1"
+-      }
+-    ]
+-  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
+@@ -129,6 +105,30 @@
+         "installed":true,
+         "interface":"eth-sw1"
+       }
++    ]
++  },
++  "16500":{
++    "inLabel":16500,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16500,
++        "installed":true,
++        "nexthop":"10.0.1.3"
++      }
++    ]
++  },
++  "16501":{
++    "inLabel":16501,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16501,
++        "installed":true,
++        "interface":"eth-sw1"
++      }
+     ]
+   }
+ }
diff --git a/tests/topotests/isis-tilfa-topo1/rt1/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt1/zebra.conf
new file mode 100644 (file)
index 0000000..9d71d30
--- /dev/null
@@ -0,0 +1,19 @@
+log file zebra.log
+!
+hostname rt1
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 1.1.1.1/32
+ ipv6 address 2001:db8:1000::1/128
+!
+interface eth-sw1
+ ip address 10.0.1.1/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt2/isisd.conf
new file mode 100644 (file)
index 0000000..1a756e2
--- /dev/null
@@ -0,0 +1,45 @@
+hostname rt2
+log file isisd.log
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis sr-events
+debug isis lsp-gen
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-sw1
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt4-1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt4-2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+router isis 1
+ net 49.0000.0000.0000.0002.00
+ is-type level-1
+ lsp-gen-interval 2
+ topology ipv6-unicast
+ segment-routing on
+ segment-routing global-block 16000 23999
+ segment-routing node-msd 8
+ segment-routing prefix 2.2.2.2/32 index 20
+ segment-routing prefix 2001:db8:1000::2/128 index 21
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..23e07b7
--- /dev/null
@@ -0,0 +1,560 @@
+{
+  "1.1.1.1\/32":[
+    {
+      "prefix":"1.1.1.1\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.1",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16050,
+            16010
+          ]
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16050,
+            16010
+          ]
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16050,
+            16030
+          ]
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16050,
+            16030
+          ]
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16050,
+            16040
+          ]
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "6.6.6.6\/32":[
+    {
+      "prefix":"6.6.6.6\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16060
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16060
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.1.0\/24":[
+    {
+      "prefix":"10.0.1.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.1.1",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "backupIndex":[
+            0,
+            1
+          ]
+        },
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "backupIndex":[
+            0,
+            1
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.3.0\/24":[
+    {
+      "prefix":"10.0.3.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.4.0\/24":[
+    {
+      "prefix":"10.0.4.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.5.0\/24":[
+    {
+      "prefix":"10.0.5.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.8.0\/24":[
+    {
+      "prefix":"10.0.8.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.2.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-1",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4-2",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..d9bd04e
--- /dev/null
@@ -0,0 +1,226 @@
+{
+  "2001:db8:1000::1\/128":[
+    {
+      "prefix":"2001:db8:1000::1\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16051,
+            16011
+          ]
+        },
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16051,
+            16011
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::3\/128":[
+    {
+      "prefix":"2001:db8:1000::3\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16051,
+            16031
+          ]
+        },
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16051,
+            16031
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::4\/128":[
+    {
+      "prefix":"2001:db8:1000::4\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16051,
+            16041
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::5\/128":[
+    {
+      "prefix":"2001:db8:1000::5\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16051
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "labels":[
+            16051
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "labels":[
+            16051
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::6\/128":[
+    {
+      "prefix":"2001:db8:1000::6\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16061
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16061
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref
new file mode 100644 (file)
index 0000000..cd2f879
--- /dev/null
@@ -0,0 +1,286 @@
+{
+  "16010":{
+    "inLabel":16010,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.1.1",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16011":{
+    "inLabel":16011,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-sw1",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16030":{
+    "inLabel":16030,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.1.3",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "nexthop":"10.0.3.4"
+      }
+    ]
+  },
+  "16031":{
+    "inLabel":16031,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-sw1",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "interface":"eth-rt4-2"
+      }
+    ]
+  },
+  "16040":{
+    "inLabel":16040,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.3.4",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.2.4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16041":{
+    "inLabel":16041,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt4-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt4-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16050":{
+    "inLabel":16050,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "installed":true,
+        "nexthop":"10.0.3.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "installed":true,
+        "nexthop":"10.0.2.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16050,
+        "installed":true,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16051":{
+    "inLabel":16051,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "installed":true,
+        "interface":"eth-rt4-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "installed":true,
+        "interface":"eth-rt4-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16060":{
+    "inLabel":16060,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16060,
+        "installed":true,
+        "nexthop":"10.0.3.4",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16060,
+        "installed":true,
+        "nexthop":"10.0.2.4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.1.3"
+      }
+    ]
+  },
+  "16061":{
+    "inLabel":16061,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16061,
+        "installed":true,
+        "interface":"eth-rt4-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16061,
+        "installed":true,
+        "interface":"eth-rt4-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-sw1"
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt2/step1/show_yang_interface_isis_adjacencies.ref
new file mode 100644 (file)
index 0000000..1ea72a5
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "frr-interface:lib": {
+    "interface": [
+      {
+        "name": "eth-rt4-1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0004",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt4-2",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0004",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-sw1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0001",
+                  "hold-timer": 9,
+                  "neighbor-priority": 100,
+                  "state": "up"
+                },
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0003",
+                  "hold-timer": 9,
+                  "neighbor-priority": 64,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..22b896f
--- /dev/null
@@ -0,0 +1,169 @@
+--- rt2/step1/show_ip_route.ref        2020-09-25 17:46:27.537642781 -0300
++++ rt2/step2/show_ip_route.ref        2020-09-25 17:46:57.306029668 -0300
+@@ -15,36 +15,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16010
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16010
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -64,36 +38,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16030
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16030
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -248,40 +196,12 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
++          "interfaceName":"eth-sw1"
+         },
+         {
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "interfaceName":"eth-sw1"
+         }
+       ]
+     }
+@@ -377,24 +297,6 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+           "active":true
+         }
+       ]
+@@ -415,24 +317,6 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+           "active":true
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..08c7d2b
--- /dev/null
@@ -0,0 +1,72 @@
+--- rt2/step1/show_ipv6_route.ref      2020-09-25 17:46:28.865660035 -0300
++++ rt2/step2/show_ipv6_route.ref      2020-09-25 17:46:58.514045373 -0300
+@@ -14,34 +14,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16011
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16011
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -60,34 +36,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16031
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16031
+-          ]
+-        }
+       ]
+     }
+   ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..4feb927
--- /dev/null
@@ -0,0 +1,102 @@
+--- rt2/step1/show_mpls_table.ref      2020-09-25 17:46:26.261626203 -0300
++++ rt2/step2/show_mpls_table.ref      2020-09-25 17:46:56.086013807 -0300
+@@ -7,23 +7,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.1.1"
+       }
+     ]
+   },
+@@ -35,23 +19,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-2"
++        "interface":"eth-sw1"
+       }
+     ]
+   },
+@@ -63,23 +31,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.3",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.1.3"
+       }
+     ]
+   },
+@@ -91,23 +43,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-2"
++        "interface":"eth-sw1"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..af1cebc
--- /dev/null
@@ -0,0 +1,169 @@
+--- rt2/step2/show_ip_route.ref        2020-09-25 17:46:57.306029668 -0300
++++ rt2/step3/show_ip_route.ref        2020-09-25 17:48:05.274913964 -0300
+@@ -15,10 +15,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050,
++            16010
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050,
++            16010
++          ]
++        }
+       ]
+     }
+   ],
+@@ -38,10 +64,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050,
++            16030
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050,
++            16030
++          ]
++        }
+       ]
+     }
+   ],
+@@ -196,12 +248,40 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
+         },
+         {
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
+@@ -297,6 +377,24 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
++          "active":true,
++          "backupIndex":[
++            0,
++            1
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
+           "active":true
+         }
+       ]
+@@ -317,6 +415,24 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
++          "active":true,
++          "backupIndex":[
++            0,
++            1
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
+           "active":true
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..9809c31
--- /dev/null
@@ -0,0 +1,72 @@
+--- rt2/step2/show_ipv6_route.ref      2020-09-25 17:46:58.514045373 -0300
++++ rt2/step3/show_ipv6_route.ref      2020-09-25 17:48:06.570930838 -0300
+@@ -14,10 +14,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16051,
++            16011
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16051,
++            16011
++          ]
++        }
+       ]
+     }
+   ],
+@@ -36,10 +60,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16051,
++            16031
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16051,
++            16031
++          ]
++        }
+       ]
+     }
+   ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..180323e
--- /dev/null
@@ -0,0 +1,102 @@
+--- rt2/step2/show_mpls_table.ref      2020-09-25 17:46:56.086013807 -0300
++++ rt2/step3/show_mpls_table.ref      2020-09-25 17:48:03.994897300 -0300
+@@ -7,7 +7,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1"
++        "nexthop":"10.0.1.1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.3.4"
+       }
+     ]
+   },
+@@ -19,7 +35,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1"
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-2"
+       }
+     ]
+   },
+@@ -31,7 +63,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.3"
++        "nexthop":"10.0.1.3",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.3.4"
+       }
+     ]
+   },
+@@ -43,7 +91,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1"
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-2"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..12d45bb
--- /dev/null
@@ -0,0 +1,192 @@
+--- rt2/step3/show_ip_route.ref        2020-09-25 17:48:05.274913964 -0300
++++ rt2/step4/show_ip_route.ref        2020-09-25 17:49:01.763649797 -0300
+@@ -15,36 +15,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16010
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16010
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -64,36 +38,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16030
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16030
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -115,9 +63,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         },
+         {
+@@ -128,9 +73,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
+@@ -141,8 +83,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050,
+-            16040
++            16050
+           ]
+         }
+       ]
+@@ -173,20 +114,14 @@
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -209,9 +144,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16060
+           ]
+         },
+         {
+@@ -222,9 +154,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16060
+           ]
+         }
+       ],
+@@ -248,40 +177,12 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
++          "interfaceName":"eth-sw1"
+         },
+         {
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "interfaceName":"eth-sw1"
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..fdf658d
--- /dev/null
@@ -0,0 +1,144 @@
+--- rt2/step3/show_ipv6_route.ref      2020-09-25 17:48:06.570930838 -0300
++++ rt2/step4/show_ipv6_route.ref      2020-09-25 17:49:02.995665853 -0300
+@@ -14,34 +14,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16011
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16011
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -60,34 +36,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16031
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16031
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -108,9 +60,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         },
+         {
+@@ -120,9 +69,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
+@@ -132,8 +78,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16051,
+-            16041
++            16051
+           ]
+         }
+       ]
+@@ -162,19 +107,13 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -196,9 +135,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16061
+           ]
+         },
+         {
+@@ -208,9 +144,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16061
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..a78f79c
--- /dev/null
@@ -0,0 +1,200 @@
+--- rt2/step3/show_mpls_table.ref      2020-09-25 17:48:03.994897300 -0300
++++ rt2/step4/show_mpls_table.ref      2020-09-25 17:49:00.551634001 -0300
+@@ -7,23 +7,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.1.1"
+       }
+     ]
+   },
+@@ -35,23 +19,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-2"
++        "interface":"eth-sw1"
+       }
+     ]
+   },
+@@ -63,23 +31,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.3",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.1.3"
+       }
+     ]
+   },
+@@ -91,84 +43,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-2"
+-      }
+-    ]
+-  },
+-  "16040":{
+-    "inLabel":16040,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.3.4",
+-        "backupIndex":[
+-          0
+-        ]
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.2.4",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.1.3"
+-      }
+-    ]
+-  },
+-  "16041":{
+-    "inLabel":16041,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt4-2",
+-        "backupIndex":[
+-          0
+-        ]
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt4-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+         "interface":"eth-sw1"
+       }
+     ]
+@@ -181,18 +55,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16050,
+         "installed":true,
+-        "nexthop":"10.0.3.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+         "nexthop":"10.0.1.3"
+       }
+     ]
+@@ -204,18 +66,6 @@
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-rt4-2"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+         "installed":true,
+         "interface":"eth-sw1"
+       }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..7d20fad
--- /dev/null
@@ -0,0 +1,192 @@
+--- rt2/step4/show_ip_route.ref        2020-09-25 17:49:01.763649797 -0300
++++ rt2/step5/show_ip_route.ref        2020-09-25 17:50:12.360570411 -0300
+@@ -15,10 +15,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050,
++            16010
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050,
++            16010
++          ]
++        }
+       ]
+     }
+   ],
+@@ -38,10 +64,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050,
++            16030
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050,
++            16030
++          ]
++        }
+       ]
+     }
+   ],
+@@ -63,6 +115,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         },
+         {
+@@ -73,6 +128,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
+@@ -83,7 +141,8 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050
++            16050,
++            16040
+           ]
+         }
+       ]
+@@ -114,14 +173,20 @@
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
+@@ -144,6 +209,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16060
+           ]
+         },
+         {
+@@ -154,6 +222,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16060
+           ]
+         }
+       ],
+@@ -177,12 +248,40 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
+         },
+         {
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..9330964
--- /dev/null
@@ -0,0 +1,144 @@
+--- rt2/step4/show_ipv6_route.ref      2020-09-25 17:49:02.995665853 -0300
++++ rt2/step5/show_ipv6_route.ref      2020-09-25 17:50:13.636587060 -0300
+@@ -14,10 +14,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16051,
++            16011
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16051,
++            16011
++          ]
++        }
+       ]
+     }
+   ],
+@@ -36,10 +60,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16051,
++            16031
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16051,
++            16031
++          ]
++        }
+       ]
+     }
+   ],
+@@ -60,6 +108,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         },
+         {
+@@ -69,6 +120,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
+@@ -78,7 +132,8 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16051
++            16051,
++            16041
+           ]
+         }
+       ]
+@@ -107,13 +162,19 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-2",
+-          "active":true
++          "active":true,
++          "labels":[
++            16051
++          ]
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16051
++          ]
+         }
+       ]
+     }
+@@ -135,6 +196,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16061
+           ]
+         },
+         {
+@@ -144,6 +208,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16061
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b1e44a7
--- /dev/null
@@ -0,0 +1,200 @@
+--- rt2/step4/show_mpls_table.ref      2020-09-25 17:49:00.551634001 -0300
++++ rt2/step5/show_mpls_table.ref      2020-09-25 17:50:11.068553553 -0300
+@@ -7,7 +7,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1"
++        "nexthop":"10.0.1.1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.3.4"
+       }
+     ]
+   },
+@@ -19,7 +35,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1"
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-2"
+       }
+     ]
+   },
+@@ -31,7 +63,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.3"
++        "nexthop":"10.0.1.3",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.3.4"
+       }
+     ]
+   },
+@@ -43,6 +91,84 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-2"
++      }
++    ]
++  },
++  "16040":{
++    "inLabel":16040,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.3.4",
++        "backupIndex":[
++          0
++        ]
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.2.4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.1.3"
++      }
++    ]
++  },
++  "16041":{
++    "inLabel":16041,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt4-2",
++        "backupIndex":[
++          0
++        ]
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt4-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
+         "interface":"eth-sw1"
+       }
+     ]
+@@ -55,6 +181,18 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16050,
+         "installed":true,
++        "nexthop":"10.0.3.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "installed":true,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "installed":true,
+         "nexthop":"10.0.1.3"
+       }
+     ]
+@@ -66,6 +204,18 @@
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16051,
++        "installed":true,
++        "interface":"eth-rt4-2"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "installed":true,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
+         "installed":true,
+         "interface":"eth-sw1"
+       }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step6/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..c92195d
--- /dev/null
@@ -0,0 +1,288 @@
+--- rt2/step6/show_ip_route.ref        2020-09-25 17:51:15.313392177 -0300
++++ rt2/step7/show_ip_route.ref        2020-09-25 17:52:02.210004805 -0300
+@@ -15,36 +15,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16010
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16010
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -64,36 +38,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16030
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16030
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -113,9 +61,6 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -126,25 +71,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.3",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16050,
+-            16040
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -163,30 +93,21 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -248,40 +169,12 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
++          "interfaceName":"eth-sw1"
+         },
+         {
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.2.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
+-        },
+-        {
+-          "ip":"10.0.3.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "interfaceName":"eth-sw1"
+         }
+       ]
+     }
+@@ -296,30 +189,13 @@
+         {
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1",
+-          "backupIndex":[
+-            0
+-          ]
++          "interfaceName":"eth-rt4-1"
+         },
+         {
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.3",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -335,29 +211,12 @@
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2",
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.3",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "interfaceName":"eth-rt4-2"
+         }
+       ]
+     }
+@@ -494,31 +353,14 @@
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.3",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..140c7b0
--- /dev/null
@@ -0,0 +1,139 @@
+--- rt2/step6/show_ipv6_route.ref      2020-09-25 17:51:16.549408319 -0300
++++ rt2/step7/show_ipv6_route.ref      2020-09-25 17:52:03.438020851 -0300
+@@ -14,34 +14,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16011
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16011
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -60,34 +36,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16031
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16031
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -106,9 +58,6 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -118,24 +67,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16051,
+-            16041
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -153,28 +88,19 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16051
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-2",
+-          "active":true,
+-          "labels":[
+-            16051
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-1",
+-          "active":true,
+-          "labels":[
+-            16051
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..f8476cd
--- /dev/null
@@ -0,0 +1,207 @@
+--- rt2/step6/show_mpls_table.ref      2020-09-25 17:51:14.073375985 -0300
++++ rt2/step7/show_mpls_table.ref      2020-09-25 17:52:00.973988653 -0300
+@@ -7,23 +7,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.1.1"
+       }
+     ]
+   },
+@@ -35,23 +19,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-2"
++        "interface":"eth-sw1"
+       }
+     ]
+   },
+@@ -63,23 +31,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.3",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.1.3"
+       }
+     ]
+   },
+@@ -91,23 +43,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-rt4-2"
++        "interface":"eth-sw1"
+       }
+     ]
+   },
+@@ -119,26 +55,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.3.4",
+-        "backupIndex":[
+-          0
+-        ]
++        "nexthop":"10.0.3.4"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.2.4",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "nexthop":"10.0.1.3"
++        "nexthop":"10.0.2.4"
+       }
+     ]
+   },
+@@ -150,74 +73,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt4-2",
+-        "backupIndex":[
+-          0
+-        ]
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt4-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-sw1"
+-      }
+-    ]
+-  },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.3.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.1.3"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+         "interface":"eth-rt4-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16051,
++        "outLabel":3,
+         "installed":true,
+         "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-sw1"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..7d5237e
--- /dev/null
@@ -0,0 +1,288 @@
+--- rt2/step7/show_ip_route.ref        2020-09-25 17:52:02.210004805 -0300
++++ rt2/step8/show_ip_route.ref        2020-09-25 17:53:20.207024469 -0300
+@@ -15,10 +15,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050,
++            16010
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050,
++            16010
++          ]
++        }
+       ]
+     }
+   ],
+@@ -38,10 +64,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050,
++            16030
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050,
++            16030
++          ]
++        }
+       ]
+     }
+   ],
+@@ -61,6 +113,9 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -71,10 +126,25 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.3",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16050,
++            16040
++          ]
++        }
+       ]
+     }
+   ],
+@@ -93,21 +163,30 @@
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
+@@ -169,12 +248,40 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
+         },
+         {
+           "ip":"10.0.1.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.2.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16050
++          ]
++        },
++        {
++          "ip":"10.0.3.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
+@@ -189,13 +296,30 @@
+         {
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt4-1"
++          "interfaceName":"eth-rt4-1",
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.3",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
+@@ -211,12 +335,29 @@
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt4-2"
++          "interfaceName":"eth-rt4-2",
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.3",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
+@@ -353,14 +494,31 @@
+           "ip":"10.0.2.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4-2",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.3",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16050
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..4532221
--- /dev/null
@@ -0,0 +1,139 @@
+--- rt2/step7/show_ipv6_route.ref      2020-09-25 17:52:03.438020851 -0300
++++ rt2/step8/show_ipv6_route.ref      2020-09-25 17:53:21.443040633 -0300
+@@ -14,10 +14,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16051,
++            16011
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16051,
++            16011
++          ]
++        }
+       ]
+     }
+   ],
+@@ -36,10 +60,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-1",
++          "active":true,
++          "labels":[
++            16051,
++            16031
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4-2",
++          "active":true,
++          "labels":[
++            16051,
++            16031
++          ]
++        }
+       ]
+     }
+   ],
+@@ -58,6 +106,9 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -67,10 +118,24 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16051,
++            16041
++          ]
++        }
+       ]
+     }
+   ],
+@@ -88,19 +153,28 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16051
++          ]
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-2",
+-          "active":true
++          "active":true,
++          "labels":[
++            16051
++          ]
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4-1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16051
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..083c647
--- /dev/null
@@ -0,0 +1,207 @@
+--- rt2/step7/show_mpls_table.ref      2020-09-25 17:52:00.973988653 -0300
++++ rt2/step8/show_mpls_table.ref      2020-09-25 17:53:18.923007676 -0300
+@@ -7,7 +7,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1"
++        "nexthop":"10.0.1.1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.3.4"
+       }
+     ]
+   },
+@@ -19,7 +35,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1"
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-2"
+       }
+     ]
+   },
+@@ -31,7 +63,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.3"
++        "nexthop":"10.0.1.3",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.3.4"
+       }
+     ]
+   },
+@@ -43,7 +91,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1"
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-rt4-2"
+       }
+     ]
+   },
+@@ -55,13 +119,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.3.4"
++        "nexthop":"10.0.3.4",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.2.4"
++        "nexthop":"10.0.2.4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.1.3"
+       }
+     ]
+   },
+@@ -73,13 +150,74 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt4-2"
++        "interface":"eth-rt4-2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
++        "interface":"eth-rt4-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "interface":"eth-sw1"
++      }
++    ]
++  },
++  "16050":{
++    "inLabel":16050,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "installed":true,
++        "nexthop":"10.0.3.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "installed":true,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "installed":true,
++        "nexthop":"10.0.1.3"
++      }
++    ]
++  },
++  "16051":{
++    "inLabel":16051,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "installed":true,
++        "interface":"eth-rt4-2"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "installed":true,
+         "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
++        "installed":true,
++        "interface":"eth-sw1"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..15370a0
--- /dev/null
@@ -0,0 +1,119 @@
+--- rt2/step8/show_ip_route.ref        2020-09-25 17:53:20.207024469 -0300
++++ rt2/step9/show_ip_route.ref        2020-09-25 17:54:37.908041089 -0300
+@@ -31,7 +31,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16050,
++            16500,
+             16010
+           ]
+         },
+@@ -41,7 +41,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16050,
++            16500,
+             16010
+           ]
+         }
+@@ -80,7 +80,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16050,
++            16500,
+             16030
+           ]
+         },
+@@ -90,7 +90,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16050,
++            16500,
+             16030
+           ]
+         }
+@@ -141,7 +141,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050,
++            16500,
+             16040
+           ]
+         }
+@@ -165,7 +165,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         },
+         {
+@@ -175,7 +175,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         },
+         {
+@@ -185,7 +185,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         }
+       ]
+@@ -271,7 +271,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         },
+         {
+@@ -280,7 +280,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         }
+       ]
+@@ -318,7 +318,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         }
+       ]
+@@ -356,7 +356,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         }
+       ]
+@@ -517,7 +517,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..2585f32
--- /dev/null
@@ -0,0 +1,74 @@
+--- rt2/step8/show_ipv6_route.ref      2020-09-25 17:53:21.443040633 -0300
++++ rt2/step9/show_ipv6_route.ref      2020-09-25 17:54:39.112056848 -0300
+@@ -29,7 +29,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16051,
++            16501,
+             16011
+           ]
+         },
+@@ -38,7 +38,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16051,
++            16501,
+             16011
+           ]
+         }
+@@ -75,7 +75,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16051,
++            16501,
+             16031
+           ]
+         },
+@@ -84,7 +84,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16051,
++            16501,
+             16031
+           ]
+         }
+@@ -132,7 +132,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16051,
++            16501,
+             16041
+           ]
+         }
+@@ -155,7 +155,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16051
++            16501
+           ]
+         },
+         {
+@@ -164,7 +164,7 @@
+           "interfaceName":"eth-rt4-2",
+           "active":true,
+           "labels":[
+-            16051
++            16501
+           ]
+         },
+         {
+@@ -173,7 +173,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16051
++            16501
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b90b889
--- /dev/null
@@ -0,0 +1,182 @@
+--- rt2/step8/show_mpls_table.ref      2020-09-25 17:53:18.923007676 -0300
++++ rt2/step9/show_mpls_table.ref      2020-09-25 17:54:36.640024493 -0300
+@@ -17,12 +17,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16050,
++        "outLabel":16500,
+         "nexthop":"10.0.2.4"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16050,
++        "outLabel":16500,
+         "nexthop":"10.0.3.4"
+       }
+     ]
+@@ -45,12 +45,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16051,
++        "outLabel":16501,
+         "interface":"eth-rt4-1"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16051,
++        "outLabel":16501,
+         "interface":"eth-rt4-2"
+       }
+     ]
+@@ -73,12 +73,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16050,
++        "outLabel":16500,
+         "nexthop":"10.0.2.4"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16050,
++        "outLabel":16500,
+         "nexthop":"10.0.3.4"
+       }
+     ]
+@@ -101,12 +101,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16051,
++        "outLabel":16501,
+         "interface":"eth-rt4-1"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16051,
++        "outLabel":16501,
+         "interface":"eth-rt4-2"
+       }
+     ]
+@@ -137,7 +137,7 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16050,
++        "outLabel":16500,
+         "nexthop":"10.0.1.3"
+       }
+     ]
+@@ -168,55 +168,7 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "interface":"eth-sw1"
+-      }
+-    ]
+-  },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.3.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.2.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16050,
+-        "installed":true,
+-        "nexthop":"10.0.1.3"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-rt4-2"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
+-        "interface":"eth-rt4-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+-        "installed":true,
++        "outLabel":16501,
+         "interface":"eth-sw1"
+       }
+     ]
+@@ -282,5 +234,53 @@
+         "interface":"eth-sw1"
+       }
+     ]
++  },
++  "16500":{
++    "inLabel":16500,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16500,
++        "installed":true,
++        "nexthop":"10.0.3.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16500,
++        "installed":true,
++        "nexthop":"10.0.2.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16500,
++        "installed":true,
++        "nexthop":"10.0.1.3"
++      }
++    ]
++  },
++  "16501":{
++    "inLabel":16501,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16501,
++        "installed":true,
++        "interface":"eth-rt4-2"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16501,
++        "installed":true,
++        "interface":"eth-rt4-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16501,
++        "installed":true,
++        "interface":"eth-sw1"
++      }
++    ]
+   }
+ }
diff --git a/tests/topotests/isis-tilfa-topo1/rt2/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt2/zebra.conf
new file mode 100644 (file)
index 0000000..dcb0686
--- /dev/null
@@ -0,0 +1,25 @@
+log file zebra.log
+!
+hostname rt2
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 2.2.2.2/32
+ ipv6 address 2001:db8:1000::2/128
+!
+interface eth-sw1
+ ip address 10.0.1.2/24
+!
+interface eth-rt4-1
+ ip address 10.0.2.2/24
+!
+interface eth-rt4-2
+ ip address 10.0.3.2/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt3/isisd.conf
new file mode 100644 (file)
index 0000000..986bf28
--- /dev/null
@@ -0,0 +1,45 @@
+hostname rt3
+log file isisd.log
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis sr-events
+debug isis lsp-gen
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-sw1
+ ip router isis 1
+ ipv6 router isis 1
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt5-1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt5-2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+router isis 1
+ net 49.0000.0000.0000.0003.00
+ is-type level-1
+ lsp-gen-interval 2
+ topology ipv6-unicast
+ segment-routing on
+ segment-routing global-block 16000 23999
+ segment-routing node-msd 8
+ segment-routing prefix 3.3.3.3/32 index 30
+ segment-routing prefix 2001:db8:1000::3/128 index 31
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..8c37180
--- /dev/null
@@ -0,0 +1,560 @@
+{
+  "1.1.1.1\/32":[
+    {
+      "prefix":"1.1.1.1\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.1",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16040,
+            16010
+          ]
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16040,
+            16010
+          ]
+        }
+      ]
+    }
+  ],
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16040,
+            16020
+          ]
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16040,
+            16020
+          ]
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16040,
+            16050
+          ]
+        }
+      ]
+    }
+  ],
+  "6.6.6.6\/32":[
+    {
+      "prefix":"6.6.6.6\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16060
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16060
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.1.0\/24":[
+    {
+      "prefix":"10.0.1.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.1.1",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "backupIndex":[
+            0,
+            1
+          ]
+        },
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "backupIndex":[
+            0,
+            1
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.3.0\/24":[
+    {
+      "prefix":"10.0.3.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.4.0\/24":[
+    {
+      "prefix":"10.0.4.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.5.0\/24":[
+    {
+      "prefix":"10.0.5.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.8.0\/24":[
+    {
+      "prefix":"10.0.8.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16040
+          ]
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..5ddb24a
--- /dev/null
@@ -0,0 +1,226 @@
+{
+  "2001:db8:1000::1\/128":[
+    {
+      "prefix":"2001:db8:1000::1\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16041,
+            16011
+          ]
+        },
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16041,
+            16011
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::2\/128":[
+    {
+      "prefix":"2001:db8:1000::2\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "backupIndex":[
+            0,
+            1
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16041,
+            16021
+          ]
+        },
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16041,
+            16021
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::4\/128":[
+    {
+      "prefix":"2001:db8:1000::4\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16041
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16041
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16041
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::5\/128":[
+    {
+      "prefix":"2001:db8:1000::5\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16041,
+            16051
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::6\/128":[
+    {
+      "prefix":"2001:db8:1000::6\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16061
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16061
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref
new file mode 100644 (file)
index 0000000..f68d1f4
--- /dev/null
@@ -0,0 +1,286 @@
+{
+  "16010":{
+    "inLabel":16010,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.1.1",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "nexthop":"10.0.4.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "nexthop":"10.0.5.5"
+      }
+    ]
+  },
+  "16011":{
+    "inLabel":16011,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-sw1",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "interface":"eth-rt5-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "interface":"eth-rt5-2"
+      }
+    ]
+  },
+  "16020":{
+    "inLabel":16020,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.1.2",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "nexthop":"10.0.4.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "nexthop":"10.0.5.5"
+      }
+    ]
+  },
+  "16021":{
+    "inLabel":16021,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-sw1",
+        "backupIndex":[
+          0,
+          1
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "interface":"eth-rt5-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "interface":"eth-rt5-2"
+      }
+    ]
+  },
+  "16040":{
+    "inLabel":16040,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "installed":true,
+        "nexthop":"10.0.5.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "installed":true,
+        "nexthop":"10.0.4.5"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "installed":true,
+        "nexthop":"10.0.1.2"
+      }
+    ]
+  },
+  "16041":{
+    "inLabel":16041,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "installed":true,
+        "interface":"eth-rt5-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "installed":true,
+        "interface":"eth-rt5-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "installed":true,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16050":{
+    "inLabel":16050,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.5.5",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.4.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "nexthop":"10.0.1.2"
+      }
+    ]
+  },
+  "16051":{
+    "inLabel":16051,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt5-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt5-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "interface":"eth-sw1"
+      }
+    ]
+  },
+  "16060":{
+    "inLabel":16060,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16060,
+        "installed":true,
+        "nexthop":"10.0.5.5",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16060,
+        "installed":true,
+        "nexthop":"10.0.4.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.1.2"
+      }
+    ]
+  },
+  "16061":{
+    "inLabel":16061,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16061,
+        "installed":true,
+        "interface":"eth-rt5-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16061,
+        "installed":true,
+        "interface":"eth-rt5-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-sw1"
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt3/step1/show_yang_interface_isis_adjacencies.ref
new file mode 100644 (file)
index 0000000..d174b4a
--- /dev/null
@@ -0,0 +1,70 @@
+{
+  "frr-interface:lib": {
+    "interface": [
+      {
+        "name": "eth-rt5-1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0005",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt5-2",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0005",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-sw1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0001",
+                  "hold-timer": 9,
+                  "neighbor-priority": 100,
+                  "state": "up"
+                },
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0002",
+                  "hold-timer": 9,
+                  "neighbor-priority": 64,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step2/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step3/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..707f954
--- /dev/null
@@ -0,0 +1,288 @@
+--- rt3/step3/show_ip_route.ref        2020-09-25 17:48:05.506916984 -0300
++++ rt3/step4/show_ip_route.ref        2020-09-25 17:49:01.963652403 -0300
+@@ -15,36 +15,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.4.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16040,
+-            16010
+-          ]
+-        },
+-        {
+-          "ip":"10.0.5.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16040,
+-            16010
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -64,36 +38,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.4.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16040,
+-            16020
+-          ]
+-        },
+-        {
+-          "ip":"10.0.5.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16040,
+-            16020
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -112,30 +60,21 @@
+           "ip":"10.0.1.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -156,9 +95,6 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -169,25 +105,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16040,
+-            16050
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -248,40 +169,12 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
++          "interfaceName":"eth-sw1"
+         },
+         {
+           "ip":"10.0.1.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "backupIndex":[
+-            0,
+-            1
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.4.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
+-        },
+-        {
+-          "ip":"10.0.5.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "interfaceName":"eth-sw1"
+         }
+       ]
+     }
+@@ -372,30 +265,13 @@
+         {
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt5-1",
+-          "backupIndex":[
+-            0
+-          ]
++          "interfaceName":"eth-rt5-1"
+         },
+         {
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -411,29 +287,12 @@
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt5-2",
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "interfaceName":"eth-rt5-2"
+         }
+       ]
+     }
+@@ -528,31 +387,14 @@
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.1.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..76d0ebc
--- /dev/null
@@ -0,0 +1,139 @@
+--- rt3/step3/show_ipv6_route.ref      2020-09-25 17:48:06.790933702 -0300
++++ rt3/step4/show_ipv6_route.ref      2020-09-25 17:49:03.199668512 -0300
+@@ -14,34 +14,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16041,
+-            16011
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16041,
+-            16011
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -60,34 +36,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
+-          "backupIndex":[
+-            0,
+-            1
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16041,
+-            16021
+-          ]
+-        },
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16041,
+-            16021
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -105,28 +57,19 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16041
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-2",
+-          "active":true,
+-          "labels":[
+-            16041
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16041
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -146,9 +89,6 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -158,24 +98,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-sw1",
+-          "active":true,
+-          "labels":[
+-            16041,
+-            16051
+-          ]
+-        }
+       ]
+     }
+   ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b888c9d
--- /dev/null
@@ -0,0 +1,206 @@
+--- rt3/step3/show_mpls_table.ref      2020-09-25 17:48:04.214900164 -0300
++++ rt3/step4/show_mpls_table.ref      2020-09-25 17:49:00.759636711 -0300
+@@ -7,23 +7,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.4.5"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.5.5"
++        "nexthop":"10.0.1.1"
+       }
+     ]
+   },
+@@ -35,23 +19,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-rt5-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-rt5-2"
++        "interface":"eth-sw1"
+       }
+     ]
+   },
+@@ -63,23 +31,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.2",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.4.5"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.5.5"
++        "nexthop":"10.0.1.2"
+       }
+     ]
+   },
+@@ -91,70 +43,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1",
+-        "backupIndex":[
+-          0,
+-          1
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-rt5-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-rt5-2"
+-      }
+-    ]
+-  },
+-  "16040":{
+-    "inLabel":16040,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "installed":true,
+-        "nexthop":"10.0.5.5"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "installed":true,
+-        "nexthop":"10.0.4.5"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "installed":true,
+-        "nexthop":"10.0.1.2"
+-      }
+-    ]
+-  },
+-  "16041":{
+-    "inLabel":16041,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "installed":true,
+-        "interface":"eth-rt5-2"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "installed":true,
+-        "interface":"eth-rt5-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "installed":true,
+         "interface":"eth-sw1"
+       }
+     ]
+@@ -167,26 +55,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.5.5",
+-        "backupIndex":[
+-          0
+-        ]
++        "nexthop":"10.0.5.5"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.4.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.1.2"
++        "nexthop":"10.0.4.5"
+       }
+     ]
+   },
+@@ -198,26 +73,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5-2",
+-        "backupIndex":[
+-          0
+-        ]
++        "interface":"eth-rt5-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-sw1"
++        "interface":"eth-rt5-1"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..8eac75b
--- /dev/null
@@ -0,0 +1,288 @@
+--- rt3/step4/show_ip_route.ref        2020-09-25 17:49:01.963652403 -0300
++++ rt3/step5/show_ip_route.ref        2020-09-25 17:50:12.592573438 -0300
+@@ -15,10 +15,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.4.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5-1",
++          "active":true,
++          "labels":[
++            16040,
++            16010
++          ]
++        },
++        {
++          "ip":"10.0.5.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5-2",
++          "active":true,
++          "labels":[
++            16040,
++            16010
++          ]
++        }
+       ]
+     }
+   ],
+@@ -38,10 +64,36 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.4.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5-1",
++          "active":true,
++          "labels":[
++            16040,
++            16020
++          ]
++        },
++        {
++          "ip":"10.0.5.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5-2",
++          "active":true,
++          "labels":[
++            16040,
++            16020
++          ]
++        }
+       ]
+     }
+   ],
+@@ -60,21 +112,30 @@
+           "ip":"10.0.1.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16040
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16040
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+-          "active":true
++          "active":true,
++          "labels":[
++            16040
++          ]
+         }
+       ]
+     }
+@@ -95,6 +156,9 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -105,10 +169,25 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16040,
++            16050
++          ]
++        }
+       ]
+     }
+   ],
+@@ -169,12 +248,40 @@
+         {
+           "ip":"10.0.1.1",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
+         },
+         {
+           "ip":"10.0.1.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-sw1"
++          "interfaceName":"eth-sw1",
++          "backupIndex":[
++            0,
++            1
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.4.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5-1",
++          "active":true,
++          "labels":[
++            16040
++          ]
++        },
++        {
++          "ip":"10.0.5.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5-2",
++          "active":true,
++          "labels":[
++            16040
++          ]
+         }
+       ]
+     }
+@@ -265,13 +372,30 @@
+         {
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt5-1"
++          "interfaceName":"eth-rt5-1",
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16040
++          ]
+         }
+       ]
+     }
+@@ -287,12 +411,29 @@
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt5-2"
++          "interfaceName":"eth-rt5-2",
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16040
++          ]
+         }
+       ]
+     }
+@@ -387,14 +528,31 @@
+           "ip":"10.0.4.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.5.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5-2",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.1.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16040
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..fc55267
--- /dev/null
@@ -0,0 +1,139 @@
+--- rt3/step4/show_ipv6_route.ref      2020-09-25 17:49:03.199668512 -0300
++++ rt3/step5/show_ipv6_route.ref      2020-09-25 17:50:13.840589722 -0300
+@@ -14,10 +14,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5-1",
++          "active":true,
++          "labels":[
++            16041,
++            16011
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5-2",
++          "active":true,
++          "labels":[
++            16041,
++            16011
++          ]
++        }
+       ]
+     }
+   ],
+@@ -36,10 +60,34 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+           "active":true,
++          "backupIndex":[
++            0,
++            1
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5-1",
++          "active":true,
++          "labels":[
++            16041,
++            16021
++          ]
++        },
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5-2",
++          "active":true,
++          "labels":[
++            16041,
++            16021
++          ]
++        }
+       ]
+     }
+   ],
+@@ -57,19 +105,28 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-sw1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16041
++          ]
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-2",
+-          "active":true
++          "active":true,
++          "labels":[
++            16041
++          ]
+         },
+         {
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-1",
+-          "active":true
++          "active":true,
++          "labels":[
++            16041
++          ]
+         }
+       ]
+     }
+@@ -89,6 +146,9 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -98,10 +158,24 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-sw1",
++          "active":true,
++          "labels":[
++            16041,
++            16051
++          ]
++        }
+       ]
+     }
+   ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..4ed491e
--- /dev/null
@@ -0,0 +1,206 @@
+--- rt3/step4/show_mpls_table.ref      2020-09-25 17:49:00.759636711 -0300
++++ rt3/step5/show_mpls_table.ref      2020-09-25 17:50:11.280556320 -0300
+@@ -7,7 +7,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.1"
++        "nexthop":"10.0.1.1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.4.5"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.5.5"
+       }
+     ]
+   },
+@@ -19,7 +35,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-sw1"
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-rt5-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-rt5-2"
+       }
+     ]
+   },
+@@ -31,7 +63,23 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.1.2"
++        "nexthop":"10.0.1.2",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.4.5"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.5.5"
+       }
+     ]
+   },
+@@ -43,6 +91,70 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
++        "interface":"eth-sw1",
++        "backupIndex":[
++          0,
++          1
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-rt5-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-rt5-2"
++      }
++    ]
++  },
++  "16040":{
++    "inLabel":16040,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "installed":true,
++        "nexthop":"10.0.5.5"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "installed":true,
++        "nexthop":"10.0.4.5"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "installed":true,
++        "nexthop":"10.0.1.2"
++      }
++    ]
++  },
++  "16041":{
++    "inLabel":16041,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "installed":true,
++        "interface":"eth-rt5-2"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "installed":true,
++        "interface":"eth-rt5-1"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "installed":true,
+         "interface":"eth-sw1"
+       }
+     ]
+@@ -55,13 +167,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.5.5"
++        "nexthop":"10.0.5.5",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.4.5"
++        "nexthop":"10.0.4.5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.1.2"
+       }
+     ]
+   },
+@@ -73,13 +198,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5-2"
++        "interface":"eth-rt5-2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5-1"
++        "interface":"eth-rt5-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-sw1"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..9273c75
--- /dev/null
@@ -0,0 +1,101 @@
+--- rt3/step5/show_ip_route.ref        2020-09-25 17:50:12.592573438 -0300
++++ rt3/step6/show_ip_route.ref        2020-09-25 17:51:15.521394894 -0300
+@@ -31,7 +31,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16040,
++            30040,
+             16010
+           ]
+         },
+@@ -41,7 +41,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16040,
++            30040,
+             16010
+           ]
+         }
+@@ -80,7 +80,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16040,
++            30040,
+             16020
+           ]
+         },
+@@ -90,7 +90,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16040,
++            30040,
+             16020
+           ]
+         }
+@@ -124,7 +124,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16040
++            30040
+           ]
+         },
+         {
+@@ -134,7 +134,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16040
++            30040
+           ]
+         }
+       ]
+@@ -185,7 +185,7 @@
+           "active":true,
+           "labels":[
+             16040,
+-            16050
++            30050
+           ]
+         }
+       ]
+@@ -211,7 +211,7 @@
+             0
+           ],
+           "labels":[
+-            16060
++            30060
+           ]
+         },
+         {
+@@ -224,7 +224,7 @@
+             0
+           ],
+           "labels":[
+-            16060
++            30060
+           ]
+         }
+       ],
+@@ -271,7 +271,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16040
++            30040
+           ]
+         },
+         {
+@@ -280,7 +280,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16040
++            30040
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..f50be89
--- /dev/null
@@ -0,0 +1,83 @@
+--- rt3/step5/show_ipv6_route.ref      2020-09-25 17:50:13.840589722 -0300
++++ rt3/step6/show_ipv6_route.ref      2020-09-25 17:51:16.757411035 -0300
+@@ -29,7 +29,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16041,
++            30041,
+             16011
+           ]
+         },
+@@ -38,7 +38,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16041,
++            30041,
+             16011
+           ]
+         }
+@@ -75,7 +75,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16041,
++            30041,
+             16021
+           ]
+         },
+@@ -84,7 +84,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16041,
++            30041,
+             16021
+           ]
+         }
+@@ -116,7 +116,7 @@
+           "interfaceName":"eth-rt5-2",
+           "active":true,
+           "labels":[
+-            16041
++            30041
+           ]
+         },
+         {
+@@ -125,7 +125,7 @@
+           "interfaceName":"eth-rt5-1",
+           "active":true,
+           "labels":[
+-            16041
++            30041
+           ]
+         }
+       ]
+@@ -173,7 +173,7 @@
+           "active":true,
+           "labels":[
+             16041,
+-            16051
++            30051
+           ]
+         }
+       ]
+@@ -198,7 +198,7 @@
+             0
+           ],
+           "labels":[
+-            16061
++            30061
+           ]
+         },
+         {
+@@ -210,7 +210,7 @@
+             0
+           ],
+           "labels":[
+-            16061
++            30061
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b63a728
--- /dev/null
@@ -0,0 +1,130 @@
+--- rt3/step5/show_mpls_table.ref      2020-09-25 17:50:11.280556320 -0300
++++ rt3/step6/show_mpls_table.ref      2020-09-25 17:51:14.281378700 -0300
+@@ -17,12 +17,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":30040,
+         "nexthop":"10.0.4.5"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":30040,
+         "nexthop":"10.0.5.5"
+       }
+     ]
+@@ -45,12 +45,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":30041,
+         "interface":"eth-rt5-1"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":30041,
+         "interface":"eth-rt5-2"
+       }
+     ]
+@@ -73,12 +73,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":30040,
+         "nexthop":"10.0.4.5"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":30040,
+         "nexthop":"10.0.5.5"
+       }
+     ]
+@@ -101,12 +101,12 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":30041,
+         "interface":"eth-rt5-1"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":30041,
+         "interface":"eth-rt5-2"
+       }
+     ]
+@@ -117,13 +117,13 @@
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":30040,
+         "installed":true,
+         "nexthop":"10.0.5.5"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":30040,
+         "installed":true,
+         "nexthop":"10.0.4.5"
+       },
+@@ -141,13 +141,13 @@
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":30041,
+         "installed":true,
+         "interface":"eth-rt5-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":30041,
+         "installed":true,
+         "interface":"eth-rt5-1"
+       },
+@@ -227,7 +227,7 @@
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16060,
++        "outLabel":30060,
+         "installed":true,
+         "nexthop":"10.0.5.5",
+         "backupIndex":[
+@@ -236,7 +236,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16060,
++        "outLabel":30060,
+         "installed":true,
+         "nexthop":"10.0.4.5",
+         "backupIndex":[
+@@ -258,7 +258,7 @@
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16061,
++        "outLabel":30061,
+         "installed":true,
+         "interface":"eth-rt5-2",
+         "backupIndex":[
+@@ -267,7 +267,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16061,
++        "outLabel":30061,
+         "installed":true,
+         "interface":"eth-rt5-1",
+         "backupIndex":[
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..0ae87af
--- /dev/null
@@ -0,0 +1,32 @@
+--- rt3/step6/show_ip_route.ref        2020-09-25 17:51:15.521394894 -0300
++++ rt3/step7/show_ip_route.ref        2020-09-25 17:52:02.414007470 -0300
+@@ -158,9 +158,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         },
+         {
+@@ -171,9 +168,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
+@@ -184,8 +178,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16040,
+-            30050
++            16040
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..f392f64
--- /dev/null
@@ -0,0 +1,32 @@
+--- rt3/step6/show_ipv6_route.ref      2020-09-25 17:51:16.757411035 -0300
++++ rt3/step7/show_ipv6_route.ref      2020-09-25 17:52:03.650023622 -0300
+@@ -148,9 +148,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         },
+         {
+@@ -160,9 +157,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
+@@ -172,8 +166,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16041,
+-            30051
++            16041
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b74eb95
--- /dev/null
@@ -0,0 +1,71 @@
+--- rt3/step6/show_mpls_table.ref      2020-09-25 17:51:14.281378700 -0300
++++ rt3/step7/show_mpls_table.ref      2020-09-25 17:52:01.181991371 -0300
+@@ -159,68 +159,6 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.5.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.4.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.1.2"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt5-2",
+-        "backupIndex":[
+-          0
+-        ]
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt5-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-sw1"
+-      }
+-    ]
+-  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..25b42f2
--- /dev/null
@@ -0,0 +1,32 @@
+--- rt3/step7/show_ip_route.ref        2020-09-25 17:52:02.414007470 -0300
++++ rt3/step8/show_ip_route.ref        2020-09-25 17:53:20.419027241 -0300
+@@ -158,6 +158,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         },
+         {
+@@ -168,6 +171,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
+@@ -178,7 +184,8 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16040
++            16040,
++            30050
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..42d9356
--- /dev/null
@@ -0,0 +1,32 @@
+--- rt3/step7/show_ipv6_route.ref      2020-09-25 17:52:03.650023622 -0300
++++ rt3/step8/show_ipv6_route.ref      2020-09-25 17:53:21.643043250 -0300
+@@ -148,6 +148,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         },
+         {
+@@ -157,6 +160,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
+@@ -166,7 +172,8 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16041
++            16041,
++            30051
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..bd40f95
--- /dev/null
@@ -0,0 +1,71 @@
+--- rt3/step7/show_mpls_table.ref      2020-09-25 17:52:01.181991371 -0300
++++ rt3/step8/show_mpls_table.ref      2020-09-25 17:53:19.135010448 -0300
+@@ -159,6 +159,68 @@
+       }
+     ]
+   },
++  "16050":{
++    "inLabel":16050,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.5.5",
++        "backupIndex":[
++          0
++        ]
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.4.5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.1.2"
++      }
++    ]
++  },
++  "16051":{
++    "inLabel":16051,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt5-2",
++        "backupIndex":[
++          0
++        ]
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt5-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-sw1"
++      }
++    ]
++  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..687e84a
--- /dev/null
@@ -0,0 +1,11 @@
+--- rt3/step8/show_ip_route.ref        2020-09-25 17:53:20.419027241 -0300
++++ rt3/step9/show_ip_route.ref        2020-09-25 17:54:38.112043759 -0300
+@@ -185,7 +185,7 @@
+           "active":true,
+           "labels":[
+             16040,
+-            30050
++            30500
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..4b76be6
--- /dev/null
@@ -0,0 +1,11 @@
+--- rt3/step8/show_ipv6_route.ref      2020-09-25 17:53:21.643043250 -0300
++++ rt3/step9/show_ipv6_route.ref      2020-09-25 17:54:39.320059571 -0300
+@@ -173,7 +173,7 @@
+           "active":true,
+           "labels":[
+             16041,
+-            30051
++            30501
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..6f6451e
--- /dev/null
@@ -0,0 +1,133 @@
+--- rt3/step8/show_mpls_table.ref      2020-09-25 17:53:19.135010448 -0300
++++ rt3/step9/show_mpls_table.ref      2020-09-25 17:54:36.852027268 -0300
+@@ -159,13 +159,13 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
++  "16060":{
++    "inLabel":16060,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":30060,
+         "installed":true,
+         "nexthop":"10.0.5.5",
+         "backupIndex":[
+@@ -174,7 +174,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":30060,
+         "installed":true,
+         "nexthop":"10.0.4.5",
+         "backupIndex":[
+@@ -185,18 +185,18 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":3,
+         "nexthop":"10.0.1.2"
+       }
+     ]
+   },
+-  "16051":{
+-    "inLabel":16051,
++  "16061":{
++    "inLabel":16061,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":30061,
+         "installed":true,
+         "interface":"eth-rt5-2",
+         "backupIndex":[
+@@ -205,7 +205,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":30061,
+         "installed":true,
+         "interface":"eth-rt5-1",
+         "backupIndex":[
+@@ -216,18 +216,18 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":3,
+         "interface":"eth-sw1"
+       }
+     ]
+   },
+-  "16060":{
+-    "inLabel":16060,
++  "16500":{
++    "inLabel":16500,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":30060,
++        "outLabel":3,
+         "installed":true,
+         "nexthop":"10.0.5.5",
+         "backupIndex":[
+@@ -236,7 +236,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":30060,
++        "outLabel":3,
+         "installed":true,
+         "nexthop":"10.0.4.5",
+         "backupIndex":[
+@@ -247,18 +247,18 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":16040,
+         "nexthop":"10.0.1.2"
+       }
+     ]
+   },
+-  "16061":{
+-    "inLabel":16061,
++  "16501":{
++    "inLabel":16501,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":30061,
++        "outLabel":3,
+         "installed":true,
+         "interface":"eth-rt5-2",
+         "backupIndex":[
+@@ -267,7 +267,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":30061,
++        "outLabel":3,
+         "installed":true,
+         "interface":"eth-rt5-1",
+         "backupIndex":[
+@@ -278,7 +278,7 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":16041,
+         "interface":"eth-sw1"
+       }
+     ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt3/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt3/zebra.conf
new file mode 100644 (file)
index 0000000..3254529
--- /dev/null
@@ -0,0 +1,25 @@
+log file zebra.log
+!
+hostname rt3
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 3.3.3.3/32
+ ipv6 address 2001:db8:1000::3/128
+!
+interface eth-sw1
+ ip address 10.0.1.3/24
+!
+interface eth-rt5-1
+ ip address 10.0.4.3/24
+!
+interface eth-rt5-2
+ ip address 10.0.5.3/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt4/isisd.conf
new file mode 100644 (file)
index 0000000..7d41106
--- /dev/null
@@ -0,0 +1,53 @@
+hostname rt4
+log file isisd.log
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis sr-events
+debug isis lsp-gen
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt2-1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt2-2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt5
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt6
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+router isis 1
+ net 49.0000.0000.0000.0004.00
+ is-type level-1
+ lsp-gen-interval 2
+ topology ipv6-unicast
+ segment-routing on
+ segment-routing global-block 16000 23999
+ segment-routing node-msd 8
+ segment-routing prefix 4.4.4.4/32 index 40
+ segment-routing prefix 2001:db8:1000::4/128 index 41
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..168b90a
--- /dev/null
@@ -0,0 +1,497 @@
+{
+  "1.1.1.1\/32":[
+    {
+      "prefix":"1.1.1.1\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16010
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16010
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16030,
+            16020
+          ]
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "labels":[
+            16030
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "labels":[
+            16030
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16030
+          ]
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "6.6.6.6\/32":[
+    {
+      "prefix":"6.6.6.6\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.1.0\/24":[
+    {
+      "prefix":"10.0.1.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16030
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.3.0\/24":[
+    {
+      "prefix":"10.0.3.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16030
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.4.0\/24":[
+    {
+      "prefix":"10.0.4.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0,
+            1,
+            2
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        },
+        {
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.5.0\/24":[
+    {
+      "prefix":"10.0.5.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0,
+            1,
+            2
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        },
+        {
+          "ip":"10.0.2.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.3.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt2-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.8.0\/24":[
+    {
+      "prefix":"10.0.8.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.7.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..a4442ee
--- /dev/null
@@ -0,0 +1,198 @@
+{
+  "2001:db8:1000::1\/128":[
+    {
+      "prefix":"2001:db8:1000::1\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16011
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16011
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::2\/128":[
+    {
+      "prefix":"2001:db8:1000::2\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16031,
+            16021
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::3\/128":[
+    {
+      "prefix":"2001:db8:1000::3\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2-1",
+          "active":true,
+          "labels":[
+            16031
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16031
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt2-2",
+          "active":true,
+          "labels":[
+            16031
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::5\/128":[
+    {
+      "prefix":"2001:db8:1000::5\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::6\/128":[
+    {
+      "prefix":"2001:db8:1000::6\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref
new file mode 100644 (file)
index 0000000..18354e9
--- /dev/null
@@ -0,0 +1,262 @@
+{
+  "16010":{
+    "inLabel":16010,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.3.2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.2.2",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.6.5"
+      }
+    ]
+  },
+  "16011":{
+    "inLabel":16011,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt2-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt2-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "16020":{
+    "inLabel":16020,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.3.2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.2.2",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16030,
+        "nexthop":"10.0.6.5"
+      }
+    ]
+  },
+  "16021":{
+    "inLabel":16021,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt2-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt2-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16031,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "16030":{
+    "inLabel":16030,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16030,
+        "installed":true,
+        "nexthop":"10.0.3.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16030,
+        "installed":true,
+        "nexthop":"10.0.2.2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16030,
+        "installed":true,
+        "nexthop":"10.0.6.5"
+      }
+    ]
+  },
+  "16031":{
+    "inLabel":16031,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16031,
+        "installed":true,
+        "interface":"eth-rt2-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16031,
+        "installed":true,
+        "interface":"eth-rt2-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16031,
+        "installed":true,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "16050":{
+    "inLabel":16050,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.6.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.7.6"
+      }
+    ]
+  },
+  "16051":{
+    "inLabel":16051,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt6"
+      }
+    ]
+  },
+  "16060":{
+    "inLabel":16060,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.7.6",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.6.5"
+      }
+    ]
+  },
+  "16061":{
+    "inLabel":16061,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt6",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt5"
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt4/step1/show_yang_interface_isis_adjacencies.ref
new file mode 100644 (file)
index 0000000..2eb64b6
--- /dev/null
@@ -0,0 +1,82 @@
+{
+  "frr-interface:lib": {
+    "interface": [
+      {
+        "name": "eth-rt2-1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0002",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt2-2",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0002",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt5",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0005",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt6",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0006",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step2/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step3/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..7dcdb74
--- /dev/null
@@ -0,0 +1,312 @@
+--- rt4/step3/show_ip_route.ref        2020-09-25 17:48:05.722919797 -0300
++++ rt4/step4/show_ip_route.ref        2020-09-25 17:49:02.163655010 -0300
+@@ -15,9 +15,6 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16010
+           ]
+@@ -28,21 +25,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16010
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true
+-        }
+       ]
+     }
+   ],
+@@ -62,9 +48,6 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -75,25 +58,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true,
+-          "labels":[
+-            16030,
+-            16020
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -156,21 +124,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.7.6",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt6",
+-          "active":true
+-        }
+       ]
+     }
+   ],
+@@ -190,21 +147,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt6",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true
+-        }
+       ]
+     }
+   ],
+@@ -223,27 +169,13 @@
+           "ip":"10.0.2.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+           "active":true
+         }
+       ]
+@@ -259,30 +191,13 @@
+         {
+           "ip":"10.0.2.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt2-1",
+-          "backupIndex":[
+-            0
+-          ]
++          "interfaceName":"eth-rt2-1"
+         },
+         {
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true,
+-          "labels":[
+-            16030
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -298,29 +213,12 @@
+           "ip":"10.0.2.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt2-2",
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true,
+-          "labels":[
+-            16030
+-          ]
++          "interfaceName":"eth-rt2-2"
+         }
+       ]
+     }
+@@ -340,31 +238,6 @@
+           "ip":"10.0.6.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5",
+-          "active":true,
+-          "backupIndex":[
+-            0,
+-            1,
+-            2
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.7.6",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt6",
+-          "active":true
+-        },
+-        {
+-          "ip":"10.0.2.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt2-1",
+-          "active":true
+-        },
+-        {
+-          "ip":"10.0.3.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt2-2",
+           "active":true
+         }
+       ]
+@@ -385,31 +258,6 @@
+           "ip":"10.0.6.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5",
+-          "active":true,
+-          "backupIndex":[
+-            0,
+-            1,
+-            2
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.7.6",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt6",
+-          "active":true
+-        },
+-        {
+-          "ip":"10.0.2.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt2-1",
+-          "active":true
+-        },
+-        {
+-          "ip":"10.0.3.2",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt2-2",
+           "active":true
+         }
+       ]
+@@ -425,18 +273,7 @@
+         {
+           "ip":"10.0.6.5",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.7.6",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt6",
+-          "active":true
++          "interfaceName":"eth-rt5"
+         }
+       ]
+     }
+@@ -451,18 +288,7 @@
+         {
+           "ip":"10.0.7.6",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt6",
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true
++          "interfaceName":"eth-rt6"
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..b84ceaf
--- /dev/null
@@ -0,0 +1,110 @@
+--- rt4/step3/show_ipv6_route.ref      2020-09-25 17:48:06.998936410 -0300
++++ rt4/step4/show_ipv6_route.ref      2020-09-25 17:49:03.399671119 -0300
+@@ -14,9 +14,6 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16011
+           ]
+@@ -26,20 +23,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16011
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5",
+-          "active":true
+-        }
+       ]
+     }
+   ],
+@@ -58,9 +45,6 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -70,24 +54,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5",
+-          "active":true,
+-          "labels":[
+-            16031,
+-            16021
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -146,20 +116,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt6",
+-          "active":true
+-        }
+       ]
+     }
+   ],
+@@ -178,20 +138,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt6",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5",
+-          "active":true
+-        }
+       ]
+     }
+   ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..70e0108
--- /dev/null
@@ -0,0 +1,194 @@
+--- rt4/step3/show_mpls_table.ref      2020-09-25 17:48:04.418902820 -0300
++++ rt4/step4/show_mpls_table.ref      2020-09-25 17:49:00.959639319 -0300
+@@ -7,26 +7,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16010,
+         "installed":true,
+-        "nexthop":"10.0.3.2",
+-        "backupIndex":[
+-          0
+-        ]
++        "nexthop":"10.0.3.2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16010,
+         "installed":true,
+-        "nexthop":"10.0.2.2",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.6.5"
++        "nexthop":"10.0.2.2"
+       }
+     ]
+   },
+@@ -38,26 +25,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
+         "installed":true,
+-        "interface":"eth-rt2-2",
+-        "backupIndex":[
+-          0
+-        ]
++        "interface":"eth-rt2-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
+         "installed":true,
+-        "interface":"eth-rt2-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt5"
++        "interface":"eth-rt2-1"
+       }
+     ]
+   },
+@@ -69,26 +43,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.3.2",
+-        "backupIndex":[
+-          0
+-        ]
++        "nexthop":"10.0.3.2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.2.2",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16030,
+-        "nexthop":"10.0.6.5"
++        "nexthop":"10.0.2.2"
+       }
+     ]
+   },
+@@ -100,26 +61,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt2-2",
+-        "backupIndex":[
+-          0
+-        ]
++        "interface":"eth-rt2-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt2-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16031,
+-        "interface":"eth-rt5"
++        "interface":"eth-rt2-1"
+       }
+     ]
+   },
+@@ -179,17 +127,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.6.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.7.6"
++        "nexthop":"10.0.6.5"
+       }
+     ]
+   },
+@@ -201,17 +139,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt6"
++        "interface":"eth-rt5"
+       }
+     ]
+   },
+@@ -223,17 +151,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.7.6",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.6.5"
++        "nexthop":"10.0.7.6"
+       }
+     ]
+   },
+@@ -245,17 +163,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt6",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt5"
++        "interface":"eth-rt6"
+       }
+     ]
+   }
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..aa319a3
--- /dev/null
@@ -0,0 +1,312 @@
+--- rt4/step4/show_ip_route.ref        2020-09-25 17:49:02.163655010 -0300
++++ rt4/step5/show_ip_route.ref        2020-09-25 17:50:12.800576153 -0300
+@@ -15,6 +15,9 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16010
+           ]
+@@ -25,10 +28,21 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16010
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true
++        }
+       ]
+     }
+   ],
+@@ -48,6 +62,9 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -58,10 +75,25 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true,
++          "labels":[
++            16030,
++            16020
++          ]
++        }
+       ]
+     }
+   ],
+@@ -124,10 +156,21 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.7.6",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt6",
++          "active":true
++        }
+       ]
+     }
+   ],
+@@ -147,10 +190,21 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt6",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true
++        }
+       ]
+     }
+   ],
+@@ -169,13 +223,27 @@
+           "ip":"10.0.2.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "fib":true,
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
+           "active":true
+         }
+       ]
+@@ -191,13 +259,30 @@
+         {
+           "ip":"10.0.2.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt2-1"
++          "interfaceName":"eth-rt2-1",
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-2",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true,
++          "labels":[
++            16030
++          ]
+         }
+       ]
+     }
+@@ -213,12 +298,29 @@
+           "ip":"10.0.2.2",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt2-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt2-2"
++          "interfaceName":"eth-rt2-2",
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true,
++          "labels":[
++            16030
++          ]
+         }
+       ]
+     }
+@@ -238,6 +340,31 @@
+           "ip":"10.0.6.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5",
++          "active":true,
++          "backupIndex":[
++            0,
++            1,
++            2
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.7.6",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt6",
++          "active":true
++        },
++        {
++          "ip":"10.0.2.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt2-1",
++          "active":true
++        },
++        {
++          "ip":"10.0.3.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt2-2",
+           "active":true
+         }
+       ]
+@@ -258,6 +385,31 @@
+           "ip":"10.0.6.5",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt5",
++          "active":true,
++          "backupIndex":[
++            0,
++            1,
++            2
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.7.6",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt6",
++          "active":true
++        },
++        {
++          "ip":"10.0.2.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt2-1",
++          "active":true
++        },
++        {
++          "ip":"10.0.3.2",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt2-2",
+           "active":true
+         }
+       ]
+@@ -273,7 +425,18 @@
+         {
+           "ip":"10.0.6.5",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt5"
++          "interfaceName":"eth-rt5",
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.7.6",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt6",
++          "active":true
+         }
+       ]
+     }
+@@ -288,7 +451,18 @@
+         {
+           "ip":"10.0.7.6",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt6"
++          "interfaceName":"eth-rt6",
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..1bd2078
--- /dev/null
@@ -0,0 +1,110 @@
+--- rt4/step4/show_ipv6_route.ref      2020-09-25 17:49:03.399671119 -0300
++++ rt4/step5/show_ipv6_route.ref      2020-09-25 17:50:14.040592332 -0300
+@@ -14,6 +14,9 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16011
+           ]
+@@ -23,10 +26,20 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16011
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5",
++          "active":true
++        }
+       ]
+     }
+   ],
+@@ -45,6 +58,9 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -54,10 +70,24 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt2-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5",
++          "active":true,
++          "labels":[
++            16031,
++            16021
++          ]
++        }
+       ]
+     }
+   ],
+@@ -116,10 +146,20 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt5",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt6",
++          "active":true
++        }
+       ]
+     }
+   ],
+@@ -138,10 +178,20 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt6",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5",
++          "active":true
++        }
+       ]
+     }
+   ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..664b129
--- /dev/null
@@ -0,0 +1,194 @@
+--- rt4/step4/show_mpls_table.ref      2020-09-25 17:49:00.959639319 -0300
++++ rt4/step5/show_mpls_table.ref      2020-09-25 17:50:11.488559034 -0300
+@@ -7,13 +7,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16010,
+         "installed":true,
+-        "nexthop":"10.0.3.2"
++        "nexthop":"10.0.3.2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16010,
+         "installed":true,
+-        "nexthop":"10.0.2.2"
++        "nexthop":"10.0.2.2",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.6.5"
+       }
+     ]
+   },
+@@ -25,13 +38,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
+         "installed":true,
+-        "interface":"eth-rt2-2"
++        "interface":"eth-rt2-2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
+         "installed":true,
+-        "interface":"eth-rt2-1"
++        "interface":"eth-rt2-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt5"
+       }
+     ]
+   },
+@@ -43,13 +69,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.3.2"
++        "nexthop":"10.0.3.2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.2.2"
++        "nexthop":"10.0.2.2",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16030,
++        "nexthop":"10.0.6.5"
+       }
+     ]
+   },
+@@ -61,13 +100,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt2-2"
++        "interface":"eth-rt2-2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt2-1"
++        "interface":"eth-rt2-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16031,
++        "interface":"eth-rt5"
+       }
+     ]
+   },
+@@ -127,7 +179,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.6.5"
++        "nexthop":"10.0.6.5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.7.6"
+       }
+     ]
+   },
+@@ -139,7 +201,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5"
++        "interface":"eth-rt5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt6"
+       }
+     ]
+   },
+@@ -151,7 +223,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.7.6"
++        "nexthop":"10.0.7.6",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.6.5"
+       }
+     ]
+   },
+@@ -163,7 +245,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt6"
++        "interface":"eth-rt6",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt5"
+       }
+     ]
+   }
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..c758b89
--- /dev/null
@@ -0,0 +1,38 @@
+--- rt4/step5/show_ip_route.ref        2020-09-25 17:50:12.800576153 -0300
++++ rt4/step6/show_ip_route.ref        2020-09-25 17:51:15.725397558 -0300
+@@ -90,7 +90,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16030,
++            30030,
+             16020
+           ]
+         }
+@@ -134,7 +134,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16030
++            30030
+           ]
+         }
+       ]
+@@ -281,7 +281,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16030
++            30030
+           ]
+         }
+       ]
+@@ -319,7 +319,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16030
++            30030
+           ]
+         }
+       ]
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..ca49521
--- /dev/null
@@ -0,0 +1,20 @@
+--- rt4/step5/show_ipv6_route.ref      2020-09-25 17:50:14.040592332 -0300
++++ rt4/step6/show_ipv6_route.ref      2020-09-25 17:51:16.969413804 -0300
+@@ -84,7 +84,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16031,
++            30031,
+             16021
+           ]
+         }
+@@ -116,7 +116,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16031
++            30031
+           ]
+         },
+         {
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..630e041
--- /dev/null
@@ -0,0 +1,38 @@
+--- rt4/step5/show_mpls_table.ref      2020-09-25 17:50:11.488559034 -0300
++++ rt4/step6/show_mpls_table.ref      2020-09-25 17:51:14.481381312 -0300
+@@ -87,7 +87,7 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16030,
++        "outLabel":30030,
+         "nexthop":"10.0.6.5"
+       }
+     ]
+@@ -118,7 +118,7 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16031,
++        "outLabel":30031,
+         "interface":"eth-rt5"
+       }
+     ]
+@@ -141,7 +141,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16030,
++        "outLabel":30030,
+         "installed":true,
+         "nexthop":"10.0.6.5"
+       }
+@@ -165,7 +165,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16031,
++        "outLabel":30031,
+         "installed":true,
+         "interface":"eth-rt5"
+       }
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..30e0dcf
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt4/step6/show_ip_route.ref        2020-09-25 17:51:15.725397558 -0300
++++ rt4/step7/show_ip_route.ref        2020-09-25 17:52:02.614010084 -0300
+@@ -158,9 +158,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..2606027
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt4/step6/show_ipv6_route.ref      2020-09-25 17:51:16.969413804 -0300
++++ rt4/step7/show_ipv6_route.ref      2020-09-25 17:52:03.854026287 -0300
+@@ -148,9 +148,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..5334cfd
--- /dev/null
@@ -0,0 +1,53 @@
+--- rt4/step6/show_mpls_table.ref      2020-09-25 17:51:14.481381312 -0300
++++ rt4/step7/show_mpls_table.ref      2020-09-25 17:52:01.385994037 -0300
+@@ -171,50 +171,6 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.6.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.7.6"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt6"
+-      }
+-    ]
+-  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..b393970
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt4/step7/show_ip_route.ref        2020-09-25 17:52:02.614010084 -0300
++++ rt4/step8/show_ip_route.ref        2020-09-25 17:53:20.623029909 -0300
+@@ -158,6 +158,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..8bad2ed
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt4/step7/show_ipv6_route.ref      2020-09-25 17:52:03.854026287 -0300
++++ rt4/step8/show_ipv6_route.ref      2020-09-25 17:53:21.843045865 -0300
+@@ -148,6 +148,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..d296dbd
--- /dev/null
@@ -0,0 +1,53 @@
+--- rt4/step7/show_mpls_table.ref      2020-09-25 17:52:01.385994037 -0300
++++ rt4/step8/show_mpls_table.ref      2020-09-25 17:53:19.371013534 -0300
+@@ -171,6 +171,50 @@
+       }
+     ]
+   },
++  "16050":{
++    "inLabel":16050,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.6.5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.7.6"
++      }
++    ]
++  },
++  "16051":{
++    "inLabel":16051,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt6"
++      }
++    ]
++  },
+   "16060":{
+     "inLabel":16060,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..408cbfb
--- /dev/null
@@ -0,0 +1,102 @@
+--- rt4/step8/show_mpls_table.ref      2020-09-25 17:53:19.371013534 -0300
++++ rt4/step9/show_mpls_table.ref      2020-09-25 17:54:37.064030042 -0300
+@@ -171,15 +171,15 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
++  "16060":{
++    "inLabel":16060,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.6.5",
++        "nexthop":"10.0.7.6",
+         "backupIndex":[
+           0
+         ]
+@@ -189,19 +189,19 @@
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+-        "nexthop":"10.0.7.6"
++        "nexthop":"10.0.6.5"
+       }
+     ]
+   },
+-  "16051":{
+-    "inLabel":16051,
++  "16061":{
++    "inLabel":16061,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5",
++        "interface":"eth-rt6",
+         "backupIndex":[
+           0
+         ]
+@@ -211,19 +211,19 @@
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+-        "interface":"eth-rt6"
++        "interface":"eth-rt5"
+       }
+     ]
+   },
+-  "16060":{
+-    "inLabel":16060,
++  "16500":{
++    "inLabel":16500,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.7.6",
++        "nexthop":"10.0.6.5",
+         "backupIndex":[
+           0
+         ]
+@@ -233,19 +233,19 @@
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+-        "nexthop":"10.0.6.5"
++        "nexthop":"10.0.7.6"
+       }
+     ]
+   },
+-  "16061":{
+-    "inLabel":16061,
++  "16501":{
++    "inLabel":16501,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt6",
++        "interface":"eth-rt5",
+         "backupIndex":[
+           0
+         ]
+@@ -255,7 +255,7 @@
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+-        "interface":"eth-rt5"
++        "interface":"eth-rt6"
+       }
+     ]
+   }
diff --git a/tests/topotests/isis-tilfa-topo1/rt4/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt4/zebra.conf
new file mode 100644 (file)
index 0000000..4945897
--- /dev/null
@@ -0,0 +1,28 @@
+log file zebra.log
+!
+hostname rt4
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 4.4.4.4/32
+ ipv6 address 2001:db8:1000::4/128
+!
+interface eth-rt2-1
+ ip address 10.0.2.4/24
+!
+interface eth-rt2-2
+ ip address 10.0.3.4/24
+!
+interface eth-rt5
+ ip address 10.0.6.4/24
+!
+interface eth-rt6
+ ip address 10.0.7.4/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt5/isisd.conf
new file mode 100644 (file)
index 0000000..be52eb0
--- /dev/null
@@ -0,0 +1,53 @@
+hostname rt5
+log file isisd.log
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis sr-events
+debug isis lsp-gen
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt3-1
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt3-2
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt4
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt6
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+router isis 1
+ net 49.0000.0000.0000.0005.00
+ is-type level-1
+ lsp-gen-interval 2
+ topology ipv6-unicast
+ segment-routing on
+ segment-routing global-block 16000 23999
+ segment-routing node-msd 8
+ segment-routing prefix 5.5.5.5/32 index 50
+ segment-routing prefix 2001:db8:1000::5/128 index 51
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..f747065
--- /dev/null
@@ -0,0 +1,497 @@
+{
+  "1.1.1.1\/32":[
+    {
+      "prefix":"1.1.1.1\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16010
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16010
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "labels":[
+            16020
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "labels":[
+            16020
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16020
+          ]
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16020,
+            16030
+          ]
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "6.6.6.6\/32":[
+    {
+      "prefix":"6.6.6.6\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.1.0\/24":[
+    {
+      "prefix":"10.0.1.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0,
+            1,
+            2
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        },
+        {
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.3.0\/24":[
+    {
+      "prefix":"10.0.3.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0,
+            1,
+            2
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        },
+        {
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true
+        },
+        {
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.4.0\/24":[
+    {
+      "prefix":"10.0.4.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16020
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.5.0\/24":[
+    {
+      "prefix":"10.0.5.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.4.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        },
+        {
+          "ip":"10.0.5.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt3-2",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16020
+          ]
+        }
+      ]
+    }
+  ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.8.0\/24":[
+    {
+      "prefix":"10.0.8.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.8.6",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt6",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.6.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..6c0a5e0
--- /dev/null
@@ -0,0 +1,198 @@
+{
+  "2001:db8:1000::1\/128":[
+    {
+      "prefix":"2001:db8:1000::1\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16011
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16011
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::2\/128":[
+    {
+      "prefix":"2001:db8:1000::2\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16021
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "labels":[
+            16021
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "labels":[
+            16021
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::3\/128":[
+    {
+      "prefix":"2001:db8:1000::3\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3-1",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt3-2",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16021,
+            16031
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::4\/128":[
+    {
+      "prefix":"2001:db8:1000::4\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt6",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::6\/128":[
+    {
+      "prefix":"2001:db8:1000::6\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt6",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref
new file mode 100644 (file)
index 0000000..2b70392
--- /dev/null
@@ -0,0 +1,262 @@
+{
+  "16010":{
+    "inLabel":16010,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.5.3",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.4.3",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.6.4"
+      }
+    ]
+  },
+  "16011":{
+    "inLabel":16011,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt3-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt3-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "16020":{
+    "inLabel":16020,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16020,
+        "installed":true,
+        "nexthop":"10.0.5.3"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16020,
+        "installed":true,
+        "nexthop":"10.0.4.3"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16020,
+        "installed":true,
+        "nexthop":"10.0.6.4"
+      }
+    ]
+  },
+  "16021":{
+    "inLabel":16021,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16021,
+        "installed":true,
+        "interface":"eth-rt3-2"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16021,
+        "installed":true,
+        "interface":"eth-rt3-1"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16021,
+        "installed":true,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "16030":{
+    "inLabel":16030,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.5.3",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.4.3",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16020,
+        "nexthop":"10.0.6.4"
+      }
+    ]
+  },
+  "16031":{
+    "inLabel":16031,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt3-2",
+        "backupIndex":[
+          0
+        ]
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt3-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16021,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "16040":{
+    "inLabel":16040,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.6.4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.8.6"
+      }
+    ]
+  },
+  "16041":{
+    "inLabel":16041,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt6"
+      }
+    ]
+  },
+  "16060":{
+    "inLabel":16060,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.8.6",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.6.4"
+      }
+    ]
+  },
+  "16061":{
+    "inLabel":16061,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt6",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt4"
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt5/step1/show_yang_interface_isis_adjacencies.ref
new file mode 100644 (file)
index 0000000..1ff8c2c
--- /dev/null
@@ -0,0 +1,82 @@
+{
+  "frr-interface:lib": {
+    "interface": [
+      {
+        "name": "eth-rt3-1",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0003",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt3-2",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0003",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt4",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0004",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt6",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0006",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step2/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step3/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..6402b51
--- /dev/null
@@ -0,0 +1,125 @@
+--- rt5/step3/show_ip_route.ref        2020-09-25 17:48:05.950922766 -0300
++++ rt5/step4/show_ip_route.ref        2020-09-25 17:49:02.363657616 -0300
+@@ -81,10 +81,7 @@
+           "ip":"10.0.6.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16020
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -105,9 +102,6 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -118,25 +112,10 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16020,
+-            16030
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -158,9 +137,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
+@@ -349,30 +325,13 @@
+         {
+           "ip":"10.0.4.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt3-1",
+-          "backupIndex":[
+-            0
+-          ]
++          "interfaceName":"eth-rt3-1"
+         },
+         {
+           "ip":"10.0.5.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16020
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -388,29 +347,12 @@
+           "ip":"10.0.4.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-1",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
++          "active":true
+         },
+         {
+           "ip":"10.0.5.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt3-2",
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16020
+-          ]
++          "interfaceName":"eth-rt3-2"
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..7a0135b
--- /dev/null
@@ -0,0 +1,59 @@
+--- rt5/step3/show_ipv6_route.ref      2020-09-25 17:48:07.218939274 -0300
++++ rt5/step4/show_ipv6_route.ref      2020-09-25 17:49:03.599673726 -0300
+@@ -57,10 +57,7 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16021
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+@@ -98,9 +95,6 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt3-1",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+@@ -110,24 +104,10 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt3-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16021,
+-            16031
+-          ]
+-        }
+       ]
+     }
+   ],
+@@ -148,9 +128,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..299dac7
--- /dev/null
@@ -0,0 +1,130 @@
+--- rt5/step3/show_mpls_table.ref      2020-09-25 17:48:04.626905528 -0300
++++ rt5/step4/show_mpls_table.ref      2020-09-25 17:49:01.159641924 -0300
+@@ -76,12 +76,6 @@
+         "outLabel":16020,
+         "installed":true,
+         "nexthop":"10.0.4.3"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16020,
+-        "installed":true,
+-        "nexthop":"10.0.6.4"
+       }
+     ]
+   },
+@@ -100,12 +94,6 @@
+         "outLabel":16021,
+         "installed":true,
+         "interface":"eth-rt3-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16021,
+-        "installed":true,
+-        "interface":"eth-rt4"
+       }
+     ]
+   },
+@@ -117,26 +105,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.5.3",
+-        "backupIndex":[
+-          0
+-        ]
++        "nexthop":"10.0.5.3"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.4.3",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16020,
+-        "nexthop":"10.0.6.4"
++        "nexthop":"10.0.4.3"
+       }
+     ]
+   },
+@@ -148,70 +123,13 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt3-2",
+-        "backupIndex":[
+-          0
+-        ]
++        "interface":"eth-rt3-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt3-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16021,
+-        "interface":"eth-rt4"
+-      }
+-    ]
+-  },
+-  "16040":{
+-    "inLabel":16040,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.6.4",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.8.6"
+-      }
+-    ]
+-  },
+-  "16041":{
+-    "inLabel":16041,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt4",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt6"
++        "interface":"eth-rt3-1"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..31f70b1
--- /dev/null
@@ -0,0 +1,125 @@
+--- rt5/step4/show_ip_route.ref        2020-09-25 17:49:02.363657616 -0300
++++ rt5/step5/show_ip_route.ref        2020-09-25 17:50:13.012578918 -0300
+@@ -81,7 +81,10 @@
+           "ip":"10.0.6.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4",
+-          "active":true
++          "active":true,
++          "labels":[
++            16020
++          ]
+         }
+       ]
+     }
+@@ -102,6 +105,9 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -112,10 +118,25 @@
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4",
++          "active":true,
++          "labels":[
++            16020,
++            16030
++          ]
++        }
+       ]
+     }
+   ],
+@@ -137,6 +158,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
+@@ -325,13 +349,30 @@
+         {
+           "ip":"10.0.4.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt3-1"
++          "interfaceName":"eth-rt3-1",
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.5.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-2",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4",
++          "active":true,
++          "labels":[
++            16020
++          ]
+         }
+       ]
+     }
+@@ -347,12 +388,29 @@
+           "ip":"10.0.4.3",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt3-1",
+-          "active":true
++          "active":true,
++          "backupIndex":[
++            0
++          ]
+         },
+         {
+           "ip":"10.0.5.3",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt3-2"
++          "interfaceName":"eth-rt3-2",
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4",
++          "active":true,
++          "labels":[
++            16020
++          ]
+         }
+       ]
+     }
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..59d9755
--- /dev/null
@@ -0,0 +1,59 @@
+--- rt5/step4/show_ipv6_route.ref      2020-09-25 17:49:03.599673726 -0300
++++ rt5/step5/show_ipv6_route.ref      2020-09-25 17:50:14.248595046 -0300
+@@ -57,7 +57,10 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4",
+-          "active":true
++          "active":true,
++          "labels":[
++            16021
++          ]
+         },
+         {
+           "fib":true,
+@@ -95,6 +98,9 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt3-1",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -104,10 +110,24 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt3-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4",
++          "active":true,
++          "labels":[
++            16021,
++            16031
++          ]
++        }
+       ]
+     }
+   ],
+@@ -128,6 +148,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..669c07e
--- /dev/null
@@ -0,0 +1,130 @@
+--- rt5/step4/show_mpls_table.ref      2020-09-25 17:49:01.159641924 -0300
++++ rt5/step5/show_mpls_table.ref      2020-09-25 17:50:11.696561748 -0300
+@@ -69,6 +69,12 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16020,
+         "installed":true,
++        "nexthop":"10.0.6.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16020,
++        "installed":true,
+         "nexthop":"10.0.5.3"
+       },
+       {
+@@ -87,6 +93,12 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16021,
+         "installed":true,
++        "interface":"eth-rt4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16021,
++        "installed":true,
+         "interface":"eth-rt3-2"
+       },
+       {
+@@ -105,13 +117,26 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.5.3"
++        "nexthop":"10.0.5.3",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.4.3"
++        "nexthop":"10.0.4.3",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16020,
++        "nexthop":"10.0.6.4"
+       }
+     ]
+   },
+@@ -123,13 +148,70 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt3-2"
++        "interface":"eth-rt3-2",
++        "backupIndex":[
++          0
++        ]
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt3-1"
++        "interface":"eth-rt3-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16021,
++        "interface":"eth-rt4"
++      }
++    ]
++  },
++  "16040":{
++    "inLabel":16040,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.6.4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.8.6"
++      }
++    ]
++  },
++  "16041":{
++    "inLabel":16041,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt6"
+       }
+     ]
+   },
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..a4f82cb
--- /dev/null
@@ -0,0 +1,146 @@
+--- rt5/step5/show_mpls_table.ref      2020-09-25 17:50:11.696561748 -0300
++++ rt5/step6/show_mpls_table.ref      2020-09-25 17:51:14.685383977 -0300
+@@ -1,6 +1,6 @@
+ {
+-  "16010":{
+-    "inLabel":16010,
++  "30010":{
++    "inLabel":30010,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -30,8 +30,8 @@
+       }
+     ]
+   },
+-  "16011":{
+-    "inLabel":16011,
++  "30011":{
++    "inLabel":30011,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -61,56 +61,56 @@
+       }
+     ]
+   },
+-  "16020":{
+-    "inLabel":16020,
++  "30020":{
++    "inLabel":30020,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16020,
+         "installed":true,
+-        "nexthop":"10.0.6.4"
++        "nexthop":"10.0.5.3"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16020,
+         "installed":true,
+-        "nexthop":"10.0.5.3"
++        "nexthop":"10.0.4.3"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16020,
+         "installed":true,
+-        "nexthop":"10.0.4.3"
++        "nexthop":"10.0.6.4"
+       }
+     ]
+   },
+-  "16021":{
+-    "inLabel":16021,
++  "30021":{
++    "inLabel":30021,
+     "installed":true,
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16021,
+         "installed":true,
+-        "interface":"eth-rt4"
++        "interface":"eth-rt3-2"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16021,
+         "installed":true,
+-        "interface":"eth-rt3-2"
++        "interface":"eth-rt3-1"
+       },
+       {
+         "type":"SR (IS-IS)",
+         "outLabel":16021,
+         "installed":true,
+-        "interface":"eth-rt3-1"
++        "interface":"eth-rt4"
+       }
+     ]
+   },
+-  "16030":{
+-    "inLabel":16030,
++  "30030":{
++    "inLabel":30030,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -140,8 +140,8 @@
+       }
+     ]
+   },
+-  "16031":{
+-    "inLabel":16031,
++  "30031":{
++    "inLabel":30031,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -171,8 +171,8 @@
+       }
+     ]
+   },
+-  "16040":{
+-    "inLabel":16040,
++  "30040":{
++    "inLabel":30040,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -193,8 +193,8 @@
+       }
+     ]
+   },
+-  "16041":{
+-    "inLabel":16041,
++  "30041":{
++    "inLabel":30041,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -215,8 +215,8 @@
+       }
+     ]
+   },
+-  "16060":{
+-    "inLabel":16060,
++  "30060":{
++    "inLabel":30060,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -237,8 +237,8 @@
+       }
+     ]
+   },
+-  "16061":{
+-    "inLabel":16061,
++  "30061":{
++    "inLabel":30061,
+     "installed":true,
+     "nexthops":[
+       {
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step7/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step8/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt5/step9/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt5/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt5/zebra.conf
new file mode 100644 (file)
index 0000000..4cfea1a
--- /dev/null
@@ -0,0 +1,28 @@
+log file zebra.log
+!
+hostname rt5
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 5.5.5.5/32
+ ipv6 address 2001:db8:1000::5/128
+!
+interface eth-rt3-1
+ ip address 10.0.4.5/24
+!
+interface eth-rt3-2
+ ip address 10.0.5.5/24
+!
+interface eth-rt4
+ ip address 10.0.6.5/24
+!
+interface eth-rt6
+ ip address 10.0.8.5/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/isisd.conf b/tests/topotests/isis-tilfa-topo1/rt6/isisd.conf
new file mode 100644 (file)
index 0000000..db47622
--- /dev/null
@@ -0,0 +1,39 @@
+hostname rt6
+log file isisd.log
+!
+debug isis events
+debug isis route-events
+debug isis spf-events
+debug isis sr-events
+debug isis lsp-gen
+!
+interface lo
+ ip router isis 1
+ ipv6 router isis 1
+ isis passive
+!
+interface eth-rt4
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+interface eth-rt5
+ ip router isis 1
+ ipv6 router isis 1
+ isis network point-to-point
+ isis hello-multiplier 3
+ isis fast-reroute ti-lfa
+!
+router isis 1
+ net 49.0000.0000.0000.0006.00
+ is-type level-1
+ lsp-gen-interval 2
+ topology ipv6-unicast
+ segment-routing on
+ segment-routing global-block 16000 23999
+ segment-routing node-msd 8
+ segment-routing prefix 6.6.6.6/32 index 60
+ segment-routing prefix 2001:db8:1000::6/128 index 61
+!
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref
new file mode 100644 (file)
index 0000000..5bcef4c
--- /dev/null
@@ -0,0 +1,401 @@
+{
+  "1.1.1.1\/32":[
+    {
+      "prefix":"1.1.1.1\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":40,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16010
+          ]
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16010
+          ]
+        }
+      ]
+    }
+  ],
+  "2.2.2.2\/32":[
+    {
+      "prefix":"2.2.2.2\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16020
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "3.3.3.3\/32":[
+    {
+      "prefix":"3.3.3.3\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16030
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "4.4.4.4\/32":[
+    {
+      "prefix":"4.4.4.4\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "5.5.5.5\/32":[
+    {
+      "prefix":"5.5.5.5\/32",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.1.0\/24":[
+    {
+      "prefix":"10.0.1.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.2.0\/24":[
+    {
+      "prefix":"10.0.2.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.3.0\/24":[
+    {
+      "prefix":"10.0.3.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.4.0\/24":[
+    {
+      "prefix":"10.0.4.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.5.0\/24":[
+    {
+      "prefix":"10.0.5.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.6.0\/24":[
+    {
+      "prefix":"10.0.6.0\/24",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        },
+        {
+          "fib":true,
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.7.0\/24":[
+    {
+      "prefix":"10.0.7.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "10.0.8.0\/24":[
+    {
+      "prefix":"10.0.8.0\/24",
+      "protocol":"isis",
+      "distance":115,
+      "metric":20,
+      "nexthops":[
+        {
+          "ip":"10.0.8.5",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt5",
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.7.4",
+          "afi":"ipv4",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref
new file mode 100644 (file)
index 0000000..8294b07
--- /dev/null
@@ -0,0 +1,161 @@
+{
+  "2001:db8:1000::1\/128":[
+    {
+      "prefix":"2001:db8:1000::1\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":40,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16011
+          ]
+        },
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16011
+          ]
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::2\/128":[
+    {
+      "prefix":"2001:db8:1000::2\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16021
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::3\/128":[
+    {
+      "prefix":"2001:db8:1000::3\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":30,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            16031
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::4\/128":[
+    {
+      "prefix":"2001:db8:1000::4\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
+      ]
+    }
+  ],
+  "2001:db8:1000::5\/128":[
+    {
+      "prefix":"2001:db8:1000::5\/128",
+      "protocol":"isis",
+      "selected":true,
+      "destSelected":true,
+      "distance":115,
+      "metric":20,
+      "installed":true,
+      "nexthops":[
+        {
+          "fib":true,
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "backupIndex":[
+            0
+          ],
+          "labels":[
+            3
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
+      ]
+    }
+  ]
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref
new file mode 100644 (file)
index 0000000..33dbf59
--- /dev/null
@@ -0,0 +1,214 @@
+{
+  "16010":{
+    "inLabel":16010,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.7.4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16010,
+        "installed":true,
+        "nexthop":"10.0.8.5"
+      }
+    ]
+  },
+  "16011":{
+    "inLabel":16011,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt4"
+      },
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16011,
+        "installed":true,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "16020":{
+    "inLabel":16020,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16020,
+        "installed":true,
+        "nexthop":"10.0.7.4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.8.5"
+      }
+    ]
+  },
+  "16021":{
+    "inLabel":16021,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16021,
+        "installed":true,
+        "interface":"eth-rt4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "16030":{
+    "inLabel":16030,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16030,
+        "installed":true,
+        "nexthop":"10.0.8.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "16031":{
+    "inLabel":16031,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16031,
+        "installed":true,
+        "interface":"eth-rt5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt4"
+      }
+    ]
+  },
+  "16040":{
+    "inLabel":16040,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.7.4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.8.5"
+      }
+    ]
+  },
+  "16041":{
+    "inLabel":16041,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt5"
+      }
+    ]
+  },
+  "16050":{
+    "inLabel":16050,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "nexthop":"10.0.8.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.7.4"
+      }
+    ]
+  },
+  "16051":{
+    "inLabel":16051,
+    "installed":true,
+    "nexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "installed":true,
+        "interface":"eth-rt5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt4"
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref b/tests/topotests/isis-tilfa-topo1/rt6/step1/show_yang_interface_isis_adjacencies.ref
new file mode 100644 (file)
index 0000000..7348323
--- /dev/null
@@ -0,0 +1,44 @@
+{
+  "frr-interface:lib": {
+    "interface": [
+      {
+        "name": "eth-rt4",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0004",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      },
+      {
+        "name": "eth-rt5",
+        "vrf": "default",
+        "state": {
+          "frr-isisd:isis": {
+            "adjacencies": {
+              "adjacency": [
+                {
+                  "neighbor-sys-type": "level-1",
+                  "neighbor-sysid": "0000.0000.0005",
+                  "hold-timer": 9,
+                  "neighbor-priority": 0,
+                  "state": "up"
+                }
+              ]
+            }
+          }
+        }
+      }
+    ]
+  }
+}
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step2/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step2/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step3/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step3/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..04adaef
--- /dev/null
@@ -0,0 +1,34 @@
+--- rt6/step3/show_ip_route.ref        2020-09-25 17:48:06.154925422 -0300
++++ rt6/step4/show_ip_route.ref        2020-09-25 17:49:02.583660484 -0300
+@@ -14,10 +14,7 @@
+           "ip":"10.0.7.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16010
+-          ]
++          "active":true
+         },
+         {
+           "fib":true,
+@@ -50,9 +47,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16020
+           ]
+         }
+       ],
+@@ -118,9 +112,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..20aa1ec
--- /dev/null
@@ -0,0 +1,34 @@
+--- rt6/step3/show_ipv6_route.ref      2020-09-25 17:48:07.434942087 -0300
++++ rt6/step4/show_ipv6_route.ref      2020-09-25 17:49:03.847676958 -0300
+@@ -22,10 +22,7 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4",
+-          "active":true,
+-          "labels":[
+-            16011
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -47,9 +44,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16021
+           ]
+         }
+       ],
+@@ -111,9 +105,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..3f24547
--- /dev/null
@@ -0,0 +1,79 @@
+--- rt6/step3/show_mpls_table.ref      2020-09-25 17:48:04.842908340 -0300
++++ rt6/step4/show_mpls_table.ref      2020-09-25 17:49:01.363644584 -0300
+@@ -7,12 +7,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16010,
+         "installed":true,
+-        "nexthop":"10.0.7.4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16010,
+-        "installed":true,
+         "nexthop":"10.0.8.5"
+       }
+     ]
+@@ -25,12 +19,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
+         "installed":true,
+-        "interface":"eth-rt4"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16011,
+-        "installed":true,
+         "interface":"eth-rt5"
+       }
+     ]
+@@ -123,50 +111,6 @@
+       }
+     ]
+   },
+-  "16040":{
+-    "inLabel":16040,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.7.4",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.8.5"
+-      }
+-    ]
+-  },
+-  "16041":{
+-    "inLabel":16041,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt4",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt5"
+-      }
+-    ]
+-  },
+   "16050":{
+     "inLabel":16050,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..9f73a29
--- /dev/null
@@ -0,0 +1,34 @@
+--- rt6/step4/show_ip_route.ref        2020-09-25 17:49:02.583660484 -0300
++++ rt6/step5/show_ip_route.ref        2020-09-25 17:50:13.220581632 -0300
+@@ -14,7 +14,10 @@
+           "ip":"10.0.7.4",
+           "afi":"ipv4",
+           "interfaceName":"eth-rt4",
+-          "active":true
++          "active":true,
++          "labels":[
++            16010
++          ]
+         },
+         {
+           "fib":true,
+@@ -47,6 +50,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16020
+           ]
+         }
+       ],
+@@ -112,6 +118,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..c9358d4
--- /dev/null
@@ -0,0 +1,34 @@
+--- rt6/step4/show_ipv6_route.ref      2020-09-25 17:49:03.847676958 -0300
++++ rt6/step5/show_ipv6_route.ref      2020-09-25 17:50:14.456597760 -0300
+@@ -22,7 +22,10 @@
+           "fib":true,
+           "afi":"ipv6",
+           "interfaceName":"eth-rt4",
+-          "active":true
++          "active":true,
++          "labels":[
++            16011
++          ]
+         }
+       ]
+     }
+@@ -44,6 +47,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16021
+           ]
+         }
+       ],
+@@ -105,6 +111,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..c9d6795
--- /dev/null
@@ -0,0 +1,79 @@
+--- rt6/step4/show_mpls_table.ref      2020-09-25 17:49:01.363644584 -0300
++++ rt6/step5/show_mpls_table.ref      2020-09-25 17:50:11.904564461 -0300
+@@ -7,6 +7,12 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16010,
+         "installed":true,
++        "nexthop":"10.0.7.4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16010,
++        "installed":true,
+         "nexthop":"10.0.8.5"
+       }
+     ]
+@@ -19,6 +25,12 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
+         "installed":true,
++        "interface":"eth-rt4"
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16011,
++        "installed":true,
+         "interface":"eth-rt5"
+       }
+     ]
+@@ -111,6 +123,50 @@
+       }
+     ]
+   },
++  "16040":{
++    "inLabel":16040,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.7.4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.8.5"
++      }
++    ]
++  },
++  "16041":{
++    "inLabel":16041,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt5"
++      }
++    ]
++  },
+   "16050":{
+     "inLabel":16050,
+     "installed":true,
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..527ec74
--- /dev/null
@@ -0,0 +1,20 @@
+--- rt6/step5/show_ip_route.ref        2020-09-25 17:50:13.220581632 -0300
++++ rt6/step6/show_ip_route.ref        2020-09-25 17:51:16.137402938 -0300
+@@ -26,7 +26,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16010
++            30010
+           ]
+         }
+       ]
+@@ -86,7 +86,7 @@
+             0
+           ],
+           "labels":[
+-            16030
++            30030
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..7b8f802
--- /dev/null
@@ -0,0 +1,20 @@
+--- rt6/step5/show_ipv6_route.ref      2020-09-25 17:50:14.456597760 -0300
++++ rt6/step6/show_ipv6_route.ref      2020-09-25 17:51:17.401419446 -0300
+@@ -15,7 +15,7 @@
+           "interfaceName":"eth-rt5",
+           "active":true,
+           "labels":[
+-            16011
++            30011
+           ]
+         },
+         {
+@@ -81,7 +81,7 @@
+             0
+           ],
+           "labels":[
+-            16031
++            30031
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..edd5afe
--- /dev/null
@@ -0,0 +1,38 @@
+--- rt6/step5/show_mpls_table.ref      2020-09-25 17:50:11.904564461 -0300
++++ rt6/step6/show_mpls_table.ref      2020-09-25 17:51:14.893386692 -0300
+@@ -11,7 +11,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16010,
++        "outLabel":30010,
+         "installed":true,
+         "nexthop":"10.0.8.5"
+       }
+@@ -29,7 +29,7 @@
+       },
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16011,
++        "outLabel":30011,
+         "installed":true,
+         "interface":"eth-rt5"
+       }
+@@ -85,7 +85,7 @@
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16030,
++        "outLabel":30030,
+         "installed":true,
+         "nexthop":"10.0.8.5",
+         "backupIndex":[
+@@ -107,7 +107,7 @@
+     "nexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16031,
++        "outLabel":30031,
+         "installed":true,
+         "interface":"eth-rt5",
+         "backupIndex":[
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..7553dd2
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt6/step6/show_ip_route.ref        2020-09-25 17:51:16.137402938 -0300
++++ rt6/step7/show_ip_route.ref        2020-09-25 17:52:03.018015363 -0300
+@@ -152,9 +152,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..b56890d
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt6/step6/show_ipv6_route.ref      2020-09-25 17:51:17.401419446 -0300
++++ rt6/step7/show_ipv6_route.ref      2020-09-25 17:52:04.270031723 -0300
+@@ -143,9 +143,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..ff043fb
--- /dev/null
@@ -0,0 +1,52 @@
+--- rt6/step6/show_mpls_table.ref      2020-09-25 17:51:14.893386692 -0300
++++ rt6/step7/show_mpls_table.ref      2020-09-25 17:52:01.809999577 -0300
+@@ -166,49 +166,5 @@
+         "interface":"eth-rt5"
+       }
+     ]
+-  },
+-  "16050":{
+-    "inLabel":16050,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.8.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "nexthop":"10.0.7.4"
+-      }
+-    ]
+-  },
+-  "16051":{
+-    "inLabel":16051,
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "installed":true,
+-        "interface":"eth-rt5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":3,
+-        "interface":"eth-rt4"
+-      }
+-    ]
+   }
+ }
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..d0b25bf
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt6/step7/show_ip_route.ref        2020-09-25 17:52:03.018015363 -0300
++++ rt6/step8/show_ip_route.ref        2020-09-25 17:53:21.035035298 -0300
+@@ -152,6 +152,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..2031755
--- /dev/null
@@ -0,0 +1,12 @@
+--- rt6/step7/show_ipv6_route.ref      2020-09-25 17:52:04.270031723 -0300
++++ rt6/step8/show_ipv6_route.ref      2020-09-25 17:53:22.239051045 -0300
+@@ -143,6 +143,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..535f30b
--- /dev/null
@@ -0,0 +1,52 @@
+--- rt6/step7/show_mpls_table.ref      2020-09-25 17:52:01.809999577 -0300
++++ rt6/step8/show_mpls_table.ref      2020-09-25 17:53:19.799019132 -0300
+@@ -166,5 +166,49 @@
+         "interface":"eth-rt5"
+       }
+     ]
++  },
++  "16050":{
++    "inLabel":16050,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "nexthop":"10.0.8.5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "nexthop":"10.0.7.4"
++      }
++    ]
++  },
++  "16051":{
++    "inLabel":16051,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "installed":true,
++        "interface":"eth-rt5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":3,
++        "interface":"eth-rt4"
++      }
++    ]
+   }
+ }
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ip_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ip_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ipv6_route.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_ipv6_route.ref.diff
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff b/tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff
new file mode 100644 (file)
index 0000000..b6e5396
--- /dev/null
@@ -0,0 +1,24 @@
+--- rt6/step8/show_mpls_table.ref      2020-09-25 17:53:19.799019132 -0300
++++ rt6/step9/show_mpls_table.ref      2020-09-25 17:54:37.492035644 -0300
+@@ -167,8 +167,8 @@
+       }
+     ]
+   },
+-  "16050":{
+-    "inLabel":16050,
++  "16500":{
++    "inLabel":16500,
+     "installed":true,
+     "nexthops":[
+       {
+@@ -189,8 +189,8 @@
+       }
+     ]
+   },
+-  "16051":{
+-    "inLabel":16051,
++  "16501":{
++    "inLabel":16501,
+     "installed":true,
+     "nexthops":[
+       {
diff --git a/tests/topotests/isis-tilfa-topo1/rt6/zebra.conf b/tests/topotests/isis-tilfa-topo1/rt6/zebra.conf
new file mode 100644 (file)
index 0000000..6084010
--- /dev/null
@@ -0,0 +1,22 @@
+log file zebra.log
+!
+hostname rt6
+!
+debug zebra kernel
+debug zebra packet
+debug zebra mpls
+!
+interface lo
+ ip address 6.6.6.6/32
+ ipv6 address 2001:db8:1000::6/128
+!
+interface eth-rt4
+ ip address 10.0.7.6/24
+!
+interface eth-rt5
+ ip address 10.0.8.6/24
+!
+ip forwarding
+!
+line vty
+!
diff --git a/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py b/tests/topotests/isis-tilfa-topo1/test_isis_tilfa_topo1.py
new file mode 100755 (executable)
index 0000000..6bc097b
--- /dev/null
@@ -0,0 +1,674 @@
+#!/usr/bin/env python
+
+#
+# test_isis_tilfa_topo1.py
+# Part of NetDEF Topology Tests
+#
+# Copyright (c) 2020 by
+# Network Device Education Foundation, Inc. ("NetDEF")
+#
+# 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_isis_tilfa_topo1.py:
+
+                         +---------+
+                         |         |
+                         |   RT1   |
+                         | 1.1.1.1 |
+                         |         |
+                         +---------+
+                              |eth-sw1
+                              |
+                              |
+                              |
+         +---------+          |          +---------+
+         |         |          |          |         |
+         |   RT2   |eth-sw1   |   eth-sw1|   RT3   |
+         | 2.2.2.2 +----------+----------+ 3.3.3.3 |
+         |         |     10.0.1.0/24     |         |
+         +---------+                     +---------+
+    eth-rt4-1|  |eth-rt4-2          eth-rt5-1|  |eth-rt5-2
+             |  |                            |  |
+  10.0.2.0/24|  |10.0.3.0/24      10.0.4.0/24|  |10.0.5.0/24
+             |  |                            |  |
+    eth-rt2-1|  |eth-rt2-2          eth-rt3-1|  |eth-rt3-2
+         +---------+                     +---------+
+         |         |                     |         |
+         |   RT4   |     10.0.6.0/24     |   RT5   |
+         | 4.4.4.4 +---------------------+ 5.5.5.5 |
+         |         |eth-rt5       eth-rt4|         |
+         +---------+                     +---------+
+       eth-rt6|                                |eth-rt6
+              |                                |
+   10.0.7.0/24|                                |10.0.8.0/24
+              |          +---------+           |
+              |          |         |           |
+              |          |   RT6   |           |
+              +----------+ 6.6.6.6 +-----------+
+                  eth-rt4|         |eth-rt5
+                         +---------+
+"""
+
+import os
+import sys
+import pytest
+import json
+import re
+import tempfile
+from time import sleep
+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
+
+# Required to instantiate the topology builder class.
+from mininet.topo import Topo
+
+# Global multi-dimensional dictionary containing all expected outputs
+outputs = {}
+
+class TemplateTopo(Topo):
+    "Test topology builder"
+    def build(self, *_args, **_opts):
+        "Build function"
+        tgen = get_topogen(self)
+
+        #
+        # Define FRR Routers
+        #
+        for router in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+            tgen.add_router(router)
+
+        #
+        # Define connections
+        #
+        switch = tgen.add_switch('s1')
+        switch.add_link(tgen.gears['rt1'], nodeif="eth-sw1")
+        switch.add_link(tgen.gears['rt2'], nodeif="eth-sw1")
+        switch.add_link(tgen.gears['rt3'], nodeif="eth-sw1")
+
+        switch = tgen.add_switch('s2')
+        switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-1")
+        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-1")
+
+        switch = tgen.add_switch('s3')
+        switch.add_link(tgen.gears['rt2'], nodeif="eth-rt4-2")
+        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt2-2")
+
+        switch = tgen.add_switch('s4')
+        switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-1")
+        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-1")
+
+        switch = tgen.add_switch('s5')
+        switch.add_link(tgen.gears['rt3'], nodeif="eth-rt5-2")
+        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt3-2")
+
+        switch = tgen.add_switch('s6')
+        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt5")
+        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt4")
+
+        switch = tgen.add_switch('s7')
+        switch.add_link(tgen.gears['rt4'], nodeif="eth-rt6")
+        switch.add_link(tgen.gears['rt6'], nodeif="eth-rt4")
+
+        switch = tgen.add_switch('s8')
+        switch.add_link(tgen.gears['rt5'], nodeif="eth-rt6")
+        switch.add_link(tgen.gears['rt6'], nodeif="eth-rt5")
+
+        #
+        # Populate multi-dimensional dictionary containing all expected outputs
+        #
+        files = ["show_ip_route.ref",
+                 "show_ipv6_route.ref",
+                 "show_mpls_table.ref",
+                 "show_yang_interface_isis_adjacencies.ref"]
+        for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+            outputs[rname] = {}
+            for step in range(1, 9 + 1):
+                outputs[rname][step] = {}
+                for file in files:
+                    if step == 1:
+                        # Get snapshots relative to the expected initial network convergence
+                        filename = '{}/{}/step{}/{}'.format(CWD, rname, step, file)
+                        outputs[rname][step][file] = open(filename).read()
+                    else:
+                        if file == "show_yang_interface_isis_adjacencies.ref":
+                            continue
+
+                        # Get diff relative to the previous step
+                        filename = '{}/{}/step{}/{}.diff'.format(CWD, rname, step, file)
+
+                        # Create temporary files in order to apply the diff
+                        f_in = tempfile.NamedTemporaryFile()
+                        f_in.write(outputs[rname][step - 1][file])
+                        f_in.flush()
+                        f_out = tempfile.NamedTemporaryFile()
+                        os.system("patch -s -o %s %s %s" %(f_out.name, f_in.name, filename))
+
+                        # Store the updated snapshot and remove the temporary files
+                        outputs[rname][step][file] = open(f_out.name).read()
+                        f_in.close()
+                        f_out.close()
+
+def setup_module(mod):
+    "Sets up the pytest environment"
+    tgen = Topogen(TemplateTopo, mod.__name__)
+    tgen.start_topology()
+
+    router_list = tgen.routers()
+
+    # For all registered routers, load the zebra configuration file
+    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_ISIS,
+            os.path.join(CWD, '{}/isisd.conf'.format(rname))
+        )
+
+    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 router_compare_json_output(rname, command, reference):
+    "Compare router JSON output"
+
+    logger.info('Comparing router "%s" "%s" output', rname, command)
+
+    tgen = get_topogen()
+    expected = json.loads(reference)
+
+    # Run test function until we get an result. Wait at most 60 seconds.
+    test_func = partial(topotest.router_json_cmp,
+        tgen.gears[rname], command, expected)
+    _, diff = topotest.run_and_expect(test_func, None, count=120, wait=0.5)
+    assertmsg = '"{}" JSON output mismatches the expected result'.format(rname)
+    assert diff is None, assertmsg
+
+#
+# Step 1
+#
+# Test initial network convergence
+#
+def test_isis_adjacencies_step1():
+    logger.info("Test (step 1): check IS-IS adjacencies")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show yang operational-data /frr-interface:lib isisd",
+                                   outputs[rname][1]["show_yang_interface_isis_adjacencies.ref"])
+
+def test_rib_ipv4_step1():
+    logger.info("Test (step 1): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][1]["show_ip_route.ref"])
+
+def test_rib_ipv6_step1():
+    logger.info("Test (step 1): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][1]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step1():
+    logger.info("Test (step 1): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][1]["show_mpls_table.ref"])
+
+#
+# Step 2
+#
+# Action(s):
+# -Disable TI-LFA link protection on rt2's eth-sw1 interface
+#
+# Expected changes:
+# -rt2 should uninstall the backup nexthops from destinations reachable over eth-sw1.
+#
+def test_rib_ipv4_step2():
+    logger.info("Test (step 2): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Disabling TI-LFA link protection on rt2\'s eth-sw1 interface')
+    tgen.net['rt2'].cmd('vtysh -c "conf t" -c "interface eth-sw1" -c "no isis fast-reroute ti-lfa"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][2]["show_ip_route.ref"])
+
+def test_rib_ipv6_step2():
+    logger.info("Test (step 2): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][2]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step2():
+    logger.info("Test (step 2): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][2]["show_mpls_table.ref"])
+
+#
+# Step 3
+#
+# Action(s):
+# -Enable TI-LFA link protection on rt2's eth-sw1 interface
+#
+# Expected changes:
+# -rt2 should install backup nexthops for destinations reachable over eth-sw1.
+#
+def test_rib_ipv4_step3():
+    logger.info("Test (step 3): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Enabling TI-LFA link protection on rt2\'s eth-sw1 interface')
+    tgen.net['rt2'].cmd('vtysh -c "conf t" -c "interface eth-sw1" -c "isis fast-reroute ti-lfa"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][3]["show_ip_route.ref"])
+
+def test_rib_ipv6_step3():
+    logger.info("Test (step 3): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][3]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step3():
+    logger.info("Test (step 3): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][3]["show_mpls_table.ref"])
+
+#
+# Step 4
+#
+# Action(s):
+# -Disable SR on rt4
+#
+# Expected changes:
+# -rt4 should uninstall all Prefix-SIDs from the network
+# -rt4 should uninstall all TI-LFA backup nexthops
+# -All routers should uninstall rt4's Prefix-SIDs
+# -All routers should uninstall all SR labels for destinations whose nexthop is rt4
+# -All routers should uninstall all TI-LFA backup nexthops that point to rt4
+# -All routers should uninstall all TI-LFA backup nexthops that use rt4's Prefix-SIDs
+#
+def test_rib_ipv4_step4():
+    logger.info("Test (step 4): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Disabling SR on rt4')
+    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing on"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][4]["show_ip_route.ref"])
+
+def test_rib_ipv6_step4():
+    logger.info("Test (step 4): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][4]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step4():
+    logger.info("Test (step 4): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][4]["show_mpls_table.ref"])
+
+#
+# Step 5
+#
+# Action(s):
+# -Enable SR on rt4
+#
+# Expected changes:
+# -Reverse all changes done on the previous step
+#
+def test_rib_ipv4_step5():
+    logger.info("Test (step 5): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Enabling SR on rt4')
+    tgen.net['rt4'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing on"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][5]["show_ip_route.ref"])
+
+def test_rib_ipv6_step5():
+    logger.info("Test (step 5): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][5]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step5():
+    logger.info("Test (step 5): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][5]["show_mpls_table.ref"])
+
+#
+# Step 6
+#
+# Action(s):
+# -Change rt5's SRGB
+#
+# Expected changes:
+# -All routers should update all SR labels for destinations whose primary or backup nexthop is rt5
+#
+def test_rib_ipv4_step6():
+    logger.info("Test (step 6): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Changing rt5\'s SRGB')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing global-block 30000 37999"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][6]["show_ip_route.ref"])
+
+def test_rib_ipv6_step6():
+    logger.info("Test (step 6): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][6]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step6():
+    logger.info("Test (step 6): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][6]["show_mpls_table.ref"])
+
+#
+# Step 7
+#
+# Action(s):
+# -Delete rt5's Prefix-SIDs
+#
+# Expected changes:
+# -All routers should uninstall rt5's Prefix-SIDs
+# -All routers should uninstall all TI-LFA backup nexthops that use rt5's Prefix-SIDs
+#
+def test_rib_ipv4_step7():
+    logger.info("Test (step 7): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Deleting rt5\'s Prefix-SIDs')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 5.5.5.5/32 index 50"')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "no segment-routing prefix 2001:db8:1000::5/128 index 51"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][7]["show_ip_route.ref"])
+
+def test_rib_ipv6_step7():
+    logger.info("Test (step 7): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][7]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step7():
+    logger.info("Test (step 7): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][7]["show_mpls_table.ref"])
+
+#
+# Step 8
+#
+# Action(s):
+# -Re-add rt5's Prefix-SIDs
+#
+# Expected changes:
+# -Reverse all changes done on the previous step
+#
+def test_rib_ipv4_step8():
+    logger.info("Test (step 8): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Re-adding rt5\'s Prefix-SIDs')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 5.5.5.5/32 index 50"')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::5/128 index 51"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][8]["show_ip_route.ref"])
+
+def test_rib_ipv6_step8():
+    logger.info("Test (step 8): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][8]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step8():
+    logger.info("Test (step 8): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][8]["show_mpls_table.ref"])
+
+#
+# Step 9
+#
+# Action(s):
+# -Change rt5's Prefix-SIDs
+#
+# Expected changes:
+# -All routers should update rt5's Prefix-SIDs
+# -All routers should update all TI-LFA backup nexthops that use rt5's Prefix-SIDs
+#
+def test_rib_ipv4_step9():
+    logger.info("Test (step 9): verify IPv4 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    logger.info('Re-adding rt5\'s Prefix-SIDs')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 5.5.5.5/32 index 500"')
+    tgen.net['rt5'].cmd('vtysh -c "conf t" -c "router isis 1" -c "segment-routing prefix 2001:db8:1000::5/128 index 501"')
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ip route isis json",
+                                   outputs[rname][9]["show_ip_route.ref"])
+
+def test_rib_ipv6_step9():
+    logger.info("Test (step 9): verify IPv6 RIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show ipv6 route isis json",
+                                   outputs[rname][9]["show_ipv6_route.ref"])
+
+def test_mpls_lib_step9():
+    logger.info("Test (step 9): verify MPLS LIB")
+    tgen = get_topogen()
+
+    # Skip if previous fatal error condition is raised
+    if tgen.routers_have_failure():
+        pytest.skip(tgen.errors)
+
+    for rname in ['rt1', 'rt2', 'rt3', 'rt4', 'rt5', 'rt6']:
+        router_compare_json_output(rname, "show mpls table json",
+                                   outputs[rname][9]["show_mpls_table.ref"])
+
+# Memory leak test template
+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 4ac4597015c6f1976cabbe12646916f87fd95881..5fb4c14d0bef216d899dea2f831d388afccaf264 100755 (executable)
@@ -8,6 +8,7 @@ interface r1-eth0
  isis circuit-type level-2-only
 !
 router isis 1 vrf r1-cust1 
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00
  metric-style wide
  redistribute ipv4 connected level-2
index 77d2ad9c6302aff87a5aa0c32e644ce885e69e42..f0a3593a4c4e72a4ce8296eb85c73627dcb5594d 100644 (file)
     }
   ], 
   "10.0.20.0/24": [
-    {
-      "distance": 115, 
-      "metric": 20, 
-      "nexthops": [
-        {
-          "afi": "ipv4", 
-          "interfaceName": "r1-eth0", 
-          "ip": "10.0.20.1" 
-        }
-      ], 
-      "prefix": "10.0.20.0/24", 
-      "protocol": "isis", 
-      "vrfName": "r1-cust1"
-    }, 
     {
       "nexthops": [
         {
index 4c6854026514a89cd56d47354f3a2f63449d5921..0d2bc7ab72036c8d9af0926fee3b22cde51eca87 100755 (executable)
@@ -8,6 +8,7 @@ interface r2-eth0
  isis circuit-type level-2-only
 !
 router isis 1 vrf r2-cust1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
  metric-style wide
  redistribute ipv4 connected level-2
index 98252c59399749158fbc981627bd6014e55060c9..a26cdfad8eb68c4536944e2ce8d31bcce0be7f75 100644 (file)
     }
   ], 
   "10.0.21.0/24": [
-    {
-      "distance": 115, 
-      "metric": 20, 
-      "nexthops": [
-        {
-          "afi": "ipv4", 
-          "interfaceName": "r2-eth0", 
-          "ip": "10.0.21.1" 
-        }
-      ], 
-      "prefix": "10.0.21.0/24", 
-      "protocol": "isis", 
-      "vrfName": "r2-cust1"
-    }, 
     {
       "nexthops": [
         {
index ca01876690d2876241f634dcd36cacf4e696488b..66092407aba493b581a73136e2a3554fe18bedc4 100755 (executable)
@@ -13,6 +13,7 @@ interface r3-eth1
  isis circuit-type level-1
 !
 router isis 1 vrf r3-cust1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
  metric-style wide
  redistribute ipv4 connected level-1
index de158876f198c9a9ef512dab89fa932124477cb0..9717df5c1afdeb7d85b305e216b336ba87e50d8a 100644 (file)
     }
   ], 
   "10.0.20.0/24": [
-    {
-      "distance": 115, 
-      "metric": 20, 
-      "nexthops": [
-        {
-          "afi": "ipv4", 
-          "interfaceName": "r3-eth0", 
-          "ip": "10.0.20.2" 
-        }
-      ], 
-      "prefix": "10.0.20.0/24", 
-      "protocol": "isis", 
-      "vrfName": "r3-cust1"
-    }, 
     {
       "nexthops": [
         {
index 74b1603d85b7c13a5a1bb2a29e4ff30abc7561a5..05815e84183850c79c380ccf0898d4acfcf24a9e 100755 (executable)
@@ -16,6 +16,7 @@ interface r4-eth1
  isis circuit-type level-1
 !
 router isis 1 vrf r4-cust1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0004.00
  metric-style wide
  redistribute ipv4 connected level-1
index b3ed4f2cbe9604acf13181709f32626297f1d36c..6cb79b03015d9a9a6647ade61f2ba71c20035fb3 100644 (file)
     }
   ], 
   "10.0.21.0/24": [
-    {
-      "nexthops": [
-        {
-          "afi": "ipv4", 
-          "interfaceName": "r4-eth0", 
-          "ip": "10.0.21.2" 
-        }
-      ], 
-      "prefix": "10.0.21.0/24", 
-      "protocol": "isis", 
-      "vrfName": "r4-cust1"
-    }, 
     {
       "nexthops": [
         {
index 9e9b030455a41920ee695e12166d9c102c543ce1..f663c33fe9b1ca7b3410a0211b55e19805a7bc92 100755 (executable)
@@ -13,6 +13,7 @@ interface r5-eth1
  isis circuit-type level-1
 !
 router isis 1 vrf r5-cust1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0005.00
  metric-style wide
  is-type level-1
index 7943b94189d5ee4d821e354ef58cfead2f2ac4fd..12121e4ddf65cf3ff2df876cf489d7882c772b6b 100644 (file)
@@ -82,6 +82,7 @@ class ISISTopo1(Topo):
         sw.add_link(tgen.gears["r4"])
         sw.add_link(tgen.gears["r5"])
 
+
 def setup_module(mod):
     "Sets up the pytest environment"
     tgen = Topogen(ISISTopo1, mod.__name__)
@@ -129,16 +130,14 @@ def setup_module(mod):
 
     for rname, router in tgen.routers().items():
         router.load_config(
-            TopoRouter.RD_ZEBRA, 
-            os.path.join(CWD, "{}/zebra.conf".format(rname))
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
         )
         router.load_config(
-            TopoRouter.RD_ISIS, 
-            os.path.join(CWD, "{}/isisd.conf".format(rname))
+            TopoRouter.RD_ISIS, os.path.join(CWD, "{}/isisd.conf".format(rname))
         )
     # After loading the configurations, this function loads configured daemons.
     tgen.start_router()
-    
+
     has_version_20 = False
     for router in tgen.routers().values():
         if router.has_version("<", "4"):
@@ -148,6 +147,7 @@ def setup_module(mod):
         logger.info("Skipping ISIS vrf tests for FRR 2.0")
         tgen.set_error("ISIS has convergence problems with IPv6")
 
+
 def teardown_module(mod):
     "Teardown the pytest environment"
     tgen = get_topogen()
@@ -155,6 +155,7 @@ def teardown_module(mod):
     # delete rx-vrf
     tgen.stop_topology()
 
+
 def test_isis_convergence():
     "Wait for the protocol to converge before starting to test"
     tgen = get_topogen()
@@ -163,10 +164,11 @@ def test_isis_convergence():
         pytest.skip(tgen.errors)
 
     logger.info("waiting for ISIS protocol to converge")
+
     for rname, router in tgen.routers().items():
         filename = "{0}/{1}/{1}_topology.json".format(CWD, rname)
         expected = json.loads(open(filename).read())
+
         def compare_isis_topology(router, expected):
             "Helper function to test ISIS vrf topology convergence."
             actual = show_isis_topology(router)
@@ -177,6 +179,7 @@ def test_isis_convergence():
         (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=120)
         assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
 
+
 def test_isis_route_installation():
     "Check whether all expected routes are present"
     tgen = get_topogen()
@@ -189,7 +192,9 @@ def test_isis_route_installation():
     for rname, router in tgen.routers().items():
         filename = "{0}/{1}/{1}_route.json".format(CWD, rname)
         expected = json.loads(open(filename, "r").read())
-        actual = router.vtysh_cmd("show ip route vrf {0}-cust1 json".format(rname) , isjson=True)
+        actual = router.vtysh_cmd(
+            "show ip route vrf {0}-cust1 json".format(rname), isjson=True
+        )
         # Older FRR versions don't list interfaces in some ISIS routes
         if router.has_version("<", "3.1"):
             for network, routes in expected.items():
@@ -209,7 +214,7 @@ def test_isis_linux_route_installation():
 
     dist = platform.dist()
 
-    if (dist[1] == "16.04"):
+    if dist[1] == "16.04":
         pytest.skip("Kernel not supported for vrf")
 
     "Check whether all expected routes are present and installed in the OS"
@@ -234,6 +239,7 @@ def test_isis_linux_route_installation():
         assertmsg = "Router '{}' OS routes mismatch".format(rname)
         assert topotest.json_cmp(actual, expected) is None, assertmsg
 
+
 def test_isis_route6_installation():
     "Check whether all expected routes are present"
     tgen = get_topogen()
@@ -246,7 +252,9 @@ def test_isis_route6_installation():
     for rname, router in tgen.routers().items():
         filename = "{0}/{1}/{1}_route6.json".format(CWD, rname)
         expected = json.loads(open(filename, "r").read())
-        actual = router.vtysh_cmd("show ipv6 route vrf {}-cust1 json".format(rname) , isjson=True)
+        actual = router.vtysh_cmd(
+            "show ipv6 route vrf {}-cust1 json".format(rname), isjson=True
+        )
 
         # Older FRR versions don't list interfaces in some ISIS routes
         if router.has_version("<", "3.1"):
@@ -262,11 +270,12 @@ def test_isis_route6_installation():
         assertmsg = "Router '{}' routes mismatch".format(rname)
         assert topotest.json_cmp(actual, expected) is None, assertmsg
 
+
 def test_isis_linux_route6_installation():
 
     dist = platform.dist()
 
-    if (dist[1] == "16.04"):
+    if dist[1] == "16.04":
         pytest.skip("Kernel not supported for vrf")
 
     "Check whether all expected routes are present and installed in the OS"
@@ -291,6 +300,7 @@ def test_isis_linux_route6_installation():
         assertmsg = "Router '{}' OS routes mismatch".format(rname)
         assert topotest.json_cmp(actual, expected) is None, assertmsg
 
+
 def test_memory_leak():
     "Run the memory leak test and report results."
     tgen = get_topogen()
@@ -452,4 +462,3 @@ def show_isis_topology(router):
 
     dict_merge(l1, l2)
     return l1
-
index ee7dba3692599d686c303c9aa9379d0cbd3fea04..4e3761e5a1e93d2be6b06aed912efc616d2227b4 100644 (file)
@@ -4,10 +4,12 @@ debug isis events
 debug isis update-packets
 interface r1-eth0
  ip router isis 1
+ isis hello-interval 2
  ipv6 router isis 1
  isis circuit-type level-2-only
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0000.00
  metric-style wide
  redistribute ipv4 connected level-2
index 123b4dd16333488f3f238262ce3f1949f0eddd17..f94233a80f56f139bcaa66036cc1f2fc19febeff 100644 (file)
     }
   ],
   "10.0.20.0/24": [
-    {
-      "distance": 115,
-      "metric": 10,
-      "nexthops": [
-        {
-          "afi": "ipv4",
-          "interfaceName": "r1-eth0",
-          "ip": "10.0.20.1"
-        }
-      ],
-      "prefix": "10.0.20.0/24",
-      "protocol": "isis"
-    },
     {
       "nexthops": [
         {
index f6fee6c84560ab8658e4a26672b2b20385fba250..14db0940ece544c143d127feae1dc20fd33d6f20 100644 (file)
@@ -4,10 +4,12 @@ debug isis events
 debug isis update-packets
 interface r2-eth0
  ip router isis 1
+ isis hello-interval 2
  ipv6 router isis 1
  isis circuit-type level-2-only
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
  metric-style wide
  redistribute ipv4 connected level-2
index fe2de057342bcf4d6c714be677b5aa1df8b0d7dd..aab651eff056f6b4bbd19e0205ae9050a4d674bf 100644 (file)
     }
   ],
   "10.0.21.0/24": [
-    {
-      "distance": 115,
-      "metric": 10,
-      "nexthops": [
-        {
-          "afi": "ipv4",
-          "interfaceName": "r2-eth0",
-          "ip": "10.0.21.1"
-        }
-      ],
-      "prefix": "10.0.21.0/24",
-      "protocol": "isis"
-    },
     {
       "nexthops": [
         {
index 4ae56b4af4364ce784291ffecf905b7b52be71ca..6f36c0fa361b95a5a44c384c5b0e9ef1c056cf80 100644 (file)
@@ -4,6 +4,7 @@ debug isis events
 debug isis update-packets
 interface r3-eth0
  ip router isis 1
+ isis hello-interval 2
  ipv6 router isis 1
  isis circuit-type level-2-only
 !
@@ -13,6 +14,7 @@ interface r3-eth1
  isis circuit-type level-1
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
  metric-style wide
  redistribute ipv4 connected level-1
index 1f0fcdfcd6471110b3a226b4978a7d991374a8ee..61d05e80bbfeb5fcfed735bab4d2b83a8b970117 100644 (file)
     }
   ],
   "10.0.20.0/24": [
-    {
-      "distance": 115,
-      "metric": 10,
-      "nexthops": [
-        {
-          "afi": "ipv4",
-          "interfaceName": "r3-eth0",
-          "ip": "10.0.20.2"
-        }
-      ],
-      "prefix": "10.0.20.0/24",
-      "protocol": "isis"
-    },
     {
       "nexthops": [
         {
index bf9653387ec995211b40574a093561545a00ad37..502e035f50bc50b8fcdc5bdc0c7957cf14092ab8 100644 (file)
@@ -4,6 +4,7 @@ debug isis events
 debug isis update-packets
 interface r4-eth0
  ip router isis 1
+ isis hello-interval 2
  ipv6 router isis 1
  isis circuit-type level-2-only
 !
@@ -13,6 +14,7 @@ interface r4-eth1
  isis circuit-type level-1
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0004.00
  metric-style wide
  redistribute ipv4 connected level-1
index 597e953c09faf4ff7961b5ae35bac76c726e2a9e..79361af4b566ed0414ba06713a61bf33c563aee0 100644 (file)
     }
   ],
   "10.0.21.0/24": [
-    {
-      "distance": 115,
-      "metric": 10,
-      "nexthops": [
-        {
-          "afi": "ipv4",
-          "interfaceName": "r4-eth0",
-          "ip": "10.0.21.2"
-        }
-      ],
-      "prefix": "10.0.21.0/24",
-      "protocol": "isis"
-    },
     {
       "nexthops": [
         {
index 5a044988a95d0b8c578ef6127682b14d3e31a2f6..42493a4991041e6baf571f052a9de47e52e747a4 100644 (file)
@@ -4,6 +4,7 @@ debug isis events
 debug isis update-packets
 interface r5-eth0
  ip router isis 1
+ isis hello-interval 2
  ipv6 router isis 1
  isis circuit-type level-1
 !
@@ -13,6 +14,7 @@ interface r5-eth1
  isis circuit-type level-1
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0005.00
  metric-style wide
  is-type level-1
index af8d117bc1b3e07cdcbd568df6de46cef354d051..da2970d94ec66054ed8f9375af299de06996eac9 100644 (file)
@@ -6,6 +6,7 @@ debug isis update-packets
 debug isis ldp-sync
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0001.00
  metric-style wide
  redistribute ipv4 connected level-1
index e477bce8279f2c96ef270133d64d96497b5b03fd..b29a2b93eeeb6876c22f0a49e77fcc22d7b048f8 100644 (file)
@@ -6,6 +6,7 @@ debug isis update-packets
 debug isis ldp-sync
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0002.00
  metric-style wide
  redistribute ipv4 connected level-1
index e50fb077ba51cb2b99f51e6080836525dc9d363a..4c8499f23d967e9c7b383d80dbc45c1c838b1964 100644 (file)
@@ -6,6 +6,7 @@ debug isis update-packets
 debug isis ldp-sync
 !
 router isis 1
+ lsp-gen-interval 2
  net 10.0000.0000.0000.0000.0000.0000.0000.0000.0003.00
  metric-style wide
  redistribute ipv4 connected level-1
index d339b7bd7b3f14f3d820d4eec1347cf635714997..331e6fafd41d800cec02c2b5a08a4f2b7dab329c 100644 (file)
@@ -182,7 +182,9 @@ def test_isis_convergence():
         router_compare_json_output(
             rname,
             "show yang operational-data /frr-interface:lib isisd",
-            "show_yang_interface_isis_adjacencies.ref")
+            "show_yang_interface_isis_adjacencies.ref",
+        )
+
 
 def test_rib():
     logger.info("Test: verify RIB")
@@ -265,6 +267,7 @@ def test_ldp_pseudowires():
             rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref"
         )
 
+
 def test_ldp_igp_sync():
     logger.info("Test: verify LDP igp-sync")
     tgen = get_topogen()
@@ -278,6 +281,7 @@ def test_ldp_igp_sync():
             rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
         )
 
+
 def test_isis_ldp_sync():
     logger.info("Test: verify ISIS igp-sync")
     tgen = get_topogen()
@@ -287,9 +291,7 @@ def test_isis_ldp_sync():
         pytest.skip(tgen.errors)
 
     for rname in ["r1", "r2", "r3"]:
-        (result, diff) = validate_show_isis_ldp_sync(
-            rname, "show_isis_ldp_sync.ref"
-        )
+        (result, diff) = validate_show_isis_ldp_sync(rname, "show_isis_ldp_sync.ref")
         assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
 
     for rname in ["r1", "r2", "r3"]:
@@ -320,7 +322,9 @@ def test_r1_eth1_shutdown():
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+            rname,
+            "show mpls ldp igp-sync json",
+            "show_ldp_igp_sync_r1_eth1_shutdown.ref",
         )
 
     for rname in ["r1", "r2", "r3"]:
@@ -355,9 +359,7 @@ def test_r1_eth1_no_shutdown():
         )
 
     for rname in ["r1", "r2", "r3"]:
-        (result, diff) = validate_show_isis_ldp_sync(
-            rname, "show_isis_ldp_sync.ref"
-        )
+        (result, diff) = validate_show_isis_ldp_sync(rname, "show_isis_ldp_sync.ref")
         assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
 
     for rname in ["r1", "r2", "r3"]:
@@ -382,7 +384,9 @@ def test_r2_eth1_shutdown():
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+            rname,
+            "show mpls ldp igp-sync json",
+            "show_ldp_igp_sync_r1_eth1_shutdown.ref",
         )
 
     for rname in ["r1", "r2", "r3"]:
@@ -417,9 +421,7 @@ def test_r2_eth1_no_shutdown():
         )
 
     for rname in ["r1", "r2", "r3"]:
-        (result, diff) = validate_show_isis_ldp_sync(
-            rname, "show_isis_ldp_sync.ref"
-        )
+        (result, diff) = validate_show_isis_ldp_sync(rname, "show_isis_ldp_sync.ref")
         assert result, "ISIS did not converge on {}:\n{}".format(rname, diff)
 
     for rname in ["r1", "r2", "r3"]:
@@ -448,6 +450,7 @@ if __name__ == "__main__":
 # Auxiliary functions
 #
 
+
 def parse_show_isis_ldp_sync(lines, rname):
     """
     Parse the output of 'show isis mpls ldp sync' into a Python dict.
@@ -461,23 +464,23 @@ def parse_show_isis_ldp_sync(lines, rname):
             interface = {}
             interface_name = None
 
-            line = it.next();
+            line = it.next()
 
             if line.startswith(rname + "-eth"):
                 interface_name = line
 
-            line = it.next();
+            line = it.next()
 
             if line.startswith(" LDP-IGP Synchronization enabled: "):
                 interface["ldpIgpSyncEnabled"] = line.endswith("yes")
-                line = it.next();
+                line = it.next()
 
                 if line.startswith(" holddown timer in seconds: "):
-                     interface["holdDownTimeInSec"] = int(line.split(": ")[-1])
-                     line = it.next();
+                    interface["holdDownTimeInSec"] = int(line.split(": ")[-1])
+                    line = it.next()
 
                 if line.startswith(" State: "):
-                     interface["ldpIgpSyncState"] = line.split(": ")[-1]
+                    interface["ldpIgpSyncState"] = line.split(": ")[-1]
 
             elif line.startswith(" Interface "):
                 interface["Interface"] = line.endswith("down")
@@ -534,7 +537,7 @@ def parse_show_isis_interface_detail(lines, rname):
 
     while True:
         try:
-            line = it.next();
+            line = it.next()
 
             area_match = re.match(r"Area (.+):", line)
             if not area_match:
@@ -543,34 +546,36 @@ def parse_show_isis_interface_detail(lines, rname):
             area_id = area_match.group(1)
             area = {}
 
-            line = it.next();
+            line = it.next()
 
             while line.startswith(" Interface: "):
-                interface_name = re.split(':|,', line)[1].lstrip()
+                interface_name = re.split(":|,", line)[1].lstrip()
 
-                area[interface_name]= []
+                area[interface_name] = []
 
                 # Look for keyword: Level-1 or Level-2
                 while not line.startswith(" Level-"):
-                    line = it.next();
+                    line = it.next()
 
                 while line.startswith(" Level-"):
 
                     level = {}
 
                     level_name = line.split()[0]
-                    level['level'] = level_name
+                    level["level"] = level_name
 
-                    line = it.next();
+                    line = it.next()
 
                     if line.startswith(" Metric:"):
-                        level['metric'] = re.split(':|,', line)[1].lstrip()
+                        level["metric"] = re.split(":|,", line)[1].lstrip()
 
                     area[interface_name].append(level)
 
                     # Look for keyword: Level-1 or Level-2 or Interface:
-                    while not line.startswith(" Level-") and not line.startswith(" Interface: "):
-                        line = it.next();
+                    while not line.startswith(" Level-") and not line.startswith(
+                        " Interface: "
+                    ):
+                        line = it.next()
 
                     if line.startswith(" Level-"):
                         continue
@@ -623,4 +628,3 @@ def validate_show_isis_interface_detail(rname, fname):
     (result, diff) = topotest.run_and_expect(test_func, None, wait=0.5, count=160)
 
     return (result, diff)
-
index 9694fa982f058fbea4e64512a92a9c5856b93ed1..20d7f46d4cea13d04c1a676d8784fa4cafb583dd 100644 (file)
@@ -264,6 +264,7 @@ def test_ldp_pseudowires():
             rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref"
         )
 
+
 def test_ldp_igp_sync():
     logger.info("Test: verify LDP igp-sync")
     tgen = get_topogen()
@@ -277,6 +278,7 @@ def test_ldp_igp_sync():
             rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync.ref"
         )
 
+
 def test_ospf_ldp_sync():
     logger.info("Test: verify OSPF igp-sync")
     tgen = get_topogen()
@@ -317,19 +319,26 @@ def test_r1_eth1_shutdown():
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+            rname,
+            "show mpls ldp igp-sync json",
+            "show_ldp_igp_sync_r1_eth1_shutdown.ref",
         )
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync_r1_eth1_shutdown.ref"
+            rname,
+            "show ip ospf mpls ldp-sync json",
+            "show_ospf_ldp_sync_r1_eth1_shutdown.ref",
         )
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show ip ospf interface json", "show_ip_ospf_interface_r1_eth1_shutdown.ref"
+            rname,
+            "show ip ospf interface json",
+            "show_ip_ospf_interface_r1_eth1_shutdown.ref",
         )
 
+
 def test_r1_eth1_no_shutdown():
     logger.info("Test: verify behaviour after r1-eth1 is no shutdown")
     tgen = get_topogen()
@@ -358,6 +367,7 @@ def test_r1_eth1_no_shutdown():
             rname, "show ip ospf interface json", "show_ip_ospf_interface.ref"
         )
 
+
 def test_r2_eth1_shutdown():
     logger.info("Test: verify behaviour after r2-eth1 is shutdown")
     tgen = get_topogen()
@@ -373,19 +383,26 @@ def test_r2_eth1_shutdown():
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show mpls ldp igp-sync json", "show_ldp_igp_sync_r1_eth1_shutdown.ref"
+            rname,
+            "show mpls ldp igp-sync json",
+            "show_ldp_igp_sync_r1_eth1_shutdown.ref",
         )
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show ip ospf mpls ldp-sync json", "show_ospf_ldp_sync_r2_eth1_shutdown.ref"
+            rname,
+            "show ip ospf mpls ldp-sync json",
+            "show_ospf_ldp_sync_r2_eth1_shutdown.ref",
         )
 
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show ip ospf interface json", "show_ip_ospf_interface_r2_eth1_shutdown.ref"
+            rname,
+            "show ip ospf interface json",
+            "show_ip_ospf_interface_r2_eth1_shutdown.ref",
         )
 
+
 def test_r2_eth1_no_shutdown():
     logger.info("Test: verify behaviour after r2-eth1 is no shutdown")
     tgen = get_topogen()
@@ -414,6 +431,7 @@ def test_r2_eth1_no_shutdown():
             rname, "show ip ospf interface json", "show_ip_ospf_interface.ref"
         )
 
+
 # Memory leak test template
 def test_memory_leak():
     "Run the memory leak test and report results."
index 0b8bf4de0ece470afbbff1a62b27f00334a93465..ba94cd47d4b20c7638852c10bce27d66d89cde9b 100644 (file)
@@ -283,8 +283,7 @@ def test_ldp_pseudowires_after_link_down():
     # for nexthop resolution). Give some extra wait time.
     for rname in ["r1", "r2", "r3"]:
         router_compare_json_output(
-            rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref",
-            count=160, wait=1
+            rname, "show l2vpn atom vc json", "show_l2vpn_vc.ref", count=160, wait=1
         )
 
 
index 3d92718c78468f66b3d02725fbdf42ddc36d2cb6..a23092de832b58c34aec6758bbbb2fc53f97a554 100644 (file)
@@ -18,8 +18,8 @@
 
 #
 # want_rd_routes = [
-#     {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1'},
-#     {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1'},
+#     {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1', 'bp': True},
+#     {'rd':'10:1', 'p':'5.1.0.0/24', 'n':'1.1.1.1', 'bp': False},
 #
 #     {'rd':'10:3', 'p':'5.1.0.0/24', 'n':'3.3.3.3'},
 # ]
 # ribRequireUnicastRoutes('r1','ipv4','','Customer routes in default',want_unicast_routes)
 #
 
-from lutil import luCommand, luResult
+from lutil import luCommand, luResult, LUtil
 import json
 import re
 
 # gpz: get rib in json form and compare against desired routes
 class BgpRib:
+    def log(self, str):
+        LUtil.log("BgpRib: " + str)
+
     def routes_include_wanted(self, pfxtbl, want, debug):
         # helper function to RequireVpnRoutes
         for pfx in pfxtbl.iterkeys():
             if debug:
-                print "trying pfx " + pfx
+                self.log("trying pfx %s" % pfx)
             if pfx != want["p"]:
                 if debug:
-                    print "want pfx=" + want["p"] + ", not " + pfx
+                    self.log("want pfx=" + want["p"] + ", not " + pfx)
                 continue
             if debug:
-                print "have pfx=" + pfx
+                self.log("have pfx=%s" % pfx)
             for r in pfxtbl[pfx]:
+                bp = r.get("bestpath", False)
                 if debug:
-                    print "trying route"
+                    self.log("trying route %s bp=%s" % (r, bp))
                 nexthops = r["nexthops"]
                 for nh in nexthops:
                     if debug:
-                        print "trying nh " + nh["ip"]
+                        self.log("trying nh %s" % nh["ip"])
                     if nh["ip"] == want["n"]:
                         if debug:
-                            print "found " + want["n"]
-                        return 1
+                            self.log("found %s" % want["n"])
+                        if bp == want.get("bp", bp):
+                            return 1
+                        elif debug:
+                            self.log("bestpath mismatch %s != %s" % (bp, want["bp"]))
                     else:
                         if debug:
-                            print "want nh=" + want["n"] + ", not " + nh["ip"]
+                            self.log("want nh=" + want["n"] + ", not " + nh["ip"])
             if debug:
-                print "missing route: pfx=" + want["p"] + ", nh=" + want["n"]
+                self.log("missing route: pfx=" + want["p"] + ", nh=" + want["n"])
             return 0
 
     def RequireVpnRoutes(self, target, title, wantroutes, debug=0):
@@ -99,12 +106,12 @@ class BgpRib:
         for want in wantroutes:
             found = 0
             if debug:
-                print "want rd " + want["rd"]
+                self.log("want rd %s" % want["rd"])
             for rd in rds.iterkeys():
                 if rd != want["rd"]:
                     continue
                 if debug:
-                    print "found rd " + rd
+                    self.log("found rd %s" % rd)
                 table = rds[rd]
                 if self.routes_include_wanted(table, want, debug):
                     found = 1
@@ -115,13 +122,13 @@ class BgpRib:
         luResult(target, True, title, logstr)
 
     def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0):
-        logstr = "RequireVpnRoutes " + str(wantroutes)
+        logstr = "RequireVpnRoutes %s" % str(wantroutes)
         vrfstr = ""
         if vrf != "":
             vrfstr = "vrf %s" % (vrf)
 
         if (afi != "ipv4") and (afi != "ipv6"):
-            print "ERROR invalid afi"
+            self.log("ERROR invalid afi")
 
         cmdstr = "show bgp %s %s unicast" % (vrfstr, afi)
         # non json form for humans
@@ -148,7 +155,11 @@ class BgpRib:
                 errstr = "-script ERROR: check if vrf missing"
             luResult(target, False, title + errstr, logstr)
             return
+        # if debug:
+        #    self.log("table=%s" % table)
         for want in wantroutes:
+            if debug:
+                self.log("want=%s" % want)
             if not self.routes_include_wanted(table, want, debug):
                 luResult(target, False, title, logstr)
                 return
index 1fa6d351010e4de6cfda442ba2a0e7318ab53663..d83f946c4266eb5e0472faeac95ac7a0adf105c0 100644 (file)
@@ -400,6 +400,7 @@ def check_router_status(tgen):
     logger.debug("Exiting lib API: {}".format(sys._getframe().f_code.co_name))
     return True
 
+
 def getStrIO():
     """
     Return a StringIO object appropriate for the current python version.
@@ -409,6 +410,7 @@ def getStrIO():
     else:
         return StringIO.StringIO()
 
+
 def reset_config_on_routers(tgen, routerName=None):
     """
     Resets configuration on routers to the snapshot created using input JSON
@@ -702,14 +704,14 @@ def start_topology(tgen, daemon=None):
     )
     TMPDIR = os.path.join(LOGDIR, tgen.modname)
 
-    linux_ver = ''
+    linux_ver = ""
     router_list = tgen.routers()
     for rname in ROUTER_LIST:
         router = router_list[rname]
 
         # It will help in debugging the failures, will give more details on which
         # specific kernel version tests are failing
-        if linux_ver == '':
+        if linux_ver == "":
             linux_ver = router.run("uname -a")
             logger.info("Logging platform related details: \n %s \n", linux_ver)
 
@@ -741,11 +743,10 @@ def start_topology(tgen, daemon=None):
         # Loading empty bgpd.conf file to router, to start the bgp deamon
         router.load_config(TopoRouter.RD_BGP, "{}/{}/bgpd.conf".format(TMPDIR, rname))
 
-        if daemon and 'ospfd' in daemon:
+        if daemon and "ospfd" in daemon:
             # Loading empty ospf.conf file to router, to start the bgp deamon
             router.load_config(
-                TopoRouter.RD_OSPF,
-                '{}/{}/ospfd.conf'.format(TMPDIR, rname)
+                TopoRouter.RD_OSPF, "{}/{}/ospfd.conf".format(TMPDIR, rname)
             )
         # Starting routers
     logger.info("Starting all routers once topology is created")
@@ -831,8 +832,8 @@ def topo_daemons(tgen, topo):
     )
 
     for rtr in ROUTER_LIST:
-        if 'ospf' in topo['routers'][rtr] and 'ospfd' not in daemon_list:
-            daemon_list.append('ospfd')
+        if "ospf" in topo["routers"][rtr] and "ospfd" not in daemon_list:
+            daemon_list.append("ospfd")
 
     return daemon_list
 
@@ -1266,8 +1267,7 @@ def interface_status(tgen, topo, input_dict):
     return True
 
 
-def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0,
-          return_is_dict=False):
+def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0, return_is_dict=False):
     """
     Retries function execution, if return is an errormsg or exception
 
@@ -1279,11 +1279,10 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0,
     """
 
     def _retry(func):
-
         @wraps(func)
         def func_retry(*args, **kwargs):
-            _wait = kwargs.pop('wait', wait)
-            _attempts = kwargs.pop('attempts', attempts)
+            _wait = kwargs.pop("wait", wait)
+            _attempts = kwargs.pop("attempts", attempts)
             _attempts = int(_attempts)
             expected = True
             if _attempts < 0:
@@ -1293,19 +1292,21 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0,
                 logger.info("Waiting for [%s]s as initial delay", initial_wait)
                 sleep(initial_wait)
 
-            _return_is_str = kwargs.pop('return_is_str', return_is_str)
-            _return_is_dict = kwargs.pop('return_is_str', return_is_dict)
+            _return_is_str = kwargs.pop("return_is_str", return_is_str)
+            _return_is_dict = kwargs.pop("return_is_str", return_is_dict)
             for i in range(1, _attempts + 1):
                 try:
-                    _expected = kwargs.setdefault('expected', True)
+                    _expected = kwargs.setdefault("expected", True)
                     if _expected is False:
                         expected = _expected
-                    kwargs.pop('expected')
+                    kwargs.pop("expected")
                     ret = func(*args, **kwargs)
                     logger.debug("Function returned %s", ret)
                     if _return_is_str and isinstance(ret, bool) and _expected:
                         return ret
-                    if (isinstance(ret, str) or isinstance(ret, unicode)) and _expected is False:
+                    if (
+                        isinstance(ret, str) or isinstance(ret, unicode)
+                    ) and _expected is False:
                         return ret
                     if _return_is_dict and isinstance(ret, dict):
                         return ret
@@ -1316,17 +1317,17 @@ def retry(attempts=3, wait=2, return_is_str=True, initial_wait=0,
                 except Exception as err:
                     if _attempts == i and expected:
                         generate_support_bundle()
-                        logger.info("Max number of attempts (%r) reached",
-                                    _attempts)
+                        logger.info("Max number of attempts (%r) reached", _attempts)
                         raise
                     else:
                         logger.info("Function returned %s", err)
                 if i < _attempts:
-                    logger.info("Retry [#%r] after sleeping for %ss"
-                                % (i, _wait))
+                    logger.info("Retry [#%r] after sleeping for %ss" % (i, _wait))
                     sleep(_wait)
+
         func_retry._original = func
         return func_retry
+
     return _retry
 
 
@@ -1420,58 +1421,63 @@ def create_interfaces_cfg(tgen, topo, build=False):
                     else:
                         interface_data.append("ipv6 address {}\n".format(intf_addr))
 
-                if 'ospf' in data:
-                    ospf_data = data['ospf']
-                    if 'area' in ospf_data:
-                        intf_ospf_area = c_data["links"][destRouterLink][
-                            "ospf"]["area"]
+                if "ospf" in data:
+                    ospf_data = data["ospf"]
+                    if "area" in ospf_data:
+                        intf_ospf_area = c_data["links"][destRouterLink]["ospf"]["area"]
                         if "delete" in data and data["delete"]:
                             interface_data.append("no ip ospf area")
                         else:
-                            interface_data.append("ip ospf area {}".format(
-                                intf_ospf_area
-                            ))
+                            interface_data.append(
+                                "ip ospf area {}".format(intf_ospf_area)
+                            )
 
-                    if "hello_interval"  in ospf_data:
-                        intf_ospf_hello = c_data["links"][destRouterLink][
-                        "ospf"]["hello_interval"]
+                    if "hello_interval" in ospf_data:
+                        intf_ospf_hello = c_data["links"][destRouterLink]["ospf"][
+                            "hello_interval"
+                        ]
                         if "delete" in data and data["delete"]:
-                            interface_data.append("no ip ospf "\
-                            " hello-interval")
+                            interface_data.append("no ip ospf " " hello-interval")
                         else:
-                            interface_data.append("ip ospf "\
-                            " hello-interval {}".format(intf_ospf_hello))
+                            interface_data.append(
+                                "ip ospf " " hello-interval {}".format(intf_ospf_hello)
+                            )
 
                     if "dead_interval" in ospf_data:
-                        intf_ospf_dead = c_data["links"][destRouterLink][
-                        "ospf"]["dead_interval"]
+                        intf_ospf_dead = c_data["links"][destRouterLink]["ospf"][
+                            "dead_interval"
+                        ]
                         if "delete" in data and data["delete"]:
-                            interface_data.append("no ip ospf"\
-                            " dead-interval")
+                            interface_data.append("no ip ospf" " dead-interval")
                         else:
-                            interface_data.append("ip ospf "\
-                            " dead-interval {}".format(intf_ospf_dead))
+                            interface_data.append(
+                                "ip ospf " " dead-interval {}".format(intf_ospf_dead)
+                            )
 
                     if "network" in ospf_data:
-                        intf_ospf_nw = c_data["links"][destRouterLink][
-                        "ospf"]["network"]
+                        intf_ospf_nw = c_data["links"][destRouterLink]["ospf"][
+                            "network"
+                        ]
                         if "delete" in data and data["delete"]:
-                            interface_data.append("no ip ospf"\
-                            " network {}".format(intf_ospf_nw))
+                            interface_data.append(
+                                "no ip ospf" " network {}".format(intf_ospf_nw)
+                            )
                         else:
-                            interface_data.append("ip ospf"\
-                            " network {}".format(intf_ospf_nw))
+                            interface_data.append(
+                                "ip ospf" " network {}".format(intf_ospf_nw)
+                            )
 
                     if "priority" in ospf_data:
-                        intf_ospf_nw = c_data["links"][destRouterLink][
-                        "ospf"]["priority"]
+                        intf_ospf_nw = c_data["links"][destRouterLink]["ospf"][
+                            "priority"
+                        ]
 
                         if "delete" in data and data["delete"]:
-                            interface_data.append("no ip ospf"\
-                            " priority")
+                            interface_data.append("no ip ospf" " priority")
                         else:
-                            interface_data.append("ip ospf"\
-                            " priority {}".format(intf_ospf_nw))
+                            interface_data.append(
+                                "ip ospf" " priority {}".format(intf_ospf_nw)
+                            )
             result = create_common_configuration(
                 tgen, c_router, interface_data, "interface_config", build=build
             )
@@ -3013,7 +3019,7 @@ def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
 
                     for st_rt in ip_list:
                         st_rt = str(ipaddress.ip_network(frr_unicode(st_rt)))
-                        #st_rt = str(ipaddr.IPNetwork(unicode(st_rt)))
+                        # st_rt = str(ipaddr.IPNetwork(unicode(st_rt)))
 
                         _addr_type = validate_ip_address(st_rt)
                         if _addr_type != addr_type:
@@ -3118,7 +3124,7 @@ def verify_fib_routes(tgen, addr_type, dut, input_dict, next_hop=None):
                 nh_found = False
 
                 for st_rt in ip_list:
-                    #st_rt = str(ipaddr.IPNetwork(unicode(st_rt)))
+                    # st_rt = str(ipaddr.IPNetwork(unicode(st_rt)))
                     st_rt = str(ipaddress.ip_network(frr_unicode(st_rt)))
 
                     _addr_type = validate_ip_address(st_rt)
@@ -4075,8 +4081,9 @@ def required_linux_kernel_version(required_version):
     """
     system_kernel = platform.release()
     if version_cmp(system_kernel, required_version) < 0:
-        error_msg = ('These tests will not run on kernel "{}", '
-            'they require kernel >= {})'.format(system_kernel,
-                required_version ))
+        error_msg = (
+            'These tests will not run on kernel "{}", '
+            "they require kernel >= {})".format(system_kernel, required_version)
+        )
         return error_msg
     return True
index 3c93e1ac5c065ee87d960a93fcbd47f13714a6ba..d211be883694a9ba18eac37cfe0157811e5ade09 100644 (file)
@@ -43,7 +43,8 @@ from mininet.topo import Topo
 
 customize = None
 
-class LTemplate():
+
+class LTemplate:
     test = None
     testdir = None
     scriptdir = None
@@ -54,12 +55,12 @@ class LTemplate():
 
     def __init__(self, test, testdir):
         global customize
-        customize = imp.load_source('customize', os.path.join(testdir, 'customize.py'))
+        customize = imp.load_source("customize", os.path.join(testdir, "customize.py"))
         self.test = test
         self.testdir = testdir
         self.scriptdir = testdir
-        self.logdir = '/tmp/topotests/{0}.test_{0}'.format(test)
-        logger.info('LTemplate: '+test)
+        self.logdir = "/tmp/topotests/{0}.test_{0}".format(test)
+        logger.info("LTemplate: " + test)
 
     def setup_module(self, mod):
         "Sets up the pytest environment"
@@ -68,14 +69,14 @@ class LTemplate():
         # ... and here it calls Mininet initialization functions.
         tgen.start_topology()
 
-        logger.info('Topology started')
+        logger.info("Topology started")
         try:
             self.prestarthooksuccess = customize.ltemplatePreRouterStartHook()
         except AttributeError:
-            #not defined
+            # not defined
             logger.debug("ltemplatePreRouterStartHook() not defined")
         if self.prestarthooksuccess != True:
-            logger.info('ltemplatePreRouterStartHook() failed, skipping test')
+            logger.info("ltemplatePreRouterStartHook() failed, skipping test")
             return
 
         # This is a sample of configuration loading.
@@ -85,48 +86,57 @@ class LTemplate():
         for rname, router in router_list.items():
             logger.info("Setting up %s" % rname)
             for rd_val in TopoRouter.RD:
-                config = os.path.join(self.testdir, '{}/{}.conf'.format(rname,TopoRouter.RD[rd_val]))
+                config = os.path.join(
+                    self.testdir, "{}/{}.conf".format(rname, TopoRouter.RD[rd_val])
+                )
                 prog = os.path.join(tgen.net[rname].daemondir, TopoRouter.RD[rd_val])
                 if os.path.exists(config):
                     if os.path.exists(prog):
                         router.load_config(rd_val, config)
                     else:
-                        logger.warning("{} not found, but have {}.conf file".format(prog, TopoRouter.RD[rd_val]))
+                        logger.warning(
+                            "{} not found, but have {}.conf file".format(
+                                prog, TopoRouter.RD[rd_val]
+                            )
+                        )
 
         # After loading the configurations, this function loads configured daemons.
-        logger.info('Starting routers')
+        logger.info("Starting routers")
         tgen.start_router()
         try:
             self.poststarthooksuccess = customize.ltemplatePostRouterStartHook()
         except AttributeError:
-            #not defined
+            # not defined
             logger.debug("ltemplatePostRouterStartHook() not defined")
         luStart(baseScriptDir=self.scriptdir, baseLogDir=self.logdir, net=tgen.net)
 
-#initialized by ltemplate_start
+
+# initialized by ltemplate_start
 _lt = None
 
+
 def setup_module(mod):
     global _lt
     root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-    test = mod.__name__[:mod.__name__.rfind(".")]
+    test = mod.__name__[: mod.__name__.rfind(".")]
     testdir = os.path.join(root, test)
 
-    #don't do this for now as reload didn't work as expected
-    #fixup sys.path, want test dir there only once
-    #try:
+    # don't do this for now as reload didn't work as expected
+    # fixup sys.path, want test dir there only once
+    # try:
     #    sys.path.remove(testdir)
-    #except ValueError:
+    # except ValueError:
     #    logger.debug(testdir+" not found in original sys.path")
-    #add testdir
-    #sys.path.append(testdir)
+    # add testdir
+    # sys.path.append(testdir)
 
-    #init class
+    # init class
     _lt = LTemplate(test, testdir)
     _lt.setup_module(mod)
 
-    #drop testdir
-    #sys.path.remove(testdir)
+    # drop testdir
+    # sys.path.remove(testdir)
+
 
 def teardown_module(mod):
     global _lt
@@ -141,7 +151,10 @@ def teardown_module(mod):
     tgen.stop_topology()
     _lt = None
 
-def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, KeepGoing=False):
+
+def ltemplateTest(
+    script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None, KeepGoing=False
+):
     global _lt
     if _lt == None or _lt.prestarthooksuccess != True:
         return
@@ -149,8 +162,8 @@ def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None,
     tgen = get_topogen()
     if not os.path.isfile(script):
         if not os.path.isfile(os.path.join(_lt.scriptdir, script)):
-            logger.error('Could not find script file: ' + script)
-            assert 'Could not find script file: ' + script
+            logger.error("Could not find script file: " + script)
+            assert "Could not find script file: " + script
     logger.info("Starting template test: " + script)
     numEntry = luNumFail()
 
@@ -163,7 +176,7 @@ def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None,
     if CheckFuncStr != None:
         check = eval(CheckFuncStr)
         if check != True:
-            pytest.skip("Check function '"+CheckFuncStr+"' returned: " + check)
+            pytest.skip("Check function '" + CheckFuncStr + "' returned: " + check)
 
     if CallOnFail != None:
         CallOnFail = eval(CallOnFail)
@@ -173,22 +186,26 @@ def ltemplateTest(script, SkipIfFailed=True, CallOnFail=None, CheckFuncStr=None,
         luShowFail()
         fatal_error = "%d tests failed" % numFail
         if not KeepGoing:
-            assert "scripts/cleanup_all.py failed" == "See summary output above", fatal_error
+            assert (
+                "scripts/cleanup_all.py failed" == "See summary output above"
+            ), fatal_error
+
 
 # Memory leak test template
 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')
+        pytest.skip("Memory leak test/report is disabled")
 
     tgen.report_memory_leaks()
 
-class ltemplateRtrCmd():
+
+class ltemplateRtrCmd:
     def __init__(self):
         self.resetCounts()
 
-    def doCmd(self, tgen, rtr, cmd, checkstr = None):
+    def doCmd(self, tgen, rtr, cmd, checkstr=None):
         output = tgen.net[rtr].cmd(cmd).strip()
         if len(output):
             self.output += 1
@@ -199,8 +216,8 @@ class ltemplateRtrCmd():
                 else:
                     self.match += 1
                 return ret
-            logger.info('command: {} {}'.format(rtr, cmd))
-            logger.info('output: ' + output)
+            logger.info("command: {} {}".format(rtr, cmd))
+            logger.info("output: " + output)
         self.none += 1
         return None
 
@@ -222,63 +239,69 @@ class ltemplateRtrCmd():
     def getNone(self):
         return self.none
 
-def ltemplateVersionCheck(vstr, rname='r1', compstr='<',cli=False, kernel='4.9', iproute2=None, mpls=True):
+
+def ltemplateVersionCheck(
+    vstr, rname="r1", compstr="<", cli=False, kernel="4.9", iproute2=None, mpls=True
+):
     tgen = get_topogen()
     router = tgen.gears[rname]
 
     if cli:
-        logger.info('calling mininet CLI')
+        logger.info("calling mininet CLI")
         tgen.mininet_cli()
-        logger.info('exited mininet CLI')
+        logger.info("exited mininet CLI")
 
     if _lt == None:
-        ret = 'Template not initialized'
+        ret = "Template not initialized"
         return ret
 
     if _lt.prestarthooksuccess != True:
-        ret = 'ltemplatePreRouterStartHook failed'
+        ret = "ltemplatePreRouterStartHook failed"
         return ret
 
     if _lt.poststarthooksuccess != True:
-        ret = 'ltemplatePostRouterStartHook failed'
+        ret = "ltemplatePostRouterStartHook failed"
         return ret
 
     if mpls == True and tgen.hasmpls != True:
-        ret = 'MPLS not initialized'
+        ret = "MPLS not initialized"
         return ret
 
     if kernel != None:
         krel = platform.release()
         if topotest.version_cmp(krel, kernel) < 0:
-            ret = 'Skipping tests, old kernel ({} < {})'.format(krel, kernel)
+            ret = "Skipping tests, old kernel ({} < {})".format(krel, kernel)
             return ret
 
     if iproute2 != None:
         if _lt.iproute2Ver == None:
-            #collect/log info on iproute2
+            # collect/log info on iproute2
             cc = ltemplateRtrCmd()
-            found = cc.doCmd(tgen, rname, 'apt-cache policy iproute2', 'Installed: ([\d\.]*)')
+            found = cc.doCmd(
+                tgen, rname, "apt-cache policy iproute2", "Installed: ([\d\.]*)"
+            )
             if found != None:
                 iproute2Ver = found.group(1)
             else:
-                iproute2Ver = '0-unknown'
-            logger.info('Have iproute2 version=' + iproute2Ver)
+                iproute2Ver = "0-unknown"
+            logger.info("Have iproute2 version=" + iproute2Ver)
 
         if topotest.version_cmp(iproute2Ver, iproute2) < 0:
-            ret = 'Skipping tests, old iproute2 ({} < {})'.format(iproute2Ver, iproute2)
+            ret = "Skipping tests, old iproute2 ({} < {})".format(iproute2Ver, iproute2)
             return ret
 
     ret = True
     try:
         if router.has_version(compstr, vstr):
-            ret = 'Skipping tests, old FRR version {} {}'.format(compstr, vstr)
+            ret = "Skipping tests, old FRR version {} {}".format(compstr, vstr)
             return ret
     except:
         ret = True
 
     return ret
 
-#for testing
-if __name__ == '__main__':
+
+# for testing
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index 05ed9c007d3df8dde5ced4c704a0e7cc859fe639..1fb4f48b0f12f76c2b595dad7db0a4e9182e346e 100644 (file)
@@ -32,46 +32,53 @@ from mininet.net import Mininet
 # These functions are inteneted to provide support for CI testing within MiniNet
 # environments.
 
+
 class lUtil:
-    #to be made configurable in the future
-    base_script_dir = '.'
-    base_log_dir = '.'
-    fout_name = 'output.log'
-    fsum_name = 'summary.txt'
+    # to be made configurable in the future
+    base_script_dir = "."
+    base_log_dir = "."
+    fout_name = "output.log"
+    fsum_name = "summary.txt"
     l_level = 6
     CallOnFail = False
 
     l_total = 0
     l_pass = 0
     l_fail = 0
-    l_filename = ''
+    l_filename = ""
     l_last = None
     l_line = 0
     l_dotall_experiment = False
     l_last_nl = None
 
-    fout = ''
-    fsum = ''
-    net  = ''
+    fout = ""
+    fsum = ""
+    net = ""
 
     def log(self, str, level=6):
         if self.l_level > 0:
-            if self.fout == '':
-                self.fout = open(self.fout_name, 'w', 0)
-            self.fout.write(str+'\n')
+            if self.fout == "":
+                self.fout = open(self.fout_name, "w", 0)
+            self.fout.write(str + "\n")
         if level <= self.l_level:
             print(str)
 
     def summary(self, str):
-        if self.fsum == '':
-            self.fsum = open(self.fsum_name, 'w', 0)
-            self.fsum.write('\
-******************************************************************************\n')
-            self.fsum.write('\
-Test Target Summary                                                  Pass Fail\n')
-            self.fsum.write('\
-******************************************************************************\n')
-        self.fsum.write(str+'\n')
+        if self.fsum == "":
+            self.fsum = open(self.fsum_name, "w", 0)
+            self.fsum.write(
+                "\
+******************************************************************************\n"
+            )
+            self.fsum.write(
+                "\
+Test Target Summary                                                  Pass Fail\n"
+            )
+            self.fsum.write(
+                "\
+******************************************************************************\n"
+            )
+        self.fsum.write(str + "\n")
 
     def result(self, target, success, str, logstr=None):
         if success:
@@ -88,32 +95,34 @@ Test Target Summary                                                  Pass Fail\n
         if logstr != None:
             self.log("R:%d %s: %s" % (self.l_total, sstr, logstr))
         res = "%-4d %-6s %-56s %-4d %d" % (self.l_total, target, str, p, f)
-        self.log ('R:'+res)
+        self.log("R:" + res)
         self.summary(res)
         if f == 1 and self.CallOnFail != False:
             self.CallOnFail()
 
     def closeFiles(self):
-        ret = '\
+        ret = (
+            "\
 ******************************************************************************\n\
 Total %-4d                                                           %-4d %d\n\
-******************************************************************************'\
-% (self.l_total, self.l_pass, self.l_fail)
-        if self.fsum != '':
-            self.fsum.write(ret + '\n')
+******************************************************************************"
+            % (self.l_total, self.l_pass, self.l_fail)
+        )
+        if self.fsum != "":
+            self.fsum.write(ret + "\n")
             self.fsum.close()
-            self.fsum = ''
-        if self.fout != '':
+            self.fsum = ""
+        if self.fout != "":
             if os.path.isfile(self.fsum_name):
-                r = open(self.fsum_name, 'r')
+                r = open(self.fsum_name, "r")
                 self.fout.write(r.read())
                 r.close()
             self.fout.close()
-            self.fout = ''
+            self.fout = ""
         return ret
 
     def setFilename(self, name):
-        str = 'FILE: ' + name
+        str = "FILE: " + name
         self.log(str)
         self.summary(str)
         self.l_filename = name
@@ -128,19 +137,19 @@ Total %-4d                                                           %-4d %d\n\
     def strToArray(self, string):
         a = []
         c = 0
-        end = ''
+        end = ""
         words = string.split()
-        if len(words) < 1 or words[0].startswith('#'):
+        if len(words) < 1 or words[0].startswith("#"):
             return a
         words = string.split()
         for word in words:
             if len(end) == 0:
                 a.append(word)
             else:
-                a[c] += str(' '+word)
-            if end == '\\':
-                end = ''
-            if not word.endswith('\\'):
+                a[c] += str(" " + word)
+            if end == "\\":
+                end = ""
+            if not word.endswith("\\"):
                 if end != '"':
                     if word.startswith('"'):
                         end = '"'
@@ -148,14 +157,14 @@ Total %-4d                                                           %-4d %d\n\
                         c += 1
                 else:
                     if word.endswith('"'):
-                        end = ''
+                        end = ""
                         c += 1
                     else:
                         c += 1
             else:
-                end = '\\'
-    #        if len(end) == 0:
-    #            print('%d:%s:' % (c, a[c-1]))
+                end = "\\"
+        #        if len(end) == 0:
+        #            print('%d:%s:' % (c, a[c-1]))
 
         return a
 
@@ -169,27 +178,37 @@ Total %-4d                                                           %-4d %d\n\
                         luCommand(a[1], a[2], a[3], a[4], a[5])
                     else:
                         self.l_line += 1
-                        self.log('%s:%s %s' % (self.l_filename, self.l_line , line))
+                        self.log("%s:%s %s" % (self.l_filename, self.l_line, line))
                         if len(a) >= 2:
-                            if a[0] == 'sleep':
+                            if a[0] == "sleep":
                                 time.sleep(int(a[1]))
-                            elif a[0] == 'include':
+                            elif a[0] == "include":
                                 self.execTestFile(a[1])
             f.close()
         else:
-            self.log('unable to read: ' + tstFile)
+            self.log("unable to read: " + tstFile)
             sys.exit(1)
 
     def command(self, target, command, regexp, op, result, returnJson):
         global net
-        if op != 'wait':
-            self.l_line  += 1
-        self.log('(#%d) %s:%s COMMAND:%s:%s:%s:%s:%s:' % \
-                 (self.l_total+1,
-                  self.l_filename, self.l_line, target, command, regexp, op, result))
-        if self.net == '':
+        if op != "wait":
+            self.l_line += 1
+        self.log(
+            "(#%d) %s:%s COMMAND:%s:%s:%s:%s:%s:"
+            % (
+                self.l_total + 1,
+                self.l_filename,
+                self.l_line,
+                target,
+                command,
+                regexp,
+                op,
+                result,
+            )
+        )
+        if self.net == "":
             return False
-        #self.log("Running %s %s" % (target, command))
+        # self.log("Running %s %s" % (target, command))
         js = None
         out = self.net[target].cmd(command).rstrip()
         if len(out) == 0:
@@ -201,13 +220,15 @@ Total %-4d                                                           %-4d %d\n\
                     js = json.loads(out)
                 except:
                     js = None
-                    self.log('WARNING: JSON load failed -- confirm command output is in JSON format.')
-        self.log('COMMAND OUTPUT:%s:' % report)
+                    self.log(
+                        "WARNING: JSON load failed -- confirm command output is in JSON format."
+                    )
+        self.log("COMMAND OUTPUT:%s:" % report)
 
         # Experiment: can we achieve the same match behavior via DOTALL
         # without converting newlines to spaces?
         out_nl = out
-        search_nl = re.search(regexp, out_nl, re.DOTALL);
+        search_nl = re.search(regexp, out_nl, re.DOTALL)
         self.l_last_nl = search_nl
         # Set up for comparison
         if search_nl != None:
@@ -220,32 +241,50 @@ Total %-4d                                                           %-4d %d\n\
         search = re.search(regexp, out)
         self.l_last = search
         if search == None:
-            if op == 'fail':
+            if op == "fail":
                 success = True
             else:
                 success = False
             ret = success
         else:
             ret = search.group()
-            if op != 'fail':
+            if op != "fail":
                 success = True
                 level = 7
             else:
                 success = False
                 level = 5
-            self.log('found:%s:' % ret, level)
+            self.log("found:%s:" % ret, level)
             # Experiment: compare matched strings obtained each way
             if self.l_dotall_experiment and (group_nl_converted != ret):
-                self.log('DOTALL experiment: strings differ dotall=[%s] orig=[%s]' % (group_nl_converted, ret), 9)
-        if op == 'pass' or op == 'fail':
+                self.log(
+                    "DOTALL experiment: strings differ dotall=[%s] orig=[%s]"
+                    % (group_nl_converted, ret),
+                    9,
+                )
+        if op == "pass" or op == "fail":
             self.result(target, success, result)
         if js != None:
             return js
         return ret
 
-    def wait(self, target, command, regexp, op, result, wait, returnJson, wait_time=0.5):
-        self.log('%s:%s WAIT:%s:%s:%s:%s:%s:%s:%s:' % \
-                 (self.l_filename, self.l_line, target, command, regexp, op, result,wait,wait_time))
+    def wait(
+        self, target, command, regexp, op, result, wait, returnJson, wait_time=0.5
+    ):
+        self.log(
+            "%s:%s WAIT:%s:%s:%s:%s:%s:%s:%s:"
+            % (
+                self.l_filename,
+                self.l_line,
+                target,
+                command,
+                regexp,
+                op,
+                result,
+                wait,
+                wait_time,
+            )
+        )
         found = False
         n = 0
         startt = time.time()
@@ -264,103 +303,137 @@ Total %-4d                                                           %-4d %d\n\
                 time.sleep(wait_time)
 
         delta = time.time() - startt
-        self.log('Done after %d loops, time=%s, Found=%s' % (n, delta, found))
-        found = self.command(target, command, regexp, 'pass', '%s +%4.2f secs' % (result, delta), returnJson)
+        self.log("Done after %d loops, time=%s, Found=%s" % (n, delta, found))
+        found = self.command(
+            target,
+            command,
+            regexp,
+            "pass",
+            "%s +%4.2f secs" % (result, delta),
+            returnJson,
+        )
         return found
 
-#initialized by luStart
-LUtil=None
 
-#entry calls
-def luStart(baseScriptDir='.', baseLogDir='.', net='',
-            fout='output.log', fsum='summary.txt', level=None):
+# initialized by luStart
+LUtil = None
+
+# entry calls
+def luStart(
+    baseScriptDir=".",
+    baseLogDir=".",
+    net="",
+    fout="output.log",
+    fsum="summary.txt",
+    level=None,
+):
     global LUtil
-    #init class
-    LUtil=lUtil()
+    # init class
+    LUtil = lUtil()
     LUtil.base_script_dir = baseScriptDir
     LUtil.base_log_dir = baseLogDir
     LUtil.net = net
-    if fout != '':
-        LUtil.fout_name = baseLogDir + '/' + fout
+    if fout != "":
+        LUtil.fout_name = baseLogDir + "/" + fout
     if fsum != None:
-        LUtil.fsum_name = baseLogDir + '/' + fsum
+        LUtil.fsum_name = baseLogDir + "/" + fsum
     if level != None:
         LUtil.l_level = level
     LUtil.l_dotall_experiment = False
     LUtil.l_dotall_experiment = True
 
-def luCommand(target, command, regexp='.', op='none', result='', time=10, returnJson=False, wait_time=0.5):
-    if op != 'wait':
+
+def luCommand(
+    target,
+    command,
+    regexp=".",
+    op="none",
+    result="",
+    time=10,
+    returnJson=False,
+    wait_time=0.5,
+):
+    if op != "wait":
         return LUtil.command(target, command, regexp, op, result, returnJson)
     else:
-        return LUtil.wait(target, command, regexp, op, result, time, returnJson, wait_time)
+        return LUtil.wait(
+            target, command, regexp, op, result, time, returnJson, wait_time
+        )
+
 
 def luLast(usenl=False):
     if usenl:
         if LUtil.l_last_nl != None:
-            LUtil.log('luLast:%s:' %  LUtil.l_last_nl.group(), 7)
+            LUtil.log("luLast:%s:" % LUtil.l_last_nl.group(), 7)
         return LUtil.l_last_nl
     else:
         if LUtil.l_last != None:
-            LUtil.log('luLast:%s:' %  LUtil.l_last.group(), 7)
+            LUtil.log("luLast:%s:" % LUtil.l_last.group(), 7)
         return LUtil.l_last
 
+
 def luInclude(filename, CallOnFail=None):
-    tstFile = LUtil.base_script_dir + '/' + filename
+    tstFile = LUtil.base_script_dir + "/" + filename
     LUtil.setFilename(filename)
     if CallOnFail != None:
         oldCallOnFail = LUtil.getCallOnFail()
         LUtil.setCallOnFail(CallOnFail)
-    if filename.endswith('.py'):
-        LUtil.log("luInclude: execfile "+tstFile)
+    if filename.endswith(".py"):
+        LUtil.log("luInclude: execfile " + tstFile)
         execfile(tstFile)
     else:
-        LUtil.log("luInclude: execTestFile "+tstFile)
+        LUtil.log("luInclude: execTestFile " + tstFile)
         LUtil.execTestFile(tstFile)
     if CallOnFail != None:
         LUtil.setCallOnFail(oldCallOnFail)
 
+
 def luFinish():
     global LUtil
     ret = LUtil.closeFiles()
-    #done
+    # done
     LUtil = None
-    return ret;
+    return ret
+
 
 def luNumFail():
     return LUtil.l_fail
 
+
 def luNumPass():
     return LUtil.l_pass
 
+
 def luResult(target, success, str, logstr=None):
     return LUtil.result(target, success, str, logstr)
 
+
 def luShowResults(prFunction):
     printed = 0
-    sf = open(LUtil.fsum_name, 'r')
+    sf = open(LUtil.fsum_name, "r")
     for line in sf:
-        printed+=1
+        printed += 1
         prFunction(line.rstrip())
     sf.close()
 
+
 def luShowFail():
     printed = 0
-    sf = open(LUtil.fsum_name, 'r')
+    sf = open(LUtil.fsum_name, "r")
     for line in sf:
         if line[-2] != "0":
-            printed+=1
+            printed += 1
             logger.error(line.rstrip())
     sf.close()
     if printed > 0:
-         logger.error("See %s for details of errors" % LUtil.fout_name)
+        logger.error("See %s for details of errors" % LUtil.fout_name)
+
 
-#for testing
-if __name__ == '__main__':
-    print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + '/lib')
+# for testing
+if __name__ == "__main__":
+    print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + "/lib")
     luStart()
     for arg in sys.argv[1:]:
         luInclude(arg)
     luFinish()
     sys.exit(0)
-
index 9d6b8fa691be4e9abd2b7be2fc46a8ec2dc61cfd..9f3d4841b0075daa21c1739e9bf3ac13d01983ba 100644 (file)
@@ -26,12 +26,15 @@ import ipaddr
 from lib.topotest import frr_unicode
 
 # Import common_config to use commomnly used APIs
-from lib.common_config import (create_common_configuration,
-                               InvalidCLIError, retry,
-                               generate_ips,
-                               check_address_types,
-                               validate_ip_address,
-                               run_frr_cmd)
+from lib.common_config import (
+    create_common_configuration,
+    InvalidCLIError,
+    retry,
+    generate_ips,
+    check_address_types,
+    validate_ip_address,
+    run_frr_cmd,
+)
 
 LOGDIR = "/tmp/topotests/"
 TMPDIR = None
@@ -40,9 +43,8 @@ TMPDIR = None
 # Configure procs
 ################################
 
-def create_router_ospf(
-        tgen, topo, input_dict=None, build=False,
-        load_config=True):
+
+def create_router_ospf(tgen, topo, input_dict=None, build=False, load_config=True):
     """
     API to configure ospf on router.
 
@@ -84,19 +86,15 @@ def create_router_ospf(
             logger.debug("Router %s: 'ospf' not present in input_dict", router)
             continue
 
-        result = __create_ospf_global(
-            tgen, input_dict, router, build, load_config)
+        result = __create_ospf_global(tgen, input_dict, router, build, load_config)
         if result is True:
             ospf_data = input_dict[router]["ospf"]
 
-
     logger.debug("Exiting lib API: create_router_ospf()")
     return result
 
 
-def __create_ospf_global(
-        tgen, input_dict, router, build=False,
-        load_config=True):
+def __create_ospf_global(tgen, input_dict, router, build=False, load_config=True):
     """
     Helper API to create ospf global configuration.
 
@@ -121,9 +119,9 @@ def __create_ospf_global(
         del_ospf_action = ospf_data.setdefault("delete", False)
         if del_ospf_action:
             config_data = ["no router ospf"]
-            result = create_common_configuration(tgen, router, config_data,
-                                                 "ospf", build,
-                                                 load_config)
+            result = create_common_configuration(
+                tgen, router, config_data, "ospf", build, load_config
+            )
             return result
 
         config_data = []
@@ -137,34 +135,33 @@ def __create_ospf_global(
         if del_router_id:
             config_data.append("no ospf router-id")
         if router_id:
-            config_data.append("ospf router-id {}".format(
-                router_id))
+            config_data.append("ospf router-id {}".format(router_id))
 
         # redistribute command
         redistribute_data = ospf_data.setdefault("redistribute", {})
         if redistribute_data:
             for redistribute in redistribute_data:
                 if "redist_type" not in redistribute:
-                    logger.debug("Router %s: 'redist_type' not present in "
-                                "input_dict", router)
+                    logger.debug(
+                        "Router %s: 'redist_type' not present in " "input_dict", router
+                    )
                 else:
-                    cmd = "redistribute {}".format(
-                        redistribute["redist_type"])
+                    cmd = "redistribute {}".format(redistribute["redist_type"])
                     for red_type in redistribute_data:
                         if "route_map" in red_type:
-                            cmd = cmd + " route-map {}".format(red_type[
-                                'route_map'])
+                            cmd = cmd + " route-map {}".format(red_type["route_map"])
                     del_action = redistribute.setdefault("delete", False)
                     if del_action:
                         cmd = "no {}".format(cmd)
                     config_data.append(cmd)
-        #area information
+        # area information
         area_data = ospf_data.setdefault("area", {})
         if area_data:
             for area in area_data:
                 if "id" not in area:
-                    logger.debug("Router %s: 'area id' not present in "
-                                "input_dict", router)
+                    logger.debug(
+                        "Router %s: 'area id' not present in " "input_dict", router
+                    )
                 else:
                     cmd = "area {}".format(area["id"])
 
@@ -175,19 +172,21 @@ def __create_ospf_global(
                     if del_action:
                         cmd = "no {}".format(cmd)
                     config_data.append(cmd)
-        result = create_common_configuration(tgen, router, config_data,
-                                             "ospf", build, load_config)
+        result = create_common_configuration(
+            tgen, router, config_data, "ospf", build, load_config
+        )
 
         # summary information
         summary_data = ospf_data.setdefault("summary-address", {})
         if summary_data:
             for summary in summary_data:
                 if "prefix" not in summary:
-                    logger.debug("Router %s: 'summary-address' not present in "
-                                 "input_dict", router)
+                    logger.debug(
+                        "Router %s: 'summary-address' not present in " "input_dict",
+                        router,
+                    )
                 else:
-                    cmd = "summary {}/{}".format(summary["prefix"], summary[
-                        "mask"])
+                    cmd = "summary {}/{}".format(summary["prefix"], summary["mask"])
 
                     _tag = summary.setdefault("tag", None)
                     if _tag:
@@ -201,8 +200,9 @@ def __create_ospf_global(
                     if del_action:
                         cmd = "no {}".format(cmd)
                     config_data.append(cmd)
-        result = create_common_configuration(tgen, router, config_data,
-                                             "ospf", build, load_config)
+        result = create_common_configuration(
+            tgen, router, config_data, "ospf", build, load_config
+        )
 
     except InvalidCLIError:
         # Traceback
@@ -214,9 +214,7 @@ def __create_ospf_global(
     return result
 
 
-def create_router_ospf6(
-        tgen, topo, input_dict=None, build=False,
-        load_config=True):
+def create_router_ospf6(tgen, topo, input_dict=None, build=False, load_config=True):
     """
     API to configure ospf on router
 
@@ -253,16 +251,13 @@ def create_router_ospf6(
             logger.debug("Router %s: 'ospf' not present in input_dict", router)
             continue
 
-        result = __create_ospf_global(
-            tgen, input_dict, router, build, load_config)
+        result = __create_ospf_global(tgen, input_dict, router, build, load_config)
 
     logger.debug("Exiting lib API: create_router_ospf()")
     return result
 
 
-def __create_ospf6_global(
-        tgen, input_dict, router, build=False,
-        load_config=True):
+def __create_ospf6_global(tgen, input_dict, router, build=False, load_config=True):
     """
     Helper API to create ospf global configuration.
 
@@ -286,9 +281,9 @@ def __create_ospf6_global(
         del_ospf_action = ospf_data.setdefault("delete", False)
         if del_ospf_action:
             config_data = ["no ipv6 router ospf"]
-            result = create_common_configuration(tgen, router, config_data,
-                                                 "ospf", build,
-                                                 load_config)
+            result = create_common_configuration(
+                tgen, router, config_data, "ospf", build, load_config
+            )
             return result
 
         config_data = []
@@ -301,11 +296,11 @@ def __create_ospf6_global(
         if del_router_id:
             config_data.append("no ospf router-id")
         if router_id:
-            config_data.append("ospf router-id {}".format(
-                router_id))
+            config_data.append("ospf router-id {}".format(router_id))
 
-        result = create_common_configuration(tgen, router, config_data,
-                                             "ospf", build, load_config)
+        result = create_common_configuration(
+            tgen, router, config_data, "ospf", build, load_config
+        )
     except InvalidCLIError:
         # Traceback
         errormsg = traceback.format_exc()
@@ -315,8 +310,8 @@ def __create_ospf6_global(
     logger.debug("Exiting lib API: create_ospf_global()")
     return result
 
-def config_ospf_interface (tgen, topo, input_dict=None, build=False,
-        load_config=True):
+
+def config_ospf_interface(tgen, topo, input_dict=None, build=False, load_config=True):
     """
     API to configure ospf on router.
 
@@ -356,22 +351,25 @@ def config_ospf_interface (tgen, topo, input_dict=None, build=False,
         input_dict = deepcopy(input_dict)
     for router in input_dict.keys():
         config_data = []
-        for lnk in input_dict[router]['links'].keys():
-            if "ospf" not in input_dict[router]['links'][lnk]:
-                logger.debug("Router %s: ospf configs is not present in"
-                             "input_dict, passed input_dict", router,
-                             input_dict)
+        for lnk in input_dict[router]["links"].keys():
+            if "ospf" not in input_dict[router]["links"][lnk]:
+                logger.debug(
+                    "Router %s: ospf configs is not present in"
+                    "input_dict, passed input_dict",
+                    router,
+                    input_dict,
+                )
                 continue
-            ospf_data = input_dict[router]['links'][lnk]['ospf']
+            ospf_data = input_dict[router]["links"][lnk]["ospf"]
             data_ospf_area = ospf_data.setdefault("area", None)
             data_ospf_auth = ospf_data.setdefault("authentication", None)
             data_ospf_dr_priority = ospf_data.setdefault("priority", None)
             data_ospf_cost = ospf_data.setdefault("cost", None)
 
             try:
-                intf = topo['routers'][router]['links'][lnk]['interface']
+                intf = topo["routers"][router]["links"][lnk]["interface"]
             except KeyError:
-                intf = topo['switches'][router]['links'][lnk]['interface']
+                intf = topo["switches"][router]["links"][lnk]["interface"]
 
             # interface
             cmd = "interface {}".format(intf)
@@ -383,58 +381,60 @@ def config_ospf_interface (tgen, topo, input_dict=None, build=False,
                 config_data.append(cmd)
             # interface ospf auth
             if data_ospf_auth:
-                if data_ospf_auth == 'null':
+                if data_ospf_auth == "null":
                     cmd = "ip ospf authentication null"
-                elif data_ospf_auth == 'message-digest':
+                elif data_ospf_auth == "message-digest":
                     cmd = "ip ospf authentication message-digest"
                 else:
                     cmd = "ip ospf authentication"
 
-                if 'del_action' in ospf_data:
+                if "del_action" in ospf_data:
                     cmd = "no {}".format(cmd)
                 config_data.append(cmd)
 
                 if "message-digest-key" in ospf_data:
                     cmd = "ip ospf message-digest-key {} md5 {}".format(
-                        ospf_data["message-digest-key"],ospf_data[
-                            "authentication-key"])
-                    if 'del_action' in ospf_data:
+                        ospf_data["message-digest-key"], ospf_data["authentication-key"]
+                    )
+                    if "del_action" in ospf_data:
                         cmd = "no {}".format(cmd)
                     config_data.append(cmd)
 
-                if "authentication-key" in ospf_data and \
-                    "message-digest-key" not in ospf_data:
-                    cmd = "ip ospf authentication-key {}".format(ospf_data[
-                        "authentication-key"])
-                    if 'del_action' in ospf_data:
+                if (
+                    "authentication-key" in ospf_data
+                    and "message-digest-key" not in ospf_data
+                ):
+                    cmd = "ip ospf authentication-key {}".format(
+                        ospf_data["authentication-key"]
+                    )
+                    if "del_action" in ospf_data:
                         cmd = "no {}".format(cmd)
                     config_data.append(cmd)
 
             # interface ospf dr priority
             if data_ospf_dr_priority in ospf_data:
-                cmd = "ip ospf priority {}".format(
-                    ospf_data["priority"])
-                if 'del_action' in ospf_data:
+                cmd = "ip ospf priority {}".format(ospf_data["priority"])
+                if "del_action" in ospf_data:
                     cmd = "no {}".format(cmd)
                 config_data.append(cmd)
 
             # interface ospf cost
             if data_ospf_cost in ospf_data:
-                cmd = "ip ospf cost {}".format(
-                    ospf_data["cost"])
-                if 'del_action' in ospf_data:
+                cmd = "ip ospf cost {}".format(ospf_data["cost"])
+                if "del_action" in ospf_data:
                     cmd = "no {}".format(cmd)
                 config_data.append(cmd)
 
             if build:
                 return config_data
             else:
-                result = create_common_configuration(tgen, router, config_data,
-                                             "interface_config",
-                                             build=build)
+                result = create_common_configuration(
+                    tgen, router, config_data, "interface_config", build=build
+                )
     logger.debug("Exiting lib API: create_igmp_config()")
     return result
 
+
 def clear_ospf(tgen, router):
     """
     This API is to clear ospf neighborship by running
@@ -517,15 +517,16 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
     result = False
     if input_dict:
         for router, rnode in tgen.routers().items():
-            if 'ospf' not in topo['routers'][router]:
+            if "ospf" not in topo["routers"][router]:
                 continue
 
             if dut is not None and dut != router:
                 continue
 
             logger.info("Verifying OSPF neighborship on router %s:", router)
-            show_ospf_json = run_frr_cmd(rnode,
-                "show ip ospf neighbor  all json", isjson=True)
+            show_ospf_json = run_frr_cmd(
+                rnode, "show ip ospf neighbor  all json", isjson=True
+            )
 
             # Verifying output dictionary show_ospf_json is empty or not
             if not bool(show_ospf_json):
@@ -533,126 +534,134 @@ def verify_ospf_neighbor(tgen, topo, dut=None, input_dict=None, lan=False):
                 return errormsg
 
             ospf_data_list = input_dict[router]["ospf"]
-            ospf_nbr_list = ospf_data_list['neighbors']
+            ospf_nbr_list = ospf_data_list["neighbors"]
 
             for ospf_nbr, nbr_data in ospf_nbr_list.items():
-                data_ip = topo['routers'][ospf_nbr]['links']
-                data_rid = topo['routers'][ospf_nbr]['ospf']['router_id']
+                data_ip = topo["routers"][ospf_nbr]["links"]
+                data_rid = topo["routers"][ospf_nbr]["ospf"]["router_id"]
                 if ospf_nbr in data_ip:
                     nbr_details = nbr_data[ospf_nbr]
                 elif lan:
-                    for switch in topo['switches']:
-                        if 'ospf' in topo['switches'][switch]['links'][router]:
-                            neighbor_ip = data_ip[switch]['ipv4'].split("/")[0]
+                    for switch in topo["switches"]:
+                        if "ospf" in topo["switches"][switch]["links"][router]:
+                            neighbor_ip = data_ip[switch]["ipv4"].split("/")[0]
                         else:
                             continue
                 else:
-                    neighbor_ip = data_ip[router]['ipv4'].split("/")[0]
+                    neighbor_ip = data_ip[router]["ipv4"].split("/")[0]
 
                 nh_state = None
                 neighbor_ip = neighbor_ip.lower()
                 nbr_rid = data_rid
                 try:
-                    nh_state = show_ospf_json[nbr_rid][0][
-                        'state'].split('/')[0]
-                    intf_state = show_ospf_json[nbr_rid][0][
-                        'state'].split('/')[1]
+                    nh_state = show_ospf_json[nbr_rid][0]["state"].split("/")[0]
+                    intf_state = show_ospf_json[nbr_rid][0]["state"].split("/")[1]
                 except KeyError:
-                    errormsg = "[DUT: {}] OSPF peer {} missing".format(router,
-                    nbr_rid)
+                    errormsg = "[DUT: {}] OSPF peer {} missing".format(router, nbr_rid)
                     return errormsg
 
-                nbr_state = nbr_data.setdefault("state",None)
-                nbr_role = nbr_data.setdefault("role",None)
+                nbr_state = nbr_data.setdefault("state", None)
+                nbr_role = nbr_data.setdefault("role", None)
 
                 if nbr_state:
                     if nbr_state == nh_state:
-                        logger.info("[DUT: {}] OSPF Nbr is {}:{} State {}".format
-                        (router, ospf_nbr, nbr_rid, nh_state))
+                        logger.info(
+                            "[DUT: {}] OSPF Nbr is {}:{} State {}".format(
+                                router, ospf_nbr, nbr_rid, nh_state
+                            )
+                        )
                         result = True
                     else:
-                        errormsg = ("[DUT: {}] OSPF is not Converged, neighbor"
-                        " state is {}".format(router, nh_state))
+                        errormsg = (
+                            "[DUT: {}] OSPF is not Converged, neighbor"
+                            " state is {}".format(router, nh_state)
+                        )
                         return errormsg
                 if nbr_role:
                     if nbr_role == intf_state:
-                        logger.info("[DUT: {}] OSPF Nbr is {}: {} Role {}".format(
-                        router, ospf_nbr, nbr_rid, nbr_role))
+                        logger.info(
+                            "[DUT: {}] OSPF Nbr is {}: {} Role {}".format(
+                                router, ospf_nbr, nbr_rid, nbr_role
+                            )
+                        )
                     else:
-                        errormsg = ("[DUT: {}] OSPF is not Converged with rid"
-                        "{}, role is {}".format(router, nbr_rid, intf_state))
+                        errormsg = (
+                            "[DUT: {}] OSPF is not Converged with rid"
+                            "{}, role is {}".format(router, nbr_rid, intf_state)
+                        )
                         return errormsg
                 continue
     else:
         for router, rnode in tgen.routers().items():
-            if 'ospf' not in topo['routers'][router]:
+            if "ospf" not in topo["routers"][router]:
                 continue
 
             if dut is not None and dut != router:
                 continue
 
             logger.info("Verifying OSPF neighborship on router %s:", router)
-            show_ospf_json = run_frr_cmd(rnode,
-                "show ip ospf neighbor  all json", isjson=True)
+            show_ospf_json = run_frr_cmd(
+                rnode, "show ip ospf neighbor  all json", isjson=True
+            )
             # Verifying output dictionary show_ospf_json is empty or not
             if not bool(show_ospf_json):
                 errormsg = "OSPF is not running"
                 return errormsg
 
             ospf_data_list = topo["routers"][router]["ospf"]
-            ospf_neighbors = ospf_data_list['neighbors']
+            ospf_neighbors = ospf_data_list["neighbors"]
             total_peer = 0
             total_peer = len(ospf_neighbors.keys())
             no_of_ospf_nbr = 0
-            ospf_nbr_list = ospf_data_list['neighbors']
+            ospf_nbr_list = ospf_data_list["neighbors"]
             no_of_peer = 0
             for ospf_nbr, nbr_data in ospf_nbr_list.items():
                 if nbr_data:
-                    data_ip = topo['routers'][nbr_data["nbr"]]['links']
-                    data_rid = topo['routers'][nbr_data["nbr"]][
-                        'ospf']['router_id']
+                    data_ip = topo["routers"][nbr_data["nbr"]]["links"]
+                    data_rid = topo["routers"][nbr_data["nbr"]]["ospf"]["router_id"]
                 else:
-                    data_ip = topo['routers'][ospf_nbr]['links']
-                    data_rid = topo['routers'][ospf_nbr]['ospf']['router_id']
+                    data_ip = topo["routers"][ospf_nbr]["links"]
+                    data_rid = topo["routers"][ospf_nbr]["ospf"]["router_id"]
                 if ospf_nbr in data_ip:
                     nbr_details = nbr_data[ospf_nbr]
                 elif lan:
-                    for switch in topo['switches']:
-                        if 'ospf' in topo['switches'][switch]['links'][router]:
-                            neighbor_ip = data_ip[switch]['ipv4'].split("/")[0]
+                    for switch in topo["switches"]:
+                        if "ospf" in topo["switches"][switch]["links"][router]:
+                            neighbor_ip = data_ip[switch]["ipv4"].split("/")[0]
                         else:
                             continue
                 else:
-                    neighbor_ip = data_ip[router]['ipv4'].split("/")[0]
+                    neighbor_ip = data_ip[router]["ipv4"].split("/")[0]
 
                 nh_state = None
                 neighbor_ip = neighbor_ip.lower()
                 nbr_rid = data_rid
                 try:
-                    nh_state = show_ospf_json[nbr_rid][0][
-                        'state'].split('/')[0]
+                    nh_state = show_ospf_json[nbr_rid][0]["state"].split("/")[0]
                 except KeyError:
-                    errormsg = "[DUT: {}] OSPF peer {} missing,from "\
-                        "{} ".format(router,
-                    nbr_rid, ospf_nbr)
+                    errormsg = "[DUT: {}] OSPF peer {} missing,from " "{} ".format(
+                        router, nbr_rid, ospf_nbr
+                    )
                     return errormsg
 
-                if nh_state == 'Full':
+                if nh_state == "Full":
                     no_of_peer += 1
 
             if no_of_peer == total_peer:
                 logger.info("[DUT: {}] OSPF is Converged".format(router))
                 result = True
             else:
-                errormsg = ("[DUT: {}] OSPF is not Converged".format(router))
+                errormsg = "[DUT: {}] OSPF is not Converged".format(router)
                 return errormsg
 
     logger.debug("Exiting API: verify_ospf_neighbor()")
     return result
 
+
 @retry(attempts=21, wait=2, return_is_str=True)
-def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
-            tag=None, metric=None, fib=None):
+def verify_ospf_rib(
+    tgen, dut, input_dict, next_hop=None, tag=None, metric=None, fib=None
+):
     """
     This API is to verify ospf routes by running
     show ip ospf route command.
@@ -706,25 +715,28 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
             found_routes = []
             missing_routes = []
 
-            if "static_routes" in input_dict[routerInput] or \
-                "prefix" in input_dict[routerInput]:
+            if (
+                "static_routes" in input_dict[routerInput]
+                or "prefix" in input_dict[routerInput]
+            ):
                 if "prefix" in input_dict[routerInput]:
                     static_routes = input_dict[routerInput]["prefix"]
                 else:
                     static_routes = input_dict[routerInput]["static_routes"]
 
-
                 for static_route in static_routes:
                     cmd = "{}".format(command)
 
                     cmd = "{} json".format(cmd)
 
-                    ospf_rib_json =  run_frr_cmd(rnode, cmd, isjson=True)
+                    ospf_rib_json = run_frr_cmd(rnode, cmd, isjson=True)
 
                     # Verifying output dictionary ospf_rib_json is not empty
                     if bool(ospf_rib_json) is False:
-                        errormsg = "[DUT: {}] No routes found in OSPF route " \
+                        errormsg = (
+                            "[DUT: {}] No routes found in OSPF route "
                             "table".format(router)
+                        )
                         return errormsg
 
                     network = static_route["network"]
@@ -732,7 +744,6 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
                     _tag = static_route.setdefault("tag", None)
                     _rtype = static_route.setdefault("routeType", None)
 
-
                     # Generating IPs for verification
                     ip_list = generate_ips(network, no_of_ip)
                     st_found = False
@@ -742,7 +753,7 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
                         st_rt = str(ipaddr.IPNetwork(frr_unicode(st_rt)))
 
                         _addr_type = validate_ip_address(st_rt)
-                        if _addr_type != 'ipv4':
+                        if _addr_type != "ipv4":
                             continue
 
                         if st_rt in ospf_rib_json:
@@ -754,17 +765,26 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
                                     next_hop = [next_hop]
 
                                 for mnh in range(0, len(ospf_rib_json[st_rt])):
-                                    if 'fib' in ospf_rib_json[st_rt][
-                                        mnh]["nexthops"][0]:
-                                        found_hops.append([rib_r[
-                                            "ip"] for rib_r in ospf_rib_json[
-                                                st_rt][mnh]["nexthops"]])
+                                    if (
+                                        "fib"
+                                        in ospf_rib_json[st_rt][mnh]["nexthops"][0]
+                                    ):
+                                        found_hops.append(
+                                            [
+                                                rib_r["ip"]
+                                                for rib_r in ospf_rib_json[st_rt][mnh][
+                                                    "nexthops"
+                                                ]
+                                            ]
+                                        )
 
                                 if found_hops[0]:
-                                    missing_list_of_nexthops = \
-                                        set(found_hops[0]).difference(next_hop)
-                                    additional_nexthops_in_required_nhs = \
-                                        set(next_hop).difference(found_hops[0])
+                                    missing_list_of_nexthops = set(
+                                        found_hops[0]
+                                    ).difference(next_hop)
+                                    additional_nexthops_in_required_nhs = set(
+                                        next_hop
+                                    ).difference(found_hops[0])
 
                                     if additional_nexthops_in_required_nhs:
                                         logger.info(
@@ -772,13 +792,18 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
                                             "%s is not active for route %s in "
                                             "RIB of router %s\n",
                                             additional_nexthops_in_required_nhs,
-                                            st_rt, dut)
+                                            st_rt,
+                                            dut,
+                                        )
                                         errormsg = (
                                             "Nexthop {} is not active"
                                             " for route {} in RIB of router"
                                             " {}\n".format(
-                                            additional_nexthops_in_required_nhs,
-                                            st_rt, dut))
+                                                additional_nexthops_in_required_nhs,
+                                                st_rt,
+                                                dut,
+                                            )
+                                        )
                                         return errormsg
                                     else:
                                         nh_found = True
@@ -786,99 +811,111 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
                             elif next_hop and fib is None:
                                 if type(next_hop) is not list:
                                     next_hop = [next_hop]
-                                found_hops = [rib_r["ip"] for rib_r in
-                                              ospf_rib_json[st_rt][
-                                    "nexthops"]]
+                                found_hops = [
+                                    rib_r["ip"]
+                                    for rib_r in ospf_rib_json[st_rt]["nexthops"]
+                                ]
 
                                 if found_hops:
-                                    missing_list_of_nexthops = \
-                                        set(found_hops).difference(next_hop)
-                                    additional_nexthops_in_required_nhs = \
-                                        set(next_hop).difference(found_hops)
+                                    missing_list_of_nexthops = set(
+                                        found_hops
+                                    ).difference(next_hop)
+                                    additional_nexthops_in_required_nhs = set(
+                                        next_hop
+                                    ).difference(found_hops)
 
                                     if additional_nexthops_in_required_nhs:
                                         logger.info(
-                                            "Missing nexthop %s for route"\
-                                        " %s in RIB of router %s\n", \
-                                        additional_nexthops_in_required_nhs,  \
-                                        st_rt, dut)
-                                        errormsg=("Nexthop {} is Missing for "\
-                                        "route {} in RIB of router {}\n".format(
+                                            "Missing nexthop %s for route"
+                                            " %s in RIB of router %s\n",
                                             additional_nexthops_in_required_nhs,
-                                            st_rt, dut))
+                                            st_rt,
+                                            dut,
+                                        )
+                                        errormsg = (
+                                            "Nexthop {} is Missing for "
+                                            "route {} in RIB of router {}\n".format(
+                                                additional_nexthops_in_required_nhs,
+                                                st_rt,
+                                                dut,
+                                            )
+                                        )
                                         return errormsg
                                     else:
                                         nh_found = True
                             if _rtype:
-                                if "routeType" not in ospf_rib_json[
-                                    st_rt]:
-                                    errormsg = ("[DUT: {}]: routeType missing"
-                                                "for route {} in OSPF RIB \n".\
-                                                format(dut, st_rt))
+                                if "routeType" not in ospf_rib_json[st_rt]:
+                                    errormsg = (
+                                        "[DUT: {}]: routeType missing"
+                                        "for route {} in OSPF RIB \n".format(dut, st_rt)
+                                    )
                                     return errormsg
-                                elif _rtype != ospf_rib_json[st_rt][
-                                    "routeType"]:
-                                    errormsg = ("[DUT: {}]: routeType mismatch"
-                                                "for route {} in OSPF RIB \n".\
-                                                format(dut, st_rt))
+                                elif _rtype != ospf_rib_json[st_rt]["routeType"]:
+                                    errormsg = (
+                                        "[DUT: {}]: routeType mismatch"
+                                        "for route {} in OSPF RIB \n".format(dut, st_rt)
+                                    )
                                     return errormsg
                                 else:
-                                    logger.info("DUT: {}]: Found routeType {}"
-                                                "for route {}".\
-                                                format(dut, _rtype, st_rt))
+                                    logger.info(
+                                        "DUT: {}]: Found routeType {}"
+                                        "for route {}".format(dut, _rtype, st_rt)
+                                    )
                             if tag:
-                                if "tag" not in ospf_rib_json[
-                                    st_rt]:
-                                    errormsg = ("[DUT: {}]: tag is not"
-                                                " present for"
-                                                " route {} in RIB \n".\
-                                                format(dut, st_rt
-                                                ))
+                                if "tag" not in ospf_rib_json[st_rt]:
+                                    errormsg = (
+                                        "[DUT: {}]: tag is not"
+                                        " present for"
+                                        " route {} in RIB \n".format(dut, st_rt)
+                                    )
                                     return errormsg
 
-                                if _tag != ospf_rib_json[
-                                    st_rt]["tag"]:
-                                    errormsg = ("[DUT: {}]: tag value {}"
-                                                " is not matched for"
-                                                " route {} in RIB \n".\
-                                                format(dut, _tag, st_rt,
-                                                ))
+                                if _tag != ospf_rib_json[st_rt]["tag"]:
+                                    errormsg = (
+                                        "[DUT: {}]: tag value {}"
+                                        " is not matched for"
+                                        " route {} in RIB \n".format(dut, _tag, st_rt,)
+                                    )
                                     return errormsg
 
                             if metric is not None:
-                                if "type2cost" not in ospf_rib_json[
-                                    st_rt]:
-                                    errormsg = ("[DUT: {}]: metric is"
-                                                " not present for"
-                                                " route {} in RIB \n".\
-                                                format(dut, st_rt))
+                                if "type2cost" not in ospf_rib_json[st_rt]:
+                                    errormsg = (
+                                        "[DUT: {}]: metric is"
+                                        " not present for"
+                                        " route {} in RIB \n".format(dut, st_rt)
+                                    )
                                     return errormsg
 
-                                if metric != ospf_rib_json[
-                                    st_rt]["type2cost"]:
-                                    errormsg = ("[DUT: {}]: metric value "
-                                                "{} is not matched for "
-                                                "route {} in RIB \n".\
-                                                format(dut, metric, st_rt,
-                                                ))
+                                if metric != ospf_rib_json[st_rt]["type2cost"]:
+                                    errormsg = (
+                                        "[DUT: {}]: metric value "
+                                        "{} is not matched for "
+                                        "route {} in RIB \n".format(dut, metric, st_rt,)
+                                    )
                                     return errormsg
 
                         else:
                             missing_routes.append(st_rt)
 
                 if nh_found:
-                    logger.info("[DUT: {}]: Found next_hop {} for all OSPF"
-                                " routes in RIB".format(router, next_hop))
+                    logger.info(
+                        "[DUT: {}]: Found next_hop {} for all OSPF"
+                        " routes in RIB".format(router, next_hop)
+                    )
 
                 if len(missing_routes) > 0:
-                    errormsg = ("[DUT: {}]: Missing route in RIB, "
-                                "routes: {}".\
-                                    format(dut, missing_routes))
+                    errormsg = "[DUT: {}]: Missing route in RIB, " "routes: {}".format(
+                        dut, missing_routes
+                    )
                     return errormsg
 
                 if found_routes:
-                    logger.info("[DUT: %s]: Verified routes in RIB, found"
-                                " routes are: %s\n", dut, found_routes)
+                    logger.info(
+                        "[DUT: %s]: Verified routes in RIB, found" " routes are: %s\n",
+                        dut,
+                        found_routes,
+                    )
                     result = True
 
     logger.info("Exiting lib API: verify_ospf_rib()")
@@ -886,7 +923,7 @@ def verify_ospf_rib(tgen, dut, input_dict, next_hop=None,
 
 
 @retry(attempts=10, wait=2, return_is_str=True)
-def verify_ospf_interface(tgen, topo, dut=None,lan=False, input_dict=None):
+def verify_ospf_interface(tgen, topo, dut=None, lan=False, input_dict=None):
     """
     This API is to verify ospf routes by running
     show ip ospf interface command.
@@ -928,15 +965,14 @@ def verify_ospf_interface(tgen, topo, dut=None,lan=False, input_dict=None):
     logger.debug("Entering lib API: verify_ospf_interface()")
     result = False
     for router, rnode in tgen.routers().items():
-        if 'ospf' not in topo['routers'][router]:
+        if "ospf" not in topo["routers"][router]:
             continue
 
         if dut is not None and dut != router:
             continue
 
         logger.info("Verifying OSPF interface on router %s:", router)
-        show_ospf_json = run_frr_cmd(rnode, "show ip ospf interface json",
-                                    isjson=True)
+        show_ospf_json = run_frr_cmd(rnode, "show ip ospf interface json", isjson=True)
 
         # Verifying output dictionary show_ospf_json is empty or not
         if not bool(show_ospf_json):
@@ -946,19 +982,29 @@ def verify_ospf_interface(tgen, topo, dut=None,lan=False, input_dict=None):
         # To find neighbor ip type
         ospf_intf_data = input_dict[router]["links"]
         for ospf_intf, intf_data in ospf_intf_data.items():
-            intf = topo['routers'][router]['links'][ospf_intf]['interface']
-            if  intf in show_ospf_json['interfaces']:
-                for intf_attribute in intf_data['ospf']:
-                    if intf_data['ospf'][intf_attribute] ==  show_ospf_json[
-                        'interfaces'][intf][intf_attribute]:
-                        logger.info("[DUT: %s] OSPF interface %s: %s is %s",
-                        router, intf, intf_attribute, intf_data['ospf'][
-                            intf_attribute])
+            intf = topo["routers"][router]["links"][ospf_intf]["interface"]
+            if intf in show_ospf_json["interfaces"]:
+                for intf_attribute in intf_data["ospf"]:
+                    if (
+                        intf_data["ospf"][intf_attribute]
+                        == show_ospf_json["interfaces"][intf][intf_attribute]
+                    ):
+                        logger.info(
+                            "[DUT: %s] OSPF interface %s: %s is %s",
+                            router,
+                            intf,
+                            intf_attribute,
+                            intf_data["ospf"][intf_attribute],
+                        )
                     else:
-                        errormsg= "[DUT: {}] OSPF interface {}: {} is {}, \
-                        Expected is {}".format(router, intf, intf_attribute,
-                        intf_data['ospf'][intf_attribute], show_ospf_json[
-                             'interfaces'][intf][intf_attribute])
+                        errormsg = "[DUT: {}] OSPF interface {}: {} is {}, \
+                        Expected is {}".format(
+                            router,
+                            intf,
+                            intf_attribute,
+                            intf_data["ospf"][intf_attribute],
+                            show_ospf_json["interfaces"][intf][intf_attribute],
+                        )
                         return errormsg
         result = True
     logger.debug("Exiting API: verify_ospf_interface()")
@@ -1016,16 +1062,14 @@ def verify_ospf_database(tgen, topo, dut, input_dict):
     router = dut
     logger.debug("Entering lib API: verify_ospf_database()")
 
-    if 'ospf' not in topo['routers'][dut]:
-        errormsg = "[DUT: {}] OSPF is not configured on the router.".format(
-            dut)
+    if "ospf" not in topo["routers"][dut]:
+        errormsg = "[DUT: {}] OSPF is not configured on the router.".format(dut)
         return errormsg
 
     rnode = tgen.routers()[dut]
 
     logger.info("Verifying OSPF interface on router %s:", dut)
-    show_ospf_json = run_frr_cmd(rnode, "show ip ospf database json",
-                                isjson=True)
+    show_ospf_json = run_frr_cmd(rnode, "show ip ospf database json", isjson=True)
     # Verifying output dictionary show_ospf_json is empty or not
     if not bool(show_ospf_json):
         errormsg = "OSPF is not running"
@@ -1033,82 +1077,103 @@ def verify_ospf_database(tgen, topo, dut, input_dict):
 
     # for inter and inter lsa's
     ospf_db_data = input_dict.setdefault("areas", None)
-    ospf_external_lsa = input_dict.setdefault(
-        'AS External Link States', None)
+    ospf_external_lsa = input_dict.setdefault("AS External Link States", None)
     if ospf_db_data:
-            for ospf_area, area_lsa in ospf_db_data.items():
-                if ospf_area in show_ospf_json['areas']:
-                    if 'Router Link States' in area_lsa:
-                        for lsa in area_lsa['Router Link States']:
-                            if lsa in show_ospf_json['areas'][ospf_area][
-                                'Router Link States']:
-                                logger.info(
-                                    "[DUT: %s]  OSPF LSDB area %s:Router "
-                                    "LSA %s", router, ospf_area, lsa)
-                                result = True
-                            else:
-                                errormsg = \
-                                "[DUT: {}]  OSPF LSDB area {}: expected" \
+        for ospf_area, area_lsa in ospf_db_data.items():
+            if ospf_area in show_ospf_json["areas"]:
+                if "Router Link States" in area_lsa:
+                    for lsa in area_lsa["Router Link States"]:
+                        if (
+                            lsa
+                            in show_ospf_json["areas"][ospf_area]["Router Link States"]
+                        ):
+                            logger.info(
+                                "[DUT: %s]  OSPF LSDB area %s:Router " "LSA %s",
+                                router,
+                                ospf_area,
+                                lsa,
+                            )
+                            result = True
+                        else:
+                            errormsg = (
+                                "[DUT: {}]  OSPF LSDB area {}: expected"
                                 " Router LSA is {}".format(router, ospf_area, lsa)
-                                return errormsg
-                    if 'Net Link States' in area_lsa:
-                        for lsa in area_lsa['Net Link States']:
-                            if lsa in show_ospf_json['areas'][ospf_area][
-                                    'Net Link States']:
-                                logger.info(
-                                    "[DUT: %s]  OSPF LSDB area %s:Network "
-                                    "LSA %s", router, ospf_area, lsa)
-                                result = True
-                            else:
-                                errormsg = \
-                                "[DUT: {}]  OSPF LSDB area {}: expected" \
+                            )
+                            return errormsg
+                if "Net Link States" in area_lsa:
+                    for lsa in area_lsa["Net Link States"]:
+                        if lsa in show_ospf_json["areas"][ospf_area]["Net Link States"]:
+                            logger.info(
+                                "[DUT: %s]  OSPF LSDB area %s:Network " "LSA %s",
+                                router,
+                                ospf_area,
+                                lsa,
+                            )
+                            result = True
+                        else:
+                            errormsg = (
+                                "[DUT: {}]  OSPF LSDB area {}: expected"
                                 " Network LSA is {}".format(router, ospf_area, lsa)
-                                return errormsg
-                    if 'Summary Link States' in area_lsa:
-                        for lsa in area_lsa['Summary Link States']:
-                            if lsa in show_ospf_json['areas'][ospf_area][
-                                    'Summary Link States']:
-                                logger.info(
-                                    "[DUT: %s]  OSPF LSDB area %s:Summary "
-                                    "LSA %s", router, ospf_area, lsa)
-                                result = True
-                            else:
-                                errormsg = \
-                                "[DUT: {}]  OSPF LSDB area {}: expected" \
+                            )
+                            return errormsg
+                if "Summary Link States" in area_lsa:
+                    for lsa in area_lsa["Summary Link States"]:
+                        if (
+                            lsa
+                            in show_ospf_json["areas"][ospf_area]["Summary Link States"]
+                        ):
+                            logger.info(
+                                "[DUT: %s]  OSPF LSDB area %s:Summary " "LSA %s",
+                                router,
+                                ospf_area,
+                                lsa,
+                            )
+                            result = True
+                        else:
+                            errormsg = (
+                                "[DUT: {}]  OSPF LSDB area {}: expected"
                                 " Summary LSA is {}".format(router, ospf_area, lsa)
-                                return errormsg
-                    if 'ASBR-Summary Link States' in area_lsa:
-                        for lsa in area_lsa['ASBR-Summary Link States']:
-                            if lsa in show_ospf_json['areas'][ospf_area][
-                                    'ASBR-Summary Link States']:
-                                logger.info(
-                                    "[DUT: %s]  OSPF LSDB area %s:ASBR Summary "
-                                    "LSA %s", router, ospf_area, lsa)
-                                result = True
-                            else:
-                                errormsg = \
-                                    "[DUT: {}]  OSPF LSDB area {}: expected" \
-                                    " ASBR Summary LSA is {}".format(
-                                        router, ospf_area, lsa)
-                                return errormsg
+                            )
+                            return errormsg
+                if "ASBR-Summary Link States" in area_lsa:
+                    for lsa in area_lsa["ASBR-Summary Link States"]:
+                        if (
+                            lsa
+                            in show_ospf_json["areas"][ospf_area][
+                                "ASBR-Summary Link States"
+                            ]
+                        ):
+                            logger.info(
+                                "[DUT: %s]  OSPF LSDB area %s:ASBR Summary " "LSA %s",
+                                router,
+                                ospf_area,
+                                lsa,
+                            )
+                            result = True
+                        else:
+                            errormsg = (
+                                "[DUT: {}]  OSPF LSDB area {}: expected"
+                                " ASBR Summary LSA is {}".format(router, ospf_area, lsa)
+                            )
+                            return errormsg
     if ospf_external_lsa:
-            for ospf_ext_lsa, ext_lsa_data in ospf_external_lsa.items():
-                if ospf_ext_lsa in show_ospf_json['AS External Link States']:
-                    logger.info(
-                            "[DUT: %s]  OSPF LSDB:External LSA %s",
-                            router, ospf_ext_lsa)
-                    result = True
-                else:
-                    errormsg = \
-                            "[DUT: {}]  OSPF LSDB : expected" \
-                            " External LSA is {}".format(router, ospf_ext_lsa)
-                    return errormsg
+        for ospf_ext_lsa, ext_lsa_data in ospf_external_lsa.items():
+            if ospf_ext_lsa in show_ospf_json["AS External Link States"]:
+                logger.info(
+                    "[DUT: %s]  OSPF LSDB:External LSA %s", router, ospf_ext_lsa
+                )
+                result = True
+            else:
+                errormsg = (
+                    "[DUT: {}]  OSPF LSDB : expected"
+                    " External LSA is {}".format(router, ospf_ext_lsa)
+                )
+                return errormsg
 
     logger.debug("Exiting API: verify_ospf_database()")
     return result
 
 
-
 @retry(attempts=10, wait=2, return_is_str=True)
 def verify_ospf_summary(tgen, topo, dut, input_dict):
     """
@@ -1146,14 +1211,12 @@ def verify_ospf_summary(tgen, topo, dut, input_dict):
 
     logger.info("Verifying OSPF summary on router %s:", router)
 
-    if 'ospf' not in topo['routers'][dut]:
-        errormsg = "[DUT: {}] OSPF is not configured on the router.".format(
-            router)
+    if "ospf" not in topo["routers"][dut]:
+        errormsg = "[DUT: {}] OSPF is not configured on the router.".format(router)
         return errormsg
 
     rnode = tgen.routers()[dut]
-    show_ospf_json = run_frr_cmd(rnode, "show ip ospf summary detail json",
-                                 isjson=True)
+    show_ospf_json = run_frr_cmd(rnode, "show ip ospf summary detail json", isjson=True)
 
     # Verifying output dictionary show_ospf_json is empty or not
     if not bool(show_ospf_json):
@@ -1165,17 +1228,25 @@ def verify_ospf_summary(tgen, topo, dut, input_dict):
     for ospf_summ, summ_data in ospf_summary_data.items():
         if ospf_summ not in show_ospf_json:
             continue
-        summary = ospf_summary_data[ospf_summ]['Summary address']
+        summary = ospf_summary_data[ospf_summ]["Summary address"]
         if summary in show_ospf_json:
             for summ in summ_data:
                 if summ_data[summ] == show_ospf_json[summary][summ]:
-                    logger.info("[DUT: %s] OSPF summary %s:%s is %s",
-                                router, summary, summ, summ_data[summ])
+                    logger.info(
+                        "[DUT: %s] OSPF summary %s:%s is %s",
+                        router,
+                        summary,
+                        summ,
+                        summ_data[summ],
+                    )
                     result = True
                 else:
-                    errormsg = ("[DUT: {}] OSPF summary {}:{} is %s, "
-                    "Expected is {}".format(router,summary, summ,
-                    show_ospf_json[summary][summ]))
+                    errormsg = (
+                        "[DUT: {}] OSPF summary {}:{} is %s, "
+                        "Expected is {}".format(
+                            router, summary, summ, show_ospf_json[summary][summ]
+                        )
+                    )
                     return errormsg
 
     logger.debug("Exiting API: verify_ospf_summary()")
index 7a061a9bc696bcd2637fa3caf68a44aa6805bb13..b85e193d3bc08cd1c38b346bfdb169e39d4ec98e 100755 (executable)
@@ -296,7 +296,7 @@ def test_json_list_ordered():
     ]
 
     dsub1 = [
-        '__ordered__',
+        "__ordered__",
         "some string",
         {"id": 1, "value": "abc"},
         123,
@@ -312,28 +312,28 @@ def test_json_list_exact_matching():
         {"id": 1, "value": "abc"},
         "some string",
         123,
-        [1,2,3],
+        [1, 2, 3],
     ]
 
     dsub1 = [
         "some string",
         {"id": 1, "value": "abc"},
         123,
-        [1,2,3],
+        [1, 2, 3],
     ]
 
     dsub2 = [
         {"id": 1},
         "some string",
         123,
-        [1,2,3],
+        [1, 2, 3],
     ]
 
     dsub3 = [
         {"id": 1, "value": "abc"},
         "some string",
         123,
-        [1,3,2],
+        [1, 3, 2],
     ]
 
     assert json_cmp(dcomplete, dsub1, exact=True) is not None
@@ -344,30 +344,30 @@ def test_json_object_exact_matching():
     "Test JSON object on exact matching using the 'exact' parameter."
 
     dcomplete = {
-        'a': {"id": 1, "value": "abc"},
-        'b': "some string",
-        'c': 123,
-        'd': [1,2,3],
+        "a": {"id": 1, "value": "abc"},
+        "b": "some string",
+        "c": 123,
+        "d": [1, 2, 3],
     }
 
     dsub1 = {
-        'a': {"id": 1, "value": "abc"},
-        'c': 123,
-        'd': [1,2,3],
+        "a": {"id": 1, "value": "abc"},
+        "c": 123,
+        "d": [1, 2, 3],
     }
 
     dsub2 = {
-        'a': {"id": 1},
-        'b': "some string",
-        'c': 123,
-        'd': [1,2,3],
+        "a": {"id": 1},
+        "b": "some string",
+        "c": 123,
+        "d": [1, 2, 3],
     }
 
     dsub3 = {
-        'a': {"id": 1, "value": "abc"},
-        'b': "some string",
-        'c': 123,
-        'd': [1,3],
+        "a": {"id": 1, "value": "abc"},
+        "b": "some string",
+        "c": 123,
+        "d": [1, 3],
     }
 
     assert json_cmp(dcomplete, dsub1, exact=True) is not None
@@ -382,35 +382,35 @@ def test_json_list_asterisk_matching():
         {"id": 1, "value": "abc"},
         "some string",
         123,
-        [1,2,3],
+        [1, 2, 3],
     ]
 
     dsub1 = [
-        '*',
+        "*",
         "some string",
         123,
-        [1,2,3],
+        [1, 2, 3],
     ]
 
     dsub2 = [
-        {"id": '*', "value": "abc"},
+        {"id": "*", "value": "abc"},
         "some string",
         123,
-        [1,2,3],
+        [1, 2, 3],
     ]
 
     dsub3 = [
         {"id": 1, "value": "abc"},
         "some string",
         123,
-        [1,'*',3],
+        [1, "*", 3],
     ]
 
     dsub4 = [
-        '*',
+        "*",
         "some string",
-        '*',
-        [1,2,3],
+        "*",
+        [1, 2, 3],
     ]
 
     assert json_cmp(dcomplete, dsub1) is None
@@ -423,38 +423,38 @@ def test_json_object_asterisk_matching():
     "Test JSON object value elements on matching '*' as a placeholder for arbitrary data."
 
     dcomplete = {
-        'a': {"id": 1, "value": "abc"},
-        'b': "some string",
-        'c': 123,
-        'd': [1,2,3],
+        "a": {"id": 1, "value": "abc"},
+        "b": "some string",
+        "c": 123,
+        "d": [1, 2, 3],
     }
 
     dsub1 = {
-        'a': '*',
-        'b': "some string",
-        'c': 123,
-        'd': [1,2,3],
+        "a": "*",
+        "b": "some string",
+        "c": 123,
+        "d": [1, 2, 3],
     }
 
     dsub2 = {
-        'a': {"id": 1, "value": "abc"},
-        'b': "some string",
-        'c': 123,
-        'd': [1,'*',3],
+        "a": {"id": 1, "value": "abc"},
+        "b": "some string",
+        "c": 123,
+        "d": [1, "*", 3],
     }
 
     dsub3 = {
-        'a': {"id": '*', "value": "abc"},
-        'b': "some string",
-        'c': 123,
-        'd': [1,2,3],
+        "a": {"id": "*", "value": "abc"},
+        "b": "some string",
+        "c": 123,
+        "d": [1, 2, 3],
     }
 
     dsub4 = {
-        'a': '*',
-        'b': "some string",
-        'c': '*',
-        'd': [1,2,3],
+        "a": "*",
+        "b": "some string",
+        "c": "*",
+        "d": [1, 2, 3],
     }
 
     assert json_cmp(dcomplete, dsub1) is None
@@ -465,37 +465,12 @@ def test_json_object_asterisk_matching():
 
 def test_json_list_nested_with_objects():
 
-    dcomplete = [
-        {
-            "key": 1,
-            "list": [
-                123
-            ]
-        },
-        {
-            "key": 2,
-            "list": [
-                123
-            ]
-        }
-    ]
+    dcomplete = [{"key": 1, "list": [123]}, {"key": 2, "list": [123]}]
 
-    dsub1 = [
-        {
-            "key": 2,
-            "list": [
-                123
-            ]
-        },
-        {
-            "key": 1,
-            "list": [
-                123
-            ]
-        }
-    ]
+    dsub1 = [{"key": 2, "list": [123]}, {"key": 1, "list": [123]}]
 
     assert json_cmp(dcomplete, dsub1) is None
 
+
 if __name__ == "__main__":
     sys.exit(pytest.main())
index ffdcb683e7f398c5c0341510d03cd484909cd117..3e92bd7565249e5190aa3ac63d6b4853f07a2bcc 100644 (file)
@@ -703,11 +703,9 @@ class TopoRouter(TopoGear):
         Stop router, private internal version
         * Kill daemons
         """
-        self.logger.debug("stopping: wait {}, assert {}".format(
-            wait, assertOnError))
+        self.logger.debug("stopping: wait {}, assert {}".format(wait, assertOnError))
         return self.tgen.net[self.name].stopRouter(wait, assertOnError)
 
-
     def stop(self):
         """
         Stop router cleanly:
@@ -724,7 +722,7 @@ class TopoRouter(TopoGear):
         * Start daemons (e.g. FRR)
         * Configure daemon logging files
         """
-        self.logger.debug('starting')
+        self.logger.debug("starting")
         nrouter = self.tgen.net[self.name]
         result = nrouter.startRouterDaemons(daemons)
 
@@ -734,10 +732,12 @@ class TopoRouter(TopoGear):
             for d in daemons:
                 if enabled == 0:
                     continue
-                self.vtysh_cmd('configure terminal\nlog commands\nlog file {}.log'.\
-                    format(daemon), daemon=daemon)
+                self.vtysh_cmd(
+                    "configure terminal\nlog commands\nlog file {}.log".format(daemon),
+                    daemon=daemon,
+                )
 
-        if result != '':
+        if result != "":
             self.tgen.set_error(result)
 
         return result
@@ -747,7 +747,7 @@ class TopoRouter(TopoGear):
         Kill specific daemon(user defined daemon only)
         forcefully using SIGKILL
         """
-        self.logger.debug('Killing daemons using SIGKILL..')
+        self.logger.debug("Killing daemons using SIGKILL..")
         return self.tgen.net[self.name].killRouterDaemons(daemons, wait, assertOnError)
 
     def vtysh_cmd(self, command, isjson=False, daemon=None):
@@ -1070,7 +1070,7 @@ def diagnose_env_linux():
             "isisd",
             "pimd",
             "ldpd",
-            "pbrd"
+            "pbrd",
         ]:
             path = os.path.join(frrdir, fname)
             if not os.path.isfile(path):
index 6535918e3629cfccb8d22fc3c4d7b20c5d8d94ef..f2fafa5e2a91a22fbf1e99e87cf122e174a4be73 100644 (file)
@@ -45,6 +45,7 @@ from lib.common_config import (
 
 from lib.bgp import create_router_bgp
 from lib.ospf import create_router_ospf
+
 ROUTER_LIST = []
 
 
@@ -214,13 +215,14 @@ def build_topo_from_json(tgen, topo):
     while listSwitches != []:
         curSwitch = listSwitches.pop(0)
         # Physical Interfaces
-        if "links" in  topo['switches'][curSwitch]:
+        if "links" in topo["switches"][curSwitch]:
             for destRouterLink, data in sorted(
-                    topo['switches'][curSwitch]['links'].items()):
+                topo["switches"][curSwitch]["links"].items()
+            ):
 
                 # Loopback interfaces
                 if "dst_node" in data:
-                    destRouter = data['dst_node']
+                    destRouter = data["dst_node"]
 
                 elif "-" in destRouterLink:
                     # Spliting and storing destRouterLink data in tempList
@@ -232,39 +234,55 @@ def build_topo_from_json(tgen, topo):
 
                 if destRouter in listAllRouters:
 
-                    topo['routers'][destRouter]['links'][curSwitch] = \
-                        deepcopy(topo['switches'][curSwitch]['links'][destRouterLink])
+                    topo["routers"][destRouter]["links"][curSwitch] = deepcopy(
+                        topo["switches"][curSwitch]["links"][destRouterLink]
+                    )
 
                     # Assigning name to interfaces
-                    topo['routers'][destRouter]['links'][curSwitch]['interface'] = \
-                        '{}-{}-eth{}'.format(destRouter, curSwitch, topo['routers'] \
-                            [destRouter]['nextIfname'])
+                    topo["routers"][destRouter]["links"][curSwitch][
+                        "interface"
+                    ] = "{}-{}-eth{}".format(
+                        destRouter, curSwitch, topo["routers"][destRouter]["nextIfname"]
+                    )
 
-                    topo['switches'][curSwitch]['links'][destRouter]['interface'] = \
-                        '{}-{}-eth{}'.format(curSwitch, destRouter, topo['routers'] \
-                            [destRouter]['nextIfname'])
+                    topo["switches"][curSwitch]["links"][destRouter][
+                        "interface"
+                    ] = "{}-{}-eth{}".format(
+                        curSwitch, destRouter, topo["routers"][destRouter]["nextIfname"]
+                    )
 
-                    topo['routers'][destRouter]['nextIfname'] += 1
+                    topo["routers"][destRouter]["nextIfname"] += 1
 
                     # Add links
-                    dictSwitches[curSwitch].add_link(tgen.gears[destRouter], \
-                        topo['switches'][curSwitch]['links'][destRouter]['interface'],
-                        topo['routers'][destRouter]['links'][curSwitch]['interface'],
-                        )
+                    dictSwitches[curSwitch].add_link(
+                        tgen.gears[destRouter],
+                        topo["switches"][curSwitch]["links"][destRouter]["interface"],
+                        topo["routers"][destRouter]["links"][curSwitch]["interface"],
+                    )
 
                     # IPv4
-                    if 'ipv4' in topo['routers'][destRouter]['links'][curSwitch]:
-                        if topo['routers'][destRouter]['links'][curSwitch]['ipv4'] == 'auto':
-                            topo['routers'][destRouter]['links'][curSwitch]['ipv4'] = \
-                                '{}/{}'.format(ipv4Next, topo['link_ip_start'][ \
-                                    'v4mask'])
+                    if "ipv4" in topo["routers"][destRouter]["links"][curSwitch]:
+                        if (
+                            topo["routers"][destRouter]["links"][curSwitch]["ipv4"]
+                            == "auto"
+                        ):
+                            topo["routers"][destRouter]["links"][curSwitch][
+                                "ipv4"
+                            ] = "{}/{}".format(
+                                ipv4Next, topo["link_ip_start"]["v4mask"]
+                            )
                             ipv4Next += 1
                     # IPv6
-                    if 'ipv6' in topo['routers'][destRouter]['links'][curSwitch]:
-                        if topo['routers'][destRouter]['links'][curSwitch]['ipv6'] == 'auto':
-                            topo['routers'][destRouter]['links'][curSwitch]['ipv6'] = \
-                                '{}/{}'.format(ipv6Next, topo['link_ip_start'][ \
-                                    'v6mask'])
+                    if "ipv6" in topo["routers"][destRouter]["links"][curSwitch]:
+                        if (
+                            topo["routers"][destRouter]["links"][curSwitch]["ipv6"]
+                            == "auto"
+                        ):
+                            topo["routers"][destRouter]["links"][curSwitch][
+                                "ipv6"
+                            ] = "{}/{}".format(
+                                ipv6Next, topo["link_ip_start"]["v6mask"]
+                            )
                             ipv6Next = ipaddr.IPv6Address(int(ipv6Next) + ipv6Step)
 
             logger.debug(
@@ -294,7 +312,7 @@ def build_config_from_json(tgen, topo, save_bkup=True):
             ("bgp_community_list", create_bgp_community_lists),
             ("route_maps", create_route_maps),
             ("bgp", create_router_bgp),
-            ("ospf", create_router_ospf)
+            ("ospf", create_router_ospf),
         ]
     )
 
index a187971e41f4431af9c6b48eb0bed5b5e8b7cfcd..4b1886210161637ab88de7e6f9e54d05dee67406 100644 (file)
@@ -51,8 +51,9 @@ from mininet.log import setLogLevel, info
 from mininet.cli import CLI
 from mininet.link import Intf
 
+
 def gdb_core(obj, daemon, corefiles):
-    gdbcmds = '''
+    gdbcmds = """
         info threads
         bt full
         disassemble
@@ -66,21 +67,21 @@ def gdb_core(obj, daemon, corefiles):
         disassemble
         up
         disassemble
-    '''
-    gdbcmds = [['-ex', i.strip()] for i in gdbcmds.strip().split('\n')]
+    """
+    gdbcmds = [["-ex", i.strip()] for i in gdbcmds.strip().split("\n")]
     gdbcmds = [item for sl in gdbcmds for item in sl]
 
     daemon_path = os.path.join(obj.daemondir, daemon)
     backtrace = subprocess.check_output(
-        ['gdb', daemon_path, corefiles[0], '--batch'] + gdbcmds
+        ["gdb", daemon_path, corefiles[0], "--batch"] + gdbcmds
     )
     sys.stderr.write(
-        "\n%s: %s crashed. Core file found - Backtrace follows:\n"
-        % (obj.name, daemon)
+        "\n%s: %s crashed. Core file found - Backtrace follows:\n" % (obj.name, daemon)
     )
     sys.stderr.write("%s" % backtrace)
     return backtrace
 
+
 class json_cmp_result(object):
     "json_cmp result class for better assertion messages"
 
@@ -739,7 +740,8 @@ def ip4_vrf_route(node):
     }
     """
     output = normalize_text(
-            node.run("ip route show vrf {0}-cust1".format(node.name))).splitlines()
+        node.run("ip route show vrf {0}-cust1".format(node.name))
+    ).splitlines()
 
     result = {}
     for line in output:
@@ -821,7 +823,8 @@ def ip6_vrf_route(node):
     }
     """
     output = normalize_text(
-            node.run("ip -6 route show vrf {0}-cust1".format(node.name))).splitlines()
+        node.run("ip -6 route show vrf {0}-cust1".format(node.name))
+    ).splitlines()
     result = {}
     for line in output:
         columns = line.split(" ")
@@ -992,7 +995,7 @@ class Router(Node):
         # Backward compatibility:
         #   Load configuration defaults like topogen.
         self.config_defaults = configparser.ConfigParser(
-            defaults = {
+            defaults={
                 "verbosity": "info",
                 "frrdir": "/usr/lib/frr",
                 "routertype": "frr",
@@ -1095,7 +1098,7 @@ class Router(Node):
         if re.search(r"No such file or directory", rundaemons):
             return 0
         if rundaemons is not None:
-            bet = rundaemons.split('\n')
+            bet = rundaemons.split("\n")
             for d in bet[:-1]:
                 daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
                 if daemonpid.isdigit() and pid_exists(int(daemonpid)):
@@ -1110,24 +1113,28 @@ class Router(Node):
         if re.search(r"No such file or directory", rundaemons):
             return errors
         if rundaemons is not None:
-            dmns = rundaemons.split('\n')
+            dmns = rundaemons.split("\n")
             # Exclude empty string at end of list
             for d in dmns[:-1]:
                 daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
                 if daemonpid.isdigit() and pid_exists(int(daemonpid)):
                     daemonname = os.path.basename(d.rstrip().rsplit(".", 1)[0])
-                    logger.info(
-                        "{}: stopping {}".format(
-                            self.name, daemonname
-                        )
-                    )
+                    logger.info("{}: stopping {}".format(self.name, daemonname))
                     try:
                         os.kill(int(daemonpid), signal.SIGTERM)
                     except OSError as err:
                         if err.errno == errno.ESRCH:
-                            logger.error("{}: {} left a dead pidfile (pid={})".format(self.name, daemonname, daemonpid))
+                            logger.error(
+                                "{}: {} left a dead pidfile (pid={})".format(
+                                    self.name, daemonname, daemonpid
+                                )
+                            )
                         else:
-                            logger.info("{}: {} could not kill pid {}: {}".format(self.name, daemonname, daemonpid, str(err)))
+                            logger.info(
+                                "{}: {} could not kill pid {}: {}".format(
+                                    self.name, daemonname, daemonpid, str(err)
+                                )
+                            )
 
             if not wait:
                 return errors
@@ -1135,18 +1142,28 @@ class Router(Node):
             running = self.listDaemons()
 
             if running:
-                sleep(0.1, "{}: waiting for daemons stopping: {}".format(self.name, ', '.join(running)))
+                sleep(
+                    0.1,
+                    "{}: waiting for daemons stopping: {}".format(
+                        self.name, ", ".join(running)
+                    ),
+                )
                 running = self.listDaemons()
 
                 counter = 20
                 while counter > 0 and running:
-                    sleep(0.5, "{}: waiting for daemons stopping: {}".format(self.name, ', '.join(running)))
+                    sleep(
+                        0.5,
+                        "{}: waiting for daemons stopping: {}".format(
+                            self.name, ", ".join(running)
+                        ),
+                    )
                     running = self.listDaemons()
                     counter -= 1
 
             if running:
                 # 2nd round of kill if daemons didn't exit
-                dmns = rundaemons.split('\n')
+                dmns = rundaemons.split("\n")
                 # Exclude empty string at end of list
                 for d in dmns[:-1]:
                     daemonpid = self.cmd("cat %s" % d.rstrip()).rstrip()
@@ -1295,11 +1312,12 @@ class Router(Node):
     def startRouterDaemons(self, daemons=None):
         "Starts all FRR daemons for this router."
 
-        bundle_data = ''
+        bundle_data = ""
 
-        if os.path.exists('/etc/frr/support_bundle_commands.conf'):
+        if os.path.exists("/etc/frr/support_bundle_commands.conf"):
             bundle_data = subprocess.check_output(
-                ["cat /etc/frr/support_bundle_commands.conf"], shell=True)
+                ["cat /etc/frr/support_bundle_commands.conf"], shell=True
+            )
         self.cmd(
             "echo '{}' > /etc/frr/support_bundle_commands.conf".format(bundle_data)
         )
@@ -1400,7 +1418,7 @@ class Router(Node):
         for daemon in daemons:
             if rundaemons is not None and daemon in rundaemons:
                 numRunning = 0
-                dmns = rundaemons.split('\n')
+                dmns = rundaemons.split("\n")
                 # Exclude empty string at end of list
                 for d in dmns[:-1]:
                     if re.search(r"%s" % daemon, d):
@@ -1738,8 +1756,9 @@ class LegacySwitch(OVSSwitch):
         OVSSwitch.__init__(self, name, failMode="standalone", **params)
         self.switchIP = None
 
+
 def frr_unicode(s):
-    '''Convert string to unicode, depending on python version'''
+    """Convert string to unicode, depending on python version"""
     if sys.version_info[0] > 2:
         return s
     else:
index 86fc90e665ed0004396b9b4c4ee05376488e83e0..53322f432fee9347499357bdaf3349064fa8dd8b 100644 (file)
@@ -65,22 +65,22 @@ class OspfSrTopo(Topo):
             tgen.add_router("r{}".format(routern))
 
         # Interconect router 1 and 2 with 2 links
-        switch = tgen.add_switch('s1')
-        switch.add_link(tgen.gears['r1'])
-        switch.add_link(tgen.gears['r2'])
-        switch = tgen.add_switch('s2')
-        switch.add_link(tgen.gears['r1'])
-        switch.add_link(tgen.gears['r2'])
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
+        switch = tgen.add_switch("s2")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
 
         # Interconect router 3 and 2
-        switch = tgen.add_switch('s3')
-        switch.add_link(tgen.gears['r3'])
-        switch.add_link(tgen.gears['r2'])
+        switch = tgen.add_switch("s3")
+        switch.add_link(tgen.gears["r3"])
+        switch.add_link(tgen.gears["r2"])
 
         # Interconect router 4 and 2
-        switch = tgen.add_switch('s4')
-        switch.add_link(tgen.gears['r4'])
-        switch.add_link(tgen.gears['r2'])
+        switch = tgen.add_switch("s4")
+        switch.add_link(tgen.gears["r4"])
+        switch.add_link(tgen.gears["r2"])
 
 
 def setup_module(mod):
@@ -134,12 +134,13 @@ def test_ospf_sr():
         # Run test function until we get an result. Wait at most 60 seconds.
         rt = tgen.gears[router]
         test_func = partial(
-            topotest.router_json_cmp, rt, 'show ip ospf database segment-routing json', expected
+            topotest.router_json_cmp,
+            rt,
+            "show ip ospf database segment-routing json",
+            expected,
         )
         rv, diff = topotest.run_and_expect(test_func, None, count=25, wait=3)
-        assert rv, "OSPF did not start Segment Routing on {}:\n{}".format(
-            router, diff
-        )
+        assert rv, "OSPF did not start Segment Routing on {}:\n{}".format(router, diff)
 
 
 def test_ospf_kernel_route():
@@ -169,7 +170,7 @@ def test_ospf_kernel_route():
           }
         ]
         """
-        out = rt.vtysh_cmd('show mpls table json', isjson=True)
+        out = rt.vtysh_cmd("show mpls table json", isjson=True)
 
         outlist = []
         for key in out.keys():
index 79e8e6bf5877b5af6a0c2c9621c4957986e1dfa2..6451f5fb329ec964f5fca2f030d0b20abca83359 100644 (file)
@@ -35,7 +35,7 @@ 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, '../'))
+sys.path.append(os.path.join(CWD, "../"))
 
 # pylint: disable=C0413
 # Import topogen and topotest helpers
@@ -46,28 +46,30 @@ from lib.topolog import logger
 # Required to instantiate the topology builder class.
 from mininet.topo import Topo
 
+
 class OSPFTopo(Topo):
     "Test topology builder"
+
     def build(self, *_args, **_opts):
         "Build function"
         tgen = get_topogen(self)
 
         # Create 4 routers
         for routern in range(1, 3):
-            tgen.add_router('r{}'.format(routern))
+            tgen.add_router("r{}".format(routern))
 
         # Create a empty network for router 1
-        switch = tgen.add_switch('s1')
-        switch.add_link(tgen.gears['r1'])
+        switch = tgen.add_switch("s1")
+        switch.add_link(tgen.gears["r1"])
 
         # Create a empty network for router 2
-        switch = tgen.add_switch('s2')
-        switch.add_link(tgen.gears['r2'])
+        switch = tgen.add_switch("s2")
+        switch.add_link(tgen.gears["r2"])
 
         # Interconect router 1, 2
-        switch = tgen.add_switch('s3')
-        switch.add_link(tgen.gears['r1'])
-        switch.add_link(tgen.gears['r2'])
+        switch = tgen.add_switch("s3")
+        switch.add_link(tgen.gears["r1"])
+        switch.add_link(tgen.gears["r2"])
 
 
 def setup_module(mod):
@@ -78,12 +80,10 @@ def setup_module(mod):
     router_list = tgen.routers()
     for rname, router in router_list.items():
         router.load_config(
-            TopoRouter.RD_ZEBRA,
-            os.path.join(CWD, '{}/zebra.conf'.format(rname))
+            TopoRouter.RD_ZEBRA, os.path.join(CWD, "{}/zebra.conf".format(rname))
         )
         router.load_config(
-            TopoRouter.RD_OSPF,
-            os.path.join(CWD, '{}/ospfd.conf'.format(rname))
+            TopoRouter.RD_OSPF, os.path.join(CWD, "{}/ospfd.conf".format(rname))
         )
 
         # What is this?  OSPF Unnumbered depends on the rp_filter
@@ -93,18 +93,15 @@ def setup_module(mod):
         # the rp_filter.  Setting it to '0' allows the OS to pass
         # up the mcast packet not destined for the local routers
         # network.
-        topotest.set_sysctl(tgen.net['r1'],
-                            'net.ipv4.conf.r1-eth1.rp_filter', 0)
-        topotest.set_sysctl(tgen.net['r1'],
-                            'net.ipv4.conf.all.rp_filter', 0)
-        topotest.set_sysctl(tgen.net['r2'],
-                            'net.ipv4.conf.r2-eth1.rp_filter', 0)
-        topotest.set_sysctl(tgen.net['r2'],
-                            'net.ipv4.conf.all.rp_filter', 0)
+        topotest.set_sysctl(tgen.net["r1"], "net.ipv4.conf.r1-eth1.rp_filter", 0)
+        topotest.set_sysctl(tgen.net["r1"], "net.ipv4.conf.all.rp_filter", 0)
+        topotest.set_sysctl(tgen.net["r2"], "net.ipv4.conf.r2-eth1.rp_filter", 0)
+        topotest.set_sysctl(tgen.net["r2"], "net.ipv4.conf.all.rp_filter", 0)
 
     # Initialize all routers.
     tgen.start_router()
-    #tgen.mininet_cli()
+    # tgen.mininet_cli()
+
 
 def teardown_module(mod):
     "Teardown the pytest environment"
@@ -116,50 +113,54 @@ def test_ospf_convergence():
     "Test OSPF daemon convergence and that we have received the ospf routes"
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
     for router, rnode in tgen.routers().items():
         logger.info('Waiting for router "%s" convergence', router)
 
-        json_file = '{}/{}/ospf-route.json'.format(CWD, router)
+        json_file = "{}/{}/ospf-route.json".format(CWD, router)
         expected = json.loads(open(json_file).read())
 
-        test_func = partial(topotest.router_json_cmp,
-                            rnode, 'show ip ospf route json', expected)
+        test_func = partial(
+            topotest.router_json_cmp, rnode, "show ip ospf route json", expected
+        )
         _, result = topotest.run_and_expect(test_func, None, count=160, wait=0.5)
         assertmsg = '"{}" JSON output mismatches'.format(router)
         assert result is None, assertmsg
-    #tgen.mininet_cli()
+    # tgen.mininet_cli()
+
 
 def test_ospf_kernel_route():
     "Test OSPF kernel route installation and we have the onlink success"
     tgen = get_topogen()
     if tgen.routers_have_failure():
-        pytest.skip('skipped because of router(s) failure')
+        pytest.skip("skipped because of router(s) failure")
 
     rlist = tgen.routers().values()
     for router in rlist:
         logger.info('Checking OSPF IPv4 kernel routes in "%s"', router.name)
 
-        json_file = '{}/{}/v4_route.json'.format(CWD, router.name)
+        json_file = "{}/{}/v4_route.json".format(CWD, router.name)
         expected = json.loads(open(json_file).read())
 
-        test_func = partial(topotest.router_json_cmp,
-                            router, 'show ip route json', expected)
-        _, result = topotest.run_and_expect(test_func, None, count=10, wait=.5)
+        test_func = partial(
+            topotest.router_json_cmp, router, "show ip route json", expected
+        )
+        _, result = topotest.run_and_expect(test_func, None, count=10, wait=0.5)
         assertmsg = '"{}" JSON output mistmatches'.format(router)
         assert result is None, assertmsg
-    #tgen.mininet_cli()
+    # tgen.mininet_cli()
 
 
 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')
+        pytest.skip("Memory leak test/report is disabled")
 
     tgen.report_memory_leaks()
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     args = ["-s"] + sys.argv[1:]
     sys.exit(pytest.main(args))
index a2f9c03ab4e00dfa86e8d55751183d6e6b993ca5..e92baefabfd778d892390f22f887b2bd283285b4 100644 (file)
@@ -48,7 +48,7 @@ from lib.common_config import (
     reset_config_on_routers,
     step,
     shutdown_bringup_interface,
-    topo_daemons
+    topo_daemons,
 )
 from lib.topolog import logger
 from lib.topojson import build_topo_from_json, build_config_from_json
index 399fa02230f074fd69e7d27efcdbd8c8820dfb6f..3b37b8a92f51262c14738b5cd24f25f8ab3f7afe 100644 (file)
@@ -53,7 +53,7 @@ from lib.common_config import (
     create_route_maps,
     shutdown_bringup_interface,
     create_interfaces_cfg,
-    topo_daemons
+    topo_daemons,
 )
 from lib.topolog import logger
 
index 17a3676e2e17ceb18267be2419691d556cd0c429..967bc448790d3402df35d26a0ec885acd21cf538 100644 (file)
@@ -53,7 +53,7 @@ from lib.common_config import (
     shutdown_bringup_interface,
     stop_router,
     start_router,
-    topo_daemons
+    topo_daemons,
 )
 from lib.bgp import verify_bgp_convergence, create_router_bgp
 from lib.topolog import logger
index f2611042069b6080480adf13d6f871807a0c32f3..1357a86c81b85d54d1cc472c50d6b80fc4ee2c36 100644 (file)
@@ -55,7 +55,7 @@ from lib.common_config import (
     shutdown_bringup_interface,
     stop_router,
     start_router,
-    topo_daemons
+    topo_daemons,
 )
 from lib.bgp import verify_bgp_convergence, create_router_bgp
 from lib.topolog import logger
index ff4399f19ef25edb3581cf882fa9f5239d01704a..82a34d046cdd72f384f80ee8209426c62cd23492 100644 (file)
@@ -44,7 +44,7 @@ from lib.common_config import (
     create_route_maps,
     shutdown_bringup_interface,
     create_interfaces_cfg,
-    topo_daemons
+    topo_daemons,
 )
 from ipaddress import IPv4Address
 from lib.topogen import Topogen, get_topogen
index 6ebc74a01374864bb02232774b4f9eee992b9ef7..64edc1ebbf99f0b91b90830276938ab322dede7a 100644 (file)
@@ -52,7 +52,7 @@ from lib.common_config import (
     step,
     create_route_maps,
     verify_prefix_lists,
-    topo_daemons
+    topo_daemons,
 )
 from lib.topolog import logger
 from lib.topojson import build_topo_from_json, build_config_from_json
index 2c6bcf0162997e839e4d410e91cd0ec9ab962e8d..6ac0b515df9fc397f5dfd6fdb236070426b7fa14 100644 (file)
@@ -50,7 +50,7 @@ from lib.common_config import (
     create_static_routes,
     step,
     shutdown_bringup_interface,
-    topo_daemons
+    topo_daemons,
 )
 from lib.bgp import verify_bgp_convergence, create_router_bgp
 from lib.topolog import logger
@@ -278,8 +278,7 @@ def test_ospf_redistribution_tc5_p0(request):
 
     dut = "r1"
     for num in range(0, nretry):
-        result = verify_ospf_rib(
-            tgen, dut, input_dict, next_hop=nh, expected=False)
+        result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False)
         if result is not True:
             break
 
@@ -399,8 +398,7 @@ def test_ospf_redistribution_tc6_p0(request):
 
     dut = "r1"
     for num in range(0, nretry):
-        result = verify_ospf_rib(
-            tgen, dut, input_dict, next_hop=nh, expected=False)
+        result = verify_ospf_rib(tgen, dut, input_dict, next_hop=nh, expected=False)
         if result is not True:
             break
     assert result is not True, "Testcase {} : Failed \n Error: {}".format(
@@ -409,13 +407,7 @@ def test_ospf_redistribution_tc6_p0(request):
 
     protocol = "ospf"
     result = verify_rib(
-        tgen,
-        "ipv4",
-        dut,
-        input_dict,
-        protocol=protocol,
-        next_hop=nh,
-        expected=False,
+        tgen, "ipv4", dut, input_dict, protocol=protocol, next_hop=nh, expected=False,
     )
     assert result is not True, "Testcase {} : Failed \n Error: {}".format(
         tc_name, result
index 5a141224f1a4bebaf72af00338419352646be6b8..f563637b3c1ca046bae7a415d0195aa4ec1f0be2 100644 (file)
@@ -53,7 +53,7 @@ from lib.common_config import (
     create_route_maps,
     shutdown_bringup_interface,
     create_interfaces_cfg,
-    topo_daemons
+    topo_daemons,
 )
 from lib.topolog import logger
 from lib.topojson import build_topo_from_json, build_config_from_json
index 91979a8f04067e32c49e803a37dab88304266998..fcbe3c0adf67e883570a351a1386e336710238cc 100644 (file)
@@ -147,7 +147,9 @@ def test_pbr_data():
         expected = json.loads(open(intf_file).read())
 
         # Actual output from router
-        test_func = partial(topotest.router_json_cmp, router, "show pbr interface json", expected)
+        test_func = partial(
+            topotest.router_json_cmp, router, "show pbr interface json", expected
+        )
         _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
         assertmsg = '"show pbr interface" mismatches on {}'.format(router.name)
         if result is not None:
@@ -161,7 +163,9 @@ def test_pbr_data():
         expected = json.loads(open(map_file).read())
 
         # Actual output from router
-        test_func = partial(topotest.router_json_cmp, router, "show pbr map json", expected)
+        test_func = partial(
+            topotest.router_json_cmp, router, "show pbr map json", expected
+        )
         _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
         assertmsg = '"show pbr map" mismatches on {}'.format(router.name)
         if result is not None:
@@ -175,13 +179,16 @@ def test_pbr_data():
         expected = json.loads(open(nexthop_file).read())
 
         # Actual output from router
-        test_func = partial(topotest.router_json_cmp, router, "show pbr nexthop-groups json", expected)
+        test_func = partial(
+            topotest.router_json_cmp, router, "show pbr nexthop-groups json", expected
+        )
         _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
         assertmsg = '"show pbr nexthop-groups" mismatches on {}'.format(router.name)
         if result is not None:
             gather_pbr_data_on_error(router)
             assert result is None, assertmsg
 
+
 def test_pbr_flap():
     "Test PBR interface flapping"
 
@@ -212,7 +219,9 @@ def test_pbr_flap():
         expected = json.loads(open(intf_file).read())
 
         # Actual output from router
-        test_func = partial(topotest.router_json_cmp, router, "show pbr interface json", expected)
+        test_func = partial(
+            topotest.router_json_cmp, router, "show pbr interface json", expected
+        )
         _, result = topotest.run_and_expect(test_func, None, count=30, wait=1)
         assertmsg = '"show pbr interface" mismatches on {}'.format(router.name)
         if result is not None:
@@ -274,4 +283,3 @@ def gather_pbr_data_on_error(router):
     logger.info(router.run("ip route show table 10005"))
     logger.info(router.run("ip -6 route show table 10005"))
     logger.info(router.run("ip rule show"))
-
index 7aa4d4027ec418ee78a6edc123319f14e09af3e8..862ad46af4b38797d2a2581d87c026a35c311b6a 100755 (executable)
@@ -35,8 +35,9 @@ import time
 
 
 def ifname_to_ifindex(ifname):
-    output = subprocess.check_output("ip link show %s" % ifname,
-                                     shell=True, universal_newlines=True)
+    output = subprocess.check_output(
+        "ip link show %s" % ifname, shell=True, universal_newlines=True
+    )
     first_line = output.split("\n")[0]
     re_index = re.search("^(\d+):", first_line)
 
index 7fb980c6473f8324a9cb85a4c2f7251accc1ee1d..87038ad5cf99c1da18ac347d3af41e1ca9576aeb 100755 (executable)
@@ -39,9 +39,7 @@ logging.addLevelName(
 )
 log = logging.getLogger(__name__)
 
-parser = argparse.ArgumentParser(
-    description="Multicast packet generator"
-)
+parser = argparse.ArgumentParser(description="Multicast packet generator")
 parser.add_argument("group", help="Multicast IP")
 parser.add_argument("ifname", help="Interface name")
 parser.add_argument("--port", type=int, help="UDP port number", default=1000)
@@ -62,8 +60,9 @@ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 #
 if sys.version_info[0] > 2:
     sock.setsockopt(
-        socket.SOL_SOCKET, 25, struct.pack("%ds" % len(args.ifname),
-                                           args.ifname.encode('utf-8'))
+        socket.SOL_SOCKET,
+        25,
+        struct.pack("%ds" % len(args.ifname), args.ifname.encode("utf-8")),
     )
 else:
     sock.setsockopt(
index 2e9c4901bc4e7ae1e81de95750d23912576cd5e8..6e8e74909230ce23366ba2253fc51e02f577a95c 100644 (file)
@@ -1,6 +1,6 @@
 # Skip pytests example directory
 [pytest]
-norecursedirs = .git example-test example-topojson-test lib docker evpn_type5_test_topo1
+norecursedirs = .git example-test example-topojson-test lib docker
 
 [topogen]
 # Default configuration values
index 0bfae3b8303a897cd7389da5ad2560d57ae7369e..8aedfc198cdda3c0ee72bc28d1ecc02d8613edc6 100644 (file)
@@ -95,7 +95,8 @@ def setup_module(module):
         )
 
     tgen.start_router()
-    #tgen.mininet_cli()
+    # tgen.mininet_cli()
+
 
 def teardown_module(_mod):
     "Teardown the pytest environment"
@@ -104,6 +105,7 @@ def teardown_module(_mod):
     # This function tears down the whole topology.
     tgen.stop_topology()
 
+
 def test_converge_protocols():
     "Wait for protocol convergence"
 
@@ -112,37 +114,45 @@ def test_converge_protocols():
     if tgen.routers_have_failure():
         pytest.skip(tgen.errors)
 
+
 def run_one_setup(r1, s):
     "Run one ecmp config"
 
     # Extract params
-    expected_installed = s['expect_in']
-    expected_removed = s['expect_rem']
+    expected_installed = s["expect_in"]
+    expected_removed = s["expect_rem"]
 
-    count = s['count']
-    wait = s['wait']
+    count = s["count"]
+    wait = s["wait"]
 
-    logger.info("Testing 1 million routes X {} ecmp".format(s['ecmp']))
+    logger.info("Testing 1 million routes X {} ecmp".format(s["ecmp"]))
 
-    r1.vtysh_cmd("sharp install route 1.0.0.0 \
-                  nexthop-group {} 1000000".format(s['nhg']),
-                 isjson=False)
+    r1.vtysh_cmd(
+        "sharp install route 1.0.0.0 \
+                  nexthop-group {} 1000000".format(
+            s["nhg"]
+        ),
+        isjson=False,
+    )
 
-    test_func = partial(topotest.router_json_cmp, r1, "show ip route summary json", expected_installed)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route summary json", expected_installed
+    )
     success, result = topotest.run_and_expect(test_func, None, count, wait)
     assert success, "Route scale test install failed:\n{}".format(result)
 
     output = r1.vtysh_cmd("sharp data route", isjson=False)
-    logger.info("1 million routes X {} ecmp installed".format(s['ecmp']))
+    logger.info("1 million routes X {} ecmp installed".format(s["ecmp"]))
     logger.info(output)
     r1.vtysh_cmd("sharp remove route 1.0.0.0 1000000", isjson=False)
-    test_func = partial(topotest.router_json_cmp, r1, "show ip route summary json", expected_removed)
+    test_func = partial(
+        topotest.router_json_cmp, r1, "show ip route summary json", expected_removed
+    )
     success, result = topotest.run_and_expect(test_func, None, count, wait)
     assert success, "Route scale test remove failed:\n{}".format(result)
 
     output = r1.vtysh_cmd("sharp data route", isjson=False)
-    logger.info("1 million routes x {} ecmp removed".format(
-        s['ecmp']))
+    logger.info("1 million routes x {} ecmp removed".format(s["ecmp"]))
     logger.info(output)
 
 
@@ -164,19 +174,23 @@ def test_route_install():
 
     # dict keys of params: ecmp number, corresponding nhg name, timeout,
     # number of times to wait
-    scale_keys = ['ecmp', 'nhg', 'wait', 'count', 'expect_in', 'expect_rem']
+    scale_keys = ["ecmp", "nhg", "wait", "count", "expect_in", "expect_rem"]
 
     # Table of defaults, used for timeout values and 'expected' objects
-    scale_defaults = dict(zip(scale_keys, [None, None, 7, 30,
-                                           expected_installed,
-                                           expected_removed]))
+    scale_defaults = dict(
+        zip(scale_keys, [None, None, 7, 30, expected_installed, expected_removed])
+    )
 
     # List of params for each step in the test; note extra time given
     # for the highest ecmp steps. Executing 'show' at scale can be costly
     # so we widen the interval there too.
     scale_steps = [
-        [1, 'one'], [2, 'two'], [4, 'four'],
-        [8, 'eight'], [16, 'sixteen', 10, 40], [32, 'thirtytwo', 10, 40]
+        [1, "one"],
+        [2, "two"],
+        [4, "four"],
+        [8, "eight"],
+        [16, "sixteen", 10, 40],
+        [32, "thirtytwo", 10, 40],
     ]
 
     # Build up a list of dicts with params for each step of the test;
@@ -191,17 +205,18 @@ def test_route_install():
         scale_setups.append(d)
 
     # Avoid top ecmp case for runs with < 4G memory
-    p = os.popen('free')
+    p = os.popen("free")
     l = p.readlines()[1].split()
     mem = int(l[1])
     if mem < 4000000:
-        logger.info('Limited memory available: {}, skipping x32 testcase'.format(mem))
+        logger.info("Limited memory available: {}, skipping x32 testcase".format(mem))
         scale_setups = scale_setups[0:-1]
 
     # Run each step using the dicts we've built
     for s in scale_setups:
         run_one_setup(r1, s)
 
+
 # Mem leak testcase
 def test_memory_leak():
     "Run the memory leak test and report results."
@@ -210,6 +225,7 @@ def test_memory_leak():
         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))
diff --git a/tools/coccinelle/README.md b/tools/coccinelle/README.md
new file mode 100644 (file)
index 0000000..262ccc1
--- /dev/null
@@ -0,0 +1,14 @@
+Coccinelle patches
+==================
+
+This collection of coccinelle patches represents some of the broader,
+codebase-wide changes that have been made. If you maintain a fork of
+FRR and find that your codebase needs to be updated to align with
+these changes, the coccinelle tool should help you make that update.
+
+The coccinelle tool is documented at:
+    https://coccinelle.gitlabpages.inria.fr/website/
+
+To run a coccinelle patch script:
+
+    spatch --sp-file tools/coccinelle/semicolon.cocci zebra/*.c
diff --git a/tools/coccinelle/thread_cancel_api.cocci b/tools/coccinelle/thread_cancel_api.cocci
new file mode 100644 (file)
index 0000000..cc34f93
--- /dev/null
@@ -0,0 +1,68 @@
+@ptrupdate@
+expression E;
+@@
+- thread_cancel(E);
++ thread_cancel(&E);
+
+@nullcheckremove depends on ptrupdate@
+expression E;
+@@
+
+thread_cancel(&E);
+- E = NULL;
+
+@cancelguardremove depends on nullcheckremove@
+expression E;
+@@
+- if (E)
+- {
+   thread_cancel(&E);
+- }
+
+@cancelguardremove2 depends on nullcheckremove@
+expression E;
+@@
+- if (E != NULL)
+- {
+   thread_cancel(&E);
+- }
+
+@cancelguardremove3 depends on nullcheckremove@
+expression E;
+@@
+- if (E)
+   thread_cancel(&E);
+
+@cancelguardremove4 depends on nullcheckremove@
+expression E;
+@@
+- if (E != NULL)
+   thread_cancel(&E);
+
+@replacetimeroff@
+expression E;
+@@
+
+- THREAD_TIMER_OFF(E);
++ thread_cancel(&E);
+
+@replacewriteoff@
+expression E;
+@@
+
+- THREAD_WRITE_OFF(E);
++ thread_cancel(&E);
+
+@replacereadoff@
+expression E;
+@@
+
+- THREAD_READ_OFF(E);
++ thread_cancel(&E);
+
+@replacethreadoff@
+expression E;
+@@
+
+- THREAD_OFF(E);
++ thread_cancel(&E);
\ No newline at end of file
index 0221b0c19ec8b01e7cb29640194f5fd762b48e45..f6d512be72f383698fd51544f5f4b74d574aba29 100644 (file)
@@ -12,7 +12,7 @@
 # When using "vtysh" such a config file is also needed. It should be owned by
 # group "frrvty" and set to ug=rw,o= though. Check /etc/pam.d/frr, too.
 #
-# The watchfrr and zebra daemons are always started.
+# The watchfrr, zebra and staticd daemons are always started.
 #
 bgpd=no
 ospfd=no
index 38958480a89f130e22e4f3a84287a0df112f9d84..57f9df90658f15e3180fd9db238a60bd4cc04f7a 100755 (executable)
@@ -8,48 +8,74 @@
 
 import sys, re, subprocess, os
 
+
 class replaceEntry:
-    compiled = None    #compiled regex
-    repl    = None     #regex
+    compiled = None  # compiled regex
+    repl = None  # regex
+
     def __init__(self, c, r):
         self.compiled = c
         self.repl = r
 
+
 rList = [
     # old #define VNL, VTYNL, VTY_NEWLINE
-    replaceEntry(re.compile(r'(VNL|VTYNL|VTY_NEWLINE)'),
-                 r'"\\n"'),
+    replaceEntry(re.compile(r"(VNL|VTYNL|VTY_NEWLINE)"), r'"\\n"'),
     # old #define VTY_GET_INTEGER(desc, v, str)
     # old #define VTY_GET_INTEGER_RANGE(desc, v, str, min, max)
     # old #define VTY_GET_ULONG(desc, v, str)
-    replaceEntry(re.compile(r'(VTY_GET_INTEGER(_RANGE|)|VTY_GET_ULONG)[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S),
-                 r'(\4) = strtoul((\5), NULL, 10);\t/* \3 */'),
+    replaceEntry(
+        re.compile(
+            r"(VTY_GET_INTEGER(_RANGE|)|VTY_GET_ULONG)[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;",
+            re.M | re.S,
+        ),
+        r"(\4) = strtoul((\5), NULL, 10);\t/* \3 */",
+    ),
     # old #define VTY_GET_ULL(desc, v, str)
-    replaceEntry(re.compile(r'VTY_GET_ULL[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S),
-                 r'(\2) = strtoull((\3), NULL, 10);\t/* \1 */'),
+    replaceEntry(
+        re.compile(
+            r"VTY_GET_ULL[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;",
+            re.M | re.S,
+        ),
+        r"(\2) = strtoull((\3), NULL, 10);\t/* \1 */",
+    ),
     # old #define VTY_GET_IPV4_ADDRESS(desc, v, str)
-    replaceEntry(re.compile(r'VTY_GET_IPV4_ADDRESS[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S),
-                 r'inet_aton((\3), &(\2));\t/* \1 */'),
+    replaceEntry(
+        re.compile(
+            r"VTY_GET_IPV4_ADDRESS[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;",
+            re.M | re.S,
+        ),
+        r"inet_aton((\3), &(\2));\t/* \1 */",
+    ),
     # old #define VTY_GET_IPV4_PREFIX(desc, v, str)
-    replaceEntry(re.compile(r'VTY_GET_IPV4_PREFIX[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;', re.M | re.S),
-                 r'str2prefix_ipv4((\3), &(\2));\t/* \1 */'),
+    replaceEntry(
+        re.compile(
+            r"VTY_GET_IPV4_PREFIX[\s\(]*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)(\s*|)(\)|,).*?;",
+            re.M | re.S,
+        ),
+        r"str2prefix_ipv4((\3), &(\2));\t/* \1 */",
+    ),
     # old #define vty_outln(vty, str, ...)
-    replaceEntry(re.compile(r'vty_outln[\s\(]*(.*?)\s*,\s*(".*?"|.*?)\s*(\)|,)', re.M | re.S),
-                 r'vty_out(\1, \2 "\\n"\3'),
-        ]
+    replaceEntry(
+        re.compile(r'vty_outln[\s\(]*(.*?)\s*,\s*(".*?"|.*?)\s*(\)|,)', re.M | re.S),
+        r'vty_out(\1, \2 "\\n"\3',
+    ),
+]
+
 
 def fixup_file(fn):
-    with open(fn, 'r') as fd:
+    with open(fn, "r") as fd:
         text = fd.read()
 
         for re in rList:
-            text = re.compiled.sub(re.repl,text)
+            text = re.compiled.sub(re.repl, text)
 
-        tmpname = fn + '.fixup'
-        with open(tmpname, 'w') as ofd:
+        tmpname = fn + ".fixup"
+        with open(tmpname, "w") as ofd:
             ofd.write(text)
         os.rename(tmpname, fn)
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     for fn in sys.argv[1:]:
         fixup_file(fn)
index 88873da904599cfee227582b9145ccaca1c47f04..951383beb260f68c4d9baa5b11bc22808ecb47c4 100755 (executable)
@@ -39,6 +39,7 @@ import string
 import subprocess
 import sys
 from collections import OrderedDict
+
 try:
     from ipaddress import IPv6Address, ip_network
 except ImportError:
@@ -51,45 +52,49 @@ except AttributeError:
     # Python 3
     def iteritems(d):
         return iter(d.items())
+
+
 else:
     # Python 2
     def iteritems(d):
         return d.iteritems()
 
+
 log = logging.getLogger(__name__)
 
 
 class VtyshException(Exception):
     pass
 
+
 class Vtysh(object):
     def __init__(self, bindir=None, confdir=None, sockdir=None, pathspace=None):
         self.bindir = bindir
         self.confdir = confdir
         self.pathspace = pathspace
-        self.common_args = [os.path.join(bindir or '', 'vtysh')]
+        self.common_args = [os.path.join(bindir or "", "vtysh")]
         if confdir:
-            self.common_args.extend(['--config_dir', confdir])
+            self.common_args.extend(["--config_dir", confdir])
         if sockdir:
-            self.common_args.extend(['--vty_socket', sockdir])
+            self.common_args.extend(["--vty_socket", sockdir])
         if pathspace:
-            self.common_args.extend(['-N', pathspace])
+            self.common_args.extend(["-N", pathspace])
 
     def _call(self, args, stdin=None, stdout=None, stderr=None):
         kwargs = {}
         if stdin is not None:
-            kwargs['stdin'] = stdin
+            kwargs["stdin"] = stdin
         if stdout is not None:
-            kwargs['stdout'] = stdout
+            kwargs["stdout"] = stdout
         if stderr is not None:
-            kwargs['stderr'] = stderr
+            kwargs["stderr"] = stderr
         return subprocess.Popen(self.common_args + args, **kwargs)
 
     def _call_cmd(self, command, stdin=None, stdout=None, stderr=None):
         if isinstance(command, list):
-            args = [item for sub in command for item in ['-c', sub]]
+            args = [item for sub in command for item in ["-c", sub]]
         else:
-            args = ['-c', command]
+            args = ["-c", command]
         return self._call(args, stdin, stdout, stderr)
 
     def __call__(self, command):
@@ -102,9 +107,10 @@ class Vtysh(object):
         proc = self._call_cmd(command, stdout=subprocess.PIPE)
         stdout, stderr = proc.communicate()
         if proc.wait() != 0:
-            raise VtyshException('vtysh returned status %d for command "%s"'
-                    % (proc.returncode, command))
-        return stdout.decode('UTF-8')
+            raise VtyshException(
+                'vtysh returned status %d for command "%s"' % (proc.returncode, command)
+            )
+        return stdout.decode("UTF-8")
 
     def is_config_available(self):
         """
@@ -113,56 +119,69 @@ class Vtysh(object):
         configuration changes.
         """
 
-        output = self('configure')
+        output = self("configure")
 
-        if 'VTY configuration is locked by other VTY' in output:
+        if "VTY configuration is locked by other VTY" in output:
             log.error("vtysh 'configure' returned\n%s\n" % (output))
             return False
 
         return True
 
     def exec_file(self, filename):
-        child = self._call(['-f', filename])
+        child = self._call(["-f", filename])
         if child.wait() != 0:
-            raise VtyshException('vtysh (exec file) exited with status %d'
-                    % (child.returncode))
+            raise VtyshException(
+                "vtysh (exec file) exited with status %d" % (child.returncode)
+            )
 
     def mark_file(self, filename, stdin=None):
-        child = self._call(['-m', '-f', filename],
-                stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE)
+        child = self._call(
+            ["-m", "-f", filename],
+            stdout=subprocess.PIPE,
+            stdin=subprocess.PIPE,
+            stderr=subprocess.PIPE,
+        )
         try:
             stdout, stderr = child.communicate()
         except subprocess.TimeoutExpired:
             child.kill()
             stdout, stderr = child.communicate()
-            raise VtyshException('vtysh call timed out!')
+            raise VtyshException("vtysh call timed out!")
 
         if child.wait() != 0:
-            raise VtyshException('vtysh (mark file) exited with status %d:\n%s'
-                    % (child.returncode, stderr))
+            raise VtyshException(
+                "vtysh (mark file) exited with status %d:\n%s"
+                % (child.returncode, stderr)
+            )
 
-        return stdout.decode('UTF-8')
+        return stdout.decode("UTF-8")
 
-    def mark_show_run(self, daemon = None):
-        cmd = 'show running-config'
+    def mark_show_run(self, daemon=None):
+        cmd = "show running-config"
         if daemon:
-            cmd += ' %s' % daemon
-        cmd += ' no-header'
+            cmd += " %s" % daemon
+        cmd += " no-header"
         show_run = self._call_cmd(cmd, stdout=subprocess.PIPE)
-        mark = self._call(['-m', '-f', '-'], stdin=show_run.stdout, stdout=subprocess.PIPE)
+        mark = self._call(
+            ["-m", "-f", "-"], stdin=show_run.stdout, stdout=subprocess.PIPE
+        )
 
         show_run.wait()
         stdout, stderr = mark.communicate()
         mark.wait()
 
         if show_run.returncode != 0:
-            raise VtyshException('vtysh (show running-config) exited with status %d:'
-                    % (show_run.returncode))
+            raise VtyshException(
+                "vtysh (show running-config) exited with status %d:"
+                % (show_run.returncode)
+            )
         if mark.returncode != 0:
-            raise VtyshException('vtysh (mark running-config) exited with status %d'
-                    % (mark.returncode))
+            raise VtyshException(
+                "vtysh (mark running-config) exited with status %d" % (mark.returncode)
+            )
+
+        return stdout.decode("UTF-8")
 
-        return stdout.decode('UTF-8')
 
 class Context(object):
 
@@ -222,15 +241,15 @@ class Config(object):
         The internal representation has been marked appropriately by passing it
         through vtysh with the -m parameter
         """
-        log.info('Loading Config object from file %s', filename)
+        log.info("Loading Config object from file %s", filename)
 
         file_output = self.vtysh.mark_file(filename)
 
-        for line in file_output.split('\n'):
+        for line in file_output.split("\n"):
             line = line.strip()
 
             # Compress duplicate whitespaces
-            line = ' '.join(line.split())
+            line = " ".join(line.split())
 
             if ":" in line and not "ipv6 add":
                 qv6_line = get_normalized_ipv6_line(line)
@@ -246,16 +265,18 @@ class Config(object):
         The internal representation has been marked appropriately by passing it
         through vtysh with the -m parameter
         """
-        log.info('Loading Config object from vtysh show running')
+        log.info("Loading Config object from vtysh show running")
 
         config_text = self.vtysh.mark_show_run(daemon)
 
-        for line in config_text.split('\n'):
+        for line in config_text.split("\n"):
             line = line.strip()
 
-            if (line == 'Building configuration...' or
-                line == 'Current configuration:' or
-                    not line):
+            if (
+                line == "Building configuration..."
+                or line == "Current configuration:"
+                or not line
+            ):
                 continue
 
             self.lines.append(line)
@@ -267,7 +288,7 @@ class Config(object):
         Return the lines read in from the configuration
         """
 
-        return '\n'.join(self.lines)
+        return "\n".join(self.lines)
 
     def get_contexts(self):
         """
@@ -275,7 +296,7 @@ class Config(object):
         """
 
         for (_, ctx) in sorted(iteritems(self.contexts)):
-            print(str(ctx) + '\n')
+            print(str(ctx) + "\n")
 
     def save_contexts(self, key, lines):
         """
@@ -285,99 +306,116 @@ class Config(object):
         if not key:
             return
 
-        '''
+        """
             IP addresses specified in "network" statements, "ip prefix-lists"
             etc. can differ in the host part of the specification the user
             provides and what the running config displays. For example, user
             can specify 11.1.1.1/24, and the running config displays this as
             11.1.1.0/24. Ensure we don't do a needless operation for such
             lines. IS-IS & OSPFv3 have no "network" support.
-        '''
-        re_key_rt = re.match(r'(ip|ipv6)\s+route\s+([A-Fa-f:.0-9/]+)(.*)$', key[0])
+        """
+        re_key_rt = re.match(r"(ip|ipv6)\s+route\s+([A-Fa-f:.0-9/]+)(.*)$", key[0])
         if re_key_rt:
             addr = re_key_rt.group(2)
-            if '/' in addr:
+            if "/" in addr:
                 try:
-                    if 'ipaddress' not in sys.modules:
+                    if "ipaddress" not in sys.modules:
                         newaddr = IPNetwork(addr)
-                        key[0] = '%s route %s/%s%s' % (re_key_rt.group(1),
-                                                       newaddr.network,
-                                                       newaddr.prefixlen,
-                                                       re_key_rt.group(3))
+                        key[0] = "%s route %s/%s%s" % (
+                            re_key_rt.group(1),
+                            newaddr.network,
+                            newaddr.prefixlen,
+                            re_key_rt.group(3),
+                        )
                     else:
                         newaddr = ip_network(addr, strict=False)
-                        key[0] = '%s route %s/%s%s' % (re_key_rt.group(1),
-                                                       str(newaddr.network_address),
-                                                       newaddr.prefixlen,
-                                                       re_key_rt.group(3))
+                        key[0] = "%s route %s/%s%s" % (
+                            re_key_rt.group(1),
+                            str(newaddr.network_address),
+                            newaddr.prefixlen,
+                            re_key_rt.group(3),
+                        )
                 except ValueError:
                     pass
 
         re_key_rt = re.match(
-            r'(ip|ipv6)\s+prefix-list(.*)(permit|deny)\s+([A-Fa-f:.0-9/]+)(.*)$',
-            key[0]
+            r"(ip|ipv6)\s+prefix-list(.*)(permit|deny)\s+([A-Fa-f:.0-9/]+)(.*)$", key[0]
         )
         if re_key_rt:
             addr = re_key_rt.group(4)
-            if '/' in addr:
+            if "/" in addr:
                 try:
-                    if 'ipaddress' not in sys.modules:
-                        newaddr = '%s/%s' % (IPNetwork(addr).network,
-                                             IPNetwork(addr).prefixlen)
+                    if "ipaddress" not in sys.modules:
+                        newaddr = "%s/%s" % (
+                            IPNetwork(addr).network,
+                            IPNetwork(addr).prefixlen,
+                        )
                     else:
                         network_addr = ip_network(addr, strict=False)
-                        newaddr = '%s/%s' % (str(network_addr.network_address),
-                                             network_addr.prefixlen)
+                        newaddr = "%s/%s" % (
+                            str(network_addr.network_address),
+                            network_addr.prefixlen,
+                        )
                 except ValueError:
                     newaddr = addr
             else:
                 newaddr = addr
 
             legestr = re_key_rt.group(5)
-            re_lege = re.search(r'(.*)le\s+(\d+)\s+ge\s+(\d+)(.*)', legestr)
+            re_lege = re.search(r"(.*)le\s+(\d+)\s+ge\s+(\d+)(.*)", legestr)
             if re_lege:
-                legestr = '%sge %s le %s%s' % (re_lege.group(1),
-                                               re_lege.group(3),
-                                               re_lege.group(2),
-                                               re_lege.group(4))
-            re_lege = re.search(r'(.*)ge\s+(\d+)\s+le\s+(\d+)(.*)', legestr)
-
-            if (re_lege and ((re_key_rt.group(1) == "ip" and
-                              re_lege.group(3) == "32") or
-                             (re_key_rt.group(1) == "ipv6" and
-                              re_lege.group(3) == "128"))):
-                legestr = '%sge %s%s' % (re_lege.group(1),
-                                         re_lege.group(2),
-                                         re_lege.group(4))
-
-            key[0] = '%s prefix-list%s%s %s%s' % (re_key_rt.group(1),
-                                                  re_key_rt.group(2),
-                                                  re_key_rt.group(3),
-                                                  newaddr,
-                                                  legestr)
-
-        if lines and key[0].startswith('router bgp'):
+                legestr = "%sge %s le %s%s" % (
+                    re_lege.group(1),
+                    re_lege.group(3),
+                    re_lege.group(2),
+                    re_lege.group(4),
+                )
+            re_lege = re.search(r"(.*)ge\s+(\d+)\s+le\s+(\d+)(.*)", legestr)
+
+            if re_lege and (
+                (re_key_rt.group(1) == "ip" and re_lege.group(3) == "32")
+                or (re_key_rt.group(1) == "ipv6" and re_lege.group(3) == "128")
+            ):
+                legestr = "%sge %s%s" % (
+                    re_lege.group(1),
+                    re_lege.group(2),
+                    re_lege.group(4),
+                )
+
+            key[0] = "%s prefix-list%s%s %s%s" % (
+                re_key_rt.group(1),
+                re_key_rt.group(2),
+                re_key_rt.group(3),
+                newaddr,
+                legestr,
+            )
+
+        if lines and key[0].startswith("router bgp"):
             newlines = []
             for line in lines:
-                re_net = re.match(r'network\s+([A-Fa-f:.0-9/]+)(.*)$', line)
+                re_net = re.match(r"network\s+([A-Fa-f:.0-9/]+)(.*)$", line)
                 if re_net:
                     addr = re_net.group(1)
-                    if '/' not in addr and key[0].startswith('router bgp'):
+                    if "/" not in addr and key[0].startswith("router bgp"):
                         # This is most likely an error because with no
                         # prefixlen, BGP treats the prefixlen as 8
-                        addr = addr + '/8'
+                        addr = addr + "/8"
 
                     try:
-                        if 'ipaddress' not in sys.modules:
+                        if "ipaddress" not in sys.modules:
                             newaddr = IPNetwork(addr)
-                            line = 'network %s/%s %s' % (newaddr.network,
-                                                         newaddr.prefixlen,
-                                                         re_net.group(2))
+                            line = "network %s/%s %s" % (
+                                newaddr.network,
+                                newaddr.prefixlen,
+                                re_net.group(2),
+                            )
                         else:
                             network_addr = ip_network(addr, strict=False)
-                            line = 'network %s/%s %s' % (str(network_addr.network_address),
-                                                         network_addr.prefixlen,
-                                                         re_net.group(2))
+                            line = "network %s/%s %s" % (
+                                str(network_addr.network_address),
+                                network_addr.prefixlen,
+                                re_net.group(2),
+                            )
                         newlines.append(line)
                     except ValueError:
                         # Really this should be an error. Whats a network
@@ -387,13 +425,16 @@ class Config(object):
                     newlines.append(line)
             lines = newlines
 
-        '''
+        """
           More fixups in user specification and what running config shows.
           "null0" in routes must be replaced by Null0.
-        '''
-        if (key[0].startswith('ip route') or key[0].startswith('ipv6 route') and
-                'null0' in key[0]):
-            key[0] = re.sub(r'\s+null0(\s*$)', ' Null0', key[0])
+        """
+        if (
+            key[0].startswith("ip route")
+            or key[0].startswith("ipv6 route")
+            and "null0" in key[0]
+        ):
+            key[0] = re.sub(r"\s+null0(\s*$)", " Null0", key[0])
 
         if lines:
             if tuple(key) not in self.contexts:
@@ -416,7 +457,7 @@ class Config(object):
         current_context_lines = []
         ctx_keys = []
 
-        '''
+        """
         The end of a context is flagged via the 'end' keyword:
 
 !
@@ -460,7 +501,7 @@ router ospf
  timers throttle spf 0 50 5000
 !
 end
-        '''
+        """
 
         # The code assumes that its working on the output from the "vtysh -m"
         # command. That provides the appropriate markers to signify end of
@@ -480,38 +521,40 @@ end
 
         # the keywords that we know are single line contexts. bgp in this case
         # is not the main router bgp block, but enabling multi-instance
-        oneline_ctx_keywords = ("access-list ",
-                                "agentx",
-                                "allow-external-route-update",
-                                "bgp ",
-                                "debug ",
-                                "domainname ",
-                                "dump ",
-                                "enable ",
-                                "frr ",
-                                "hostname ",
-                                "ip ",
-                                "ipv6 ",
-                                "log ",
-                                "mpls lsp",
-                                "mpls label",
-                                "no ",
-                                "password ",
-                                "ptm-enable",
-                                "router-id ",
-                                "service ",
-                                "table ",
-                                "username ",
-                                "zebra ",
-                                "vrrp autoconfigure",
-                                "evpn mh")
+        oneline_ctx_keywords = (
+            "access-list ",
+            "agentx",
+            "allow-external-route-update",
+            "bgp ",
+            "debug ",
+            "domainname ",
+            "dump ",
+            "enable ",
+            "frr ",
+            "hostname ",
+            "ip ",
+            "ipv6 ",
+            "log ",
+            "mpls lsp",
+            "mpls label",
+            "no ",
+            "password ",
+            "ptm-enable",
+            "router-id ",
+            "service ",
+            "table ",
+            "username ",
+            "zebra ",
+            "vrrp autoconfigure",
+            "evpn mh",
+        )
 
         for line in self.lines:
 
             if not line:
                 continue
 
-            if line.startswith('!') or line.startswith('#'):
+            if line.startswith("!") or line.startswith("#"):
                 continue
 
             # one line contexts
@@ -519,22 +562,31 @@ end
             # as part of its 'mpls ldp' config context. If we are processing
             # ldp configuration and encounter a router-id we should NOT switch
             # to a new context
-            if new_ctx is True and any(line.startswith(keyword) for keyword in oneline_ctx_keywords) and not (
-                ctx_keys and ctx_keys[0].startswith("mpls ldp") and line.startswith("router-id ")):
+            if (
+                new_ctx is True
+                and any(line.startswith(keyword) for keyword in oneline_ctx_keywords)
+                and not (
+                    ctx_keys
+                    and ctx_keys[0].startswith("mpls ldp")
+                    and line.startswith("router-id ")
+                )
+            ):
                 self.save_contexts(ctx_keys, current_context_lines)
 
                 # Start a new context
                 main_ctx_key = []
-                ctx_keys = [line, ]
+                ctx_keys = [
+                    line,
+                ]
                 current_context_lines = []
 
-                log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys)
+                log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys)
                 self.save_contexts(ctx_keys, current_context_lines)
                 new_ctx = True
 
             elif line == "end":
                 self.save_contexts(ctx_keys, current_context_lines)
-                log.debug('LINE %-50s: exiting old context, %-50s', line, ctx_keys)
+                log.debug("LINE %-50s: exiting old context, %-50s", line, ctx_keys)
 
                 # Start a new context
                 new_ctx = True
@@ -545,9 +597,11 @@ end
             elif line == "exit-vrf":
                 self.save_contexts(ctx_keys, current_context_lines)
                 current_context_lines.append(line)
-                log.debug('LINE %-50s: append to current_context_lines, %-50s', line, ctx_keys)
+                log.debug(
+                    "LINE %-50s: append to current_context_lines, %-50s", line, ctx_keys
+                )
 
-                #Start a new context
+                # Start a new context
                 new_ctx = True
                 main_ctx_key = []
                 ctx_keys = []
@@ -561,7 +615,11 @@ end
                     # Start a new context
                     ctx_keys = copy.deepcopy(main_ctx_key)
                     current_context_lines = []
-                    log.debug('LINE %-50s: popping from subcontext to ctx%-50s', line, ctx_keys)
+                    log.debug(
+                        "LINE %-50s: popping from subcontext to ctx%-50s",
+                        line,
+                        ctx_keys,
+                    )
 
             elif line in ["exit-vni", "exit-ldp-if"]:
                 if sub_main_ctx_key:
@@ -570,70 +628,92 @@ end
                     # Start a new context
                     ctx_keys = copy.deepcopy(sub_main_ctx_key)
                     current_context_lines = []
-                    log.debug('LINE %-50s: popping from sub-subcontext to ctx%-50s', line, ctx_keys)
+                    log.debug(
+                        "LINE %-50s: popping from sub-subcontext to ctx%-50s",
+                        line,
+                        ctx_keys,
+                    )
 
             elif new_ctx is True:
                 if not main_ctx_key:
-                    ctx_keys = [line, ]
+                    ctx_keys = [
+                        line,
+                    ]
                 else:
                     ctx_keys = copy.deepcopy(main_ctx_key)
                     main_ctx_key = []
 
                 current_context_lines = []
                 new_ctx = False
-                log.debug('LINE %-50s: entering new context, %-50s', line, ctx_keys)
-            elif (line.startswith("address-family ") or
-                  line.startswith("vnc defaults") or
-                  line.startswith("vnc l2-group") or
-                  line.startswith("vnc nve-group") or
-                  line.startswith("peer") or
-                  line.startswith("key ") or
-                  line.startswith("member pseudowire")):
+                log.debug("LINE %-50s: entering new context, %-50s", line, ctx_keys)
+            elif (
+                line.startswith("address-family ")
+                or line.startswith("vnc defaults")
+                or line.startswith("vnc l2-group")
+                or line.startswith("vnc nve-group")
+                or line.startswith("peer")
+                or line.startswith("key ")
+                or line.startswith("member pseudowire")
+            ):
                 main_ctx_key = []
 
                 # Save old context first
                 self.save_contexts(ctx_keys, current_context_lines)
                 current_context_lines = []
                 main_ctx_key = copy.deepcopy(ctx_keys)
-                log.debug('LINE %-50s: entering sub-context, append to ctx_keys', line)
+                log.debug("LINE %-50s: entering sub-context, append to ctx_keys", line)
 
-                if line == "address-family ipv6" and not ctx_keys[0].startswith("mpls ldp"):
+                if line == "address-family ipv6" and not ctx_keys[0].startswith(
+                    "mpls ldp"
+                ):
                     ctx_keys.append("address-family ipv6 unicast")
-                elif line == "address-family ipv4" and not ctx_keys[0].startswith("mpls ldp"):
+                elif line == "address-family ipv4" and not ctx_keys[0].startswith(
+                    "mpls ldp"
+                ):
                     ctx_keys.append("address-family ipv4 unicast")
                 elif line == "address-family evpn":
                     ctx_keys.append("address-family l2vpn evpn")
                 else:
                     ctx_keys.append(line)
 
-            elif ((line.startswith("vni ") and
-                   len(ctx_keys) == 2 and
-                   ctx_keys[0].startswith('router bgp') and
-                   ctx_keys[1] == 'address-family l2vpn evpn')):
+            elif (
+                line.startswith("vni ")
+                and len(ctx_keys) == 2
+                and ctx_keys[0].startswith("router bgp")
+                and ctx_keys[1] == "address-family l2vpn evpn"
+            ):
 
                 # Save old context first
                 self.save_contexts(ctx_keys, current_context_lines)
                 current_context_lines = []
                 sub_main_ctx_key = copy.deepcopy(ctx_keys)
-                log.debug('LINE %-50s: entering sub-sub-context, append to ctx_keys', line)
+                log.debug(
+                    "LINE %-50s: entering sub-sub-context, append to ctx_keys", line
+                )
                 ctx_keys.append(line)
-            
-            elif ((line.startswith("interface ") and
-                   len(ctx_keys) == 2 and
-                   ctx_keys[0].startswith('mpls ldp') and
-                   ctx_keys[1].startswith('address-family'))):
+
+            elif (
+                line.startswith("interface ")
+                and len(ctx_keys) == 2
+                and ctx_keys[0].startswith("mpls ldp")
+                and ctx_keys[1].startswith("address-family")
+            ):
 
                 # Save old context first
                 self.save_contexts(ctx_keys, current_context_lines)
                 current_context_lines = []
                 sub_main_ctx_key = copy.deepcopy(ctx_keys)
-                log.debug('LINE %-50s: entering sub-sub-context, append to ctx_keys', line)
+                log.debug(
+                    "LINE %-50s: entering sub-sub-context, append to ctx_keys", line
+                )
                 ctx_keys.append(line)
 
             else:
                 # Continuing in an existing context, add non-commented lines to it
                 current_context_lines.append(line)
-                log.debug('LINE %-50s: append to current_context_lines, %-50s', line, ctx_keys)
+                log.debug(
+                    "LINE %-50s: append to current_context_lines, %-50s", line, ctx_keys
+                )
 
         # Save the context of the last one
         self.save_contexts(ctx_keys, current_context_lines)
@@ -647,20 +727,20 @@ def lines_to_config(ctx_keys, line, delete):
 
     if line:
         for (i, ctx_key) in enumerate(ctx_keys):
-            cmd.append(' ' * i + ctx_key)
+            cmd.append(" " * i + ctx_key)
 
         line = line.lstrip()
-        indent = len(ctx_keys) * ' '
+        indent = len(ctx_keys) * " "
 
         # There are some commands that are on by default so their "no" form will be
         # displayed in the config.  "no bgp default ipv4-unicast" is one of these.
         # If we need to remove this line we do so by adding "bgp default ipv4-unicast",
         # not by doing a "no no bgp default ipv4-unicast"
         if delete:
-            if line.startswith('no '):
-                cmd.append('%s%s' % (indent, line[3:]))
+            if line.startswith("no "):
+                cmd.append("%s%s" % (indent, line[3:]))
             else:
-                cmd.append('%sno %s' % (indent, line))
+                cmd.append("%sno %s" % (indent, line))
 
         else:
             cmd.append(indent + line)
@@ -669,16 +749,16 @@ def lines_to_config(ctx_keys, line, delete):
     # context ('no router ospf' for example)
     else:
         for i, ctx_key in enumerate(ctx_keys[:-1]):
-            cmd.append('%s%s' % (' ' * i, ctx_key))
+            cmd.append("%s%s" % (" " * i, ctx_key))
 
         # Only put the 'no' on the last sub-context
         if delete:
-            if ctx_keys[-1].startswith('no '):
-                cmd.append('%s%s' % (' ' * (len(ctx_keys) - 1), ctx_keys[-1][3:]))
+            if ctx_keys[-1].startswith("no "):
+                cmd.append("%s%s" % (" " * (len(ctx_keys) - 1), ctx_keys[-1][3:]))
             else:
-                cmd.append('%sno %s' % (' ' * (len(ctx_keys) - 1), ctx_keys[-1]))
+                cmd.append("%sno %s" % (" " * (len(ctx_keys) - 1), ctx_keys[-1]))
         else:
-            cmd.append('%s%s' % (' ' * (len(ctx_keys) - 1), ctx_keys[-1]))
+            cmd.append("%s%s" % (" " * (len(ctx_keys) - 1), ctx_keys[-1]))
 
     return cmd
 
@@ -691,23 +771,26 @@ def get_normalized_ipv6_line(line):
     the IPv6 word is a network
     """
     norm_line = ""
-    words = line.split(' ')
+    words = line.split(" ")
     for word in words:
         if ":" in word:
             norm_word = None
             if "/" in word:
                 try:
-                    if 'ipaddress' not in sys.modules:
+                    if "ipaddress" not in sys.modules:
                         v6word = IPNetwork(word)
-                        norm_word = '%s/%s' % (v6word.network, v6word.prefixlen)
+                        norm_word = "%s/%s" % (v6word.network, v6word.prefixlen)
                     else:
                         v6word = ip_network(word, strict=False)
-                        norm_word = '%s/%s' % (str(v6word.network_address), v6word.prefixlen)
+                        norm_word = "%s/%s" % (
+                            str(v6word.network_address),
+                            v6word.prefixlen,
+                        )
                 except ValueError:
                     pass
             if not norm_word:
                 try:
-                    norm_word = '%s' % IPv6Address(word)
+                    norm_word = "%s" % IPv6Address(word)
                 except ValueError:
                     norm_word = word
         else:
@@ -728,6 +811,7 @@ def line_exist(lines, target_ctx_keys, target_line, exact_match=True):
                     return True
     return False
 
+
 def check_for_exit_vrf(lines_to_add, lines_to_del):
 
     # exit-vrf is a bit tricky.  If the new config is missing it but we
@@ -740,25 +824,26 @@ def check_for_exit_vrf(lines_to_add, lines_to_del):
     for (ctx_keys, line) in lines_to_add:
         if add_exit_vrf == True:
             if ctx_keys[0] != prior_ctx_key:
-                insert_key=(prior_ctx_key),
+                insert_key = ((prior_ctx_key),)
                 lines_to_add.insert(index, ((insert_key, "exit-vrf")))
                 add_exit_vrf = False
 
-        if ctx_keys[0].startswith('vrf') and line:
+        if ctx_keys[0].startswith("vrf") and line:
             if line is not "exit-vrf":
                 add_exit_vrf = True
-                prior_ctx_key = (ctx_keys[0])
+                prior_ctx_key = ctx_keys[0]
             else:
                 add_exit_vrf = False
-        index+=1
+        index += 1
 
     for (ctx_keys, line) in lines_to_del:
         if line == "exit-vrf":
-            if (line_exist(lines_to_add, ctx_keys, line)):
+            if line_exist(lines_to_add, ctx_keys, line):
                 lines_to_del.remove((ctx_keys, line))
 
     return (lines_to_add, lines_to_del)
 
+
 def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
 
     # Quite possibly the most confusing (while accurate) variable names in history
@@ -768,10 +853,10 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
     for (ctx_keys, line) in lines_to_del:
         deleted = False
 
-        if ctx_keys[0].startswith('router bgp') and line:
+        if ctx_keys[0].startswith("router bgp") and line:
 
-            if line.startswith('neighbor '):
-                '''
+            if line.startswith("neighbor "):
+                """
                 BGP changed how it displays swpX peers that are part of peer-group. Older
                 versions of frr would display these on separate lines:
                     neighbor swp1 interface
@@ -788,10 +873,14 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                     neighbor swp1 peer-group FOO
 
                 If so then chop the del line and the corresponding add lines
-                '''
+                """
 
-                re_swpx_int_peergroup = re.search('neighbor (\S+) interface peer-group (\S+)', line)
-                re_swpx_int_v6only_peergroup = re.search('neighbor (\S+) interface v6only peer-group (\S+)', line)
+                re_swpx_int_peergroup = re.search(
+                    "neighbor (\S+) interface peer-group (\S+)", line
+                )
+                re_swpx_int_v6only_peergroup = re.search(
+                    "neighbor (\S+) interface v6only peer-group (\S+)", line
+                )
 
                 if re_swpx_int_peergroup or re_swpx_int_v6only_peergroup:
                     swpx_interface = None
@@ -807,21 +896,29 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                         swpx_interface = "neighbor %s interface v6only" % swpx
 
                     swpx_peergroup = "neighbor %s peer-group %s" % (swpx, peergroup)
-                    found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
-                    found_add_swpx_peergroup = line_exist(lines_to_add, ctx_keys, swpx_peergroup)
+                    found_add_swpx_interface = line_exist(
+                        lines_to_add, ctx_keys, swpx_interface
+                    )
+                    found_add_swpx_peergroup = line_exist(
+                        lines_to_add, ctx_keys, swpx_peergroup
+                    )
                     tmp_ctx_keys = tuple(list(ctx_keys))
 
                     if not found_add_swpx_peergroup:
                         tmp_ctx_keys = list(ctx_keys)
-                        tmp_ctx_keys.append('address-family ipv4 unicast')
+                        tmp_ctx_keys.append("address-family ipv4 unicast")
                         tmp_ctx_keys = tuple(tmp_ctx_keys)
-                        found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup)
+                        found_add_swpx_peergroup = line_exist(
+                            lines_to_add, tmp_ctx_keys, swpx_peergroup
+                        )
 
                         if not found_add_swpx_peergroup:
                             tmp_ctx_keys = list(ctx_keys)
-                            tmp_ctx_keys.append('address-family ipv6 unicast')
+                            tmp_ctx_keys.append("address-family ipv6 unicast")
                             tmp_ctx_keys = tuple(tmp_ctx_keys)
-                            found_add_swpx_peergroup = line_exist(lines_to_add, tmp_ctx_keys, swpx_peergroup)
+                            found_add_swpx_peergroup = line_exist(
+                                lines_to_add, tmp_ctx_keys, swpx_peergroup
+                            )
 
                     if found_add_swpx_interface and found_add_swpx_peergroup:
                         deleted = True
@@ -829,30 +926,36 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                         lines_to_add_to_del.append((ctx_keys, swpx_interface))
                         lines_to_add_to_del.append((tmp_ctx_keys, swpx_peergroup))
 
-                '''
+                """
                 Changing the bfd timers on neighbors is allowed without doing
                 a delete/add process. Since doing a "no neighbor blah bfd ..."
                 will cause the peer to bounce unnecessarily, just skip the delete
                 and just do the add.
-                '''
-                re_nbr_bfd_timers = re.search(r'neighbor (\S+) bfd (\S+) (\S+) (\S+)', line)
+                """
+                re_nbr_bfd_timers = re.search(
+                    r"neighbor (\S+) bfd (\S+) (\S+) (\S+)", line
+                )
 
                 if re_nbr_bfd_timers:
                     nbr = re_nbr_bfd_timers.group(1)
                     bfd_nbr = "neighbor %s" % nbr
-                    bfd_search_string =  bfd_nbr + r' bfd (\S+) (\S+) (\S+)'
+                    bfd_search_string = bfd_nbr + r" bfd (\S+) (\S+) (\S+)"
 
                     for (ctx_keys, add_line) in lines_to_add:
-                        if ctx_keys[0].startswith('router bgp'):
-                            re_add_nbr_bfd_timers = re.search(bfd_search_string, add_line)
+                        if ctx_keys[0].startswith("router bgp"):
+                            re_add_nbr_bfd_timers = re.search(
+                                bfd_search_string, add_line
+                            )
 
                             if re_add_nbr_bfd_timers:
-                                found_add_bfd_nbr = line_exist(lines_to_add, ctx_keys, bfd_nbr, False)
+                                found_add_bfd_nbr = line_exist(
+                                    lines_to_add, ctx_keys, bfd_nbr, False
+                                )
 
                                 if found_add_bfd_nbr:
                                     lines_to_del_to_del.append((ctx_keys, line))
 
-                '''
+                """
                 We changed how we display the neighbor interface command. Older
                 versions of frr would display the following:
                     neighbor swp1 interface
@@ -874,9 +977,13 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                     neighbor swp1 capability extended-nexthop
 
                 If so then chop the del line and the corresponding add lines
-                '''
-                re_swpx_int_remoteas = re.search('neighbor (\S+) interface remote-as (\S+)', line)
-                re_swpx_int_v6only_remoteas = re.search('neighbor (\S+) interface v6only remote-as (\S+)', line)
+                """
+                re_swpx_int_remoteas = re.search(
+                    "neighbor (\S+) interface remote-as (\S+)", line
+                )
+                re_swpx_int_v6only_remoteas = re.search(
+                    "neighbor (\S+) interface v6only remote-as (\S+)", line
+                )
 
                 if re_swpx_int_remoteas or re_swpx_int_v6only_remoteas:
                     swpx_interface = None
@@ -892,8 +999,12 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                         swpx_interface = "neighbor %s interface v6only" % swpx
 
                     swpx_remoteas = "neighbor %s remote-as %s" % (swpx, remoteas)
-                    found_add_swpx_interface = line_exist(lines_to_add, ctx_keys, swpx_interface)
-                    found_add_swpx_remoteas = line_exist(lines_to_add, ctx_keys, swpx_remoteas)
+                    found_add_swpx_interface = line_exist(
+                        lines_to_add, ctx_keys, swpx_interface
+                    )
+                    found_add_swpx_remoteas = line_exist(
+                        lines_to_add, ctx_keys, swpx_remoteas
+                    )
                     tmp_ctx_keys = tuple(list(ctx_keys))
 
                     if found_add_swpx_interface and found_add_swpx_remoteas:
@@ -902,7 +1013,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                         lines_to_add_to_del.append((ctx_keys, swpx_interface))
                         lines_to_add_to_del.append((tmp_ctx_keys, swpx_remoteas))
 
-            '''
+            """
             We made the 'bgp bestpath as-path multipath-relax' command
             automatically assume 'no-as-set' since the lack of this option caused
             weird routing problems. When the running config is shown in
@@ -910,10 +1021,12 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
             is the default. This causes frr-reload to unnecessarily unapply
             this option only to apply it back again, causing unnecessary session
             resets.
-            '''
-            if 'multipath-relax' in line:
-                re_asrelax_new = re.search('^bgp\s+bestpath\s+as-path\s+multipath-relax$', line)
-                old_asrelax_cmd = 'bgp bestpath as-path multipath-relax no-as-set'
+            """
+            if "multipath-relax" in line:
+                re_asrelax_new = re.search(
+                    "^bgp\s+bestpath\s+as-path\s+multipath-relax$", line
+                )
+                old_asrelax_cmd = "bgp bestpath as-path multipath-relax no-as-set"
                 found_asrelax_old = line_exist(lines_to_add, ctx_keys, old_asrelax_cmd)
 
                 if re_asrelax_new and found_asrelax_old:
@@ -921,34 +1034,36 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                     lines_to_del_to_del.append((ctx_keys, line))
                     lines_to_add_to_del.append((ctx_keys, old_asrelax_cmd))
 
-            '''
+            """
             If we are modifying the BGP table-map we need to avoid a del/add and
             instead modify the table-map in place via an add.  This is needed to
             avoid installing all routes in the RIB the second the 'no table-map'
             is issued.
-            '''
-            if line.startswith('table-map'):
-                found_table_map = line_exist(lines_to_add, ctx_keys, 'table-map', False)
+            """
+            if line.startswith("table-map"):
+                found_table_map = line_exist(lines_to_add, ctx_keys, "table-map", False)
 
                 if found_table_map:
                     lines_to_del_to_del.append((ctx_keys, line))
 
-        '''
+        """
         More old-to-new config handling. ip import-table no longer accepts
         distance, but we honor the old syntax. But 'show running' shows only
         the new syntax. This causes an unnecessary 'no import-table' followed
         by the same old 'ip import-table' which causes perturbations in
         announced routes leading to traffic blackholes. Fix this issue.
-        '''
-        re_importtbl = re.search('^ip\s+import-table\s+(\d+)$', ctx_keys[0])
+        """
+        re_importtbl = re.search("^ip\s+import-table\s+(\d+)$", ctx_keys[0])
         if re_importtbl:
             table_num = re_importtbl.group(1)
             for ctx in lines_to_add:
-                if ctx[0][0].startswith('ip import-table %s distance' % table_num):
-                    lines_to_del_to_del.append((('ip import-table %s' % table_num,), None))
+                if ctx[0][0].startswith("ip import-table %s distance" % table_num):
+                    lines_to_del_to_del.append(
+                        (("ip import-table %s" % table_num,), None)
+                    )
                     lines_to_add_to_del.append((ctx[0], None))
 
-        '''
+        """
         ip/ipv6 prefix-list can be specified without a seq number. However,
         the running config always adds 'seq x', where x is a number incremented
         by 5 for every element, to the prefix list. So, ignore such lines as
@@ -956,24 +1071,36 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
              ip prefix-list PR-TABLE-2 seq 5 permit 20.8.2.0/24 le 32
              ip prefix-list PR-TABLE-2 seq 10 permit 20.8.2.0/24 le 32
              ipv6 prefix-list vrfdev6-12 permit 2000:9:2::/64 gt 64
-        '''
-        re_ip_pfxlst = re.search('^(ip|ipv6)(\s+prefix-list\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$',
-                                 ctx_keys[0])
+        """
+        re_ip_pfxlst = re.search(
+            "^(ip|ipv6)(\s+prefix-list\s+)(\S+\s+)(seq \d+\s+)(permit|deny)(.*)$",
+            ctx_keys[0],
+        )
         if re_ip_pfxlst:
-            tmpline = (re_ip_pfxlst.group(1) + re_ip_pfxlst.group(2) +
-                       re_ip_pfxlst.group(3) + re_ip_pfxlst.group(5) +
-                       re_ip_pfxlst.group(6))
+            tmpline = (
+                re_ip_pfxlst.group(1)
+                + re_ip_pfxlst.group(2)
+                + re_ip_pfxlst.group(3)
+                + re_ip_pfxlst.group(5)
+                + re_ip_pfxlst.group(6)
+            )
             for ctx in lines_to_add:
                 if ctx[0][0] == tmpline:
                     lines_to_del_to_del.append((ctx_keys, None))
                     lines_to_add_to_del.append(((tmpline,), None))
 
-        if (len(ctx_keys) == 3 and
-            ctx_keys[0].startswith('router bgp') and
-            ctx_keys[1] == 'address-family l2vpn evpn' and
-            ctx_keys[2].startswith('vni')):
+        if (
+            len(ctx_keys) == 3
+            and ctx_keys[0].startswith("router bgp")
+            and ctx_keys[1] == "address-family l2vpn evpn"
+            and ctx_keys[2].startswith("vni")
+        ):
 
-            re_route_target = re.search('^route-target import (.*)$', line) if line is not None else False
+            re_route_target = (
+                re.search("^route-target import (.*)$", line)
+                if line is not None
+                else False
+            )
 
             if re_route_target:
                 rt = re_route_target.group(1).strip()
@@ -981,10 +1108,14 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                 route_target_export_line = "route-target export %s" % rt
                 route_target_both_line = "route-target both %s" % rt
 
-                found_route_target_export_line = line_exist(lines_to_del, ctx_keys, route_target_export_line)
-                found_route_target_both_line = line_exist(lines_to_add, ctx_keys, route_target_both_line)
+                found_route_target_export_line = line_exist(
+                    lines_to_del, ctx_keys, route_target_export_line
+                )
+                found_route_target_both_line = line_exist(
+                    lines_to_add, ctx_keys, route_target_both_line
+                )
 
-                '''
+                """
                 If the running configs has
                     route-target import 1:1
                     route-target export 1:1
@@ -993,7 +1124,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                     route-target both 1:1
 
                 then we can ignore deleting the import/export and ignore adding the 'both'
-                '''
+                """
                 if found_route_target_export_line and found_route_target_both_line:
                     lines_to_del_to_del.append((ctx_keys, route_target_import_line))
                     lines_to_del_to_del.append((ctx_keys, route_target_export_line))
@@ -1002,10 +1133,9 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
         # Deleting static routes under a vrf can lead to time-outs if each is sent
         # as separate vtysh -c commands. Change them from being in lines_to_del and
         # put the "no" form in lines_to_add
-        if ctx_keys[0].startswith('vrf ') and line:
-            if (line.startswith('ip route') or
-                line.startswith('ipv6 route')):
-                add_cmd = ('no ' + line)
+        if ctx_keys[0].startswith("vrf ") and line:
+            if line.startswith("ip route") or line.startswith("ipv6 route"):
+                add_cmd = "no " + line
                 lines_to_add.append((ctx_keys, add_cmd))
                 lines_to_del_to_del.append((ctx_keys, line))
 
@@ -1016,7 +1146,7 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                 lines_to_del_to_del.append((ctx_keys, line))
                 lines_to_add_to_del.append((ctx_keys, line))
             else:
-                '''
+                """
                 We have commands that used to be displayed in the global part
                 of 'router bgp' that are now displayed under 'address-family ipv4 unicast'
 
@@ -1032,8 +1162,12 @@ def ignore_delete_re_add_lines(lines_to_add, lines_to_del):
                     neighbor ISL advertisement-interval 0
 
                 Look to see if we are deleting it in one format just to add it back in the other
-                '''
-                if ctx_keys[0].startswith('router bgp') and len(ctx_keys) > 1 and ctx_keys[1] == 'address-family ipv4 unicast':
+                """
+                if (
+                    ctx_keys[0].startswith("router bgp")
+                    and len(ctx_keys) > 1
+                    and ctx_keys[1] == "address-family ipv4 unicast"
+                ):
                     tmp_ctx_keys = list(ctx_keys)[:-1]
                     tmp_ctx_keys = tuple(tmp_ctx_keys)
 
@@ -1061,16 +1195,18 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
 
     for (ctx_keys, line) in lines_to_del:
 
-        if (ctx_keys[0].startswith('frr version') or
-            ctx_keys[0].startswith('frr defaults') or
-            ctx_keys[0].startswith('username') or
-            ctx_keys[0].startswith('password') or
-            ctx_keys[0].startswith('line vty') or
-
+        if (
+            ctx_keys[0].startswith("frr version")
+            or ctx_keys[0].startswith("frr defaults")
+            or ctx_keys[0].startswith("username")
+            or ctx_keys[0].startswith("password")
+            or ctx_keys[0].startswith("line vty")
+            or
             # This is technically "no"able but if we did so frr-reload would
             # stop working so do not let the user shoot themselves in the foot
             # by removing this.
-            ctx_keys[0].startswith('service integrated-vtysh-config')):
+            ctx_keys[0].startswith("service integrated-vtysh-config")
+        ):
 
             log.info('"%s" cannot be removed' % (ctx_keys[-1],))
             lines_to_del_to_del.append((ctx_keys, line))
@@ -1106,25 +1242,35 @@ def compare_context_objects(newconf, running):
                 lines_to_del.append((running_ctx_keys, None))
 
             # We cannot do 'no interface' or 'no vrf' in FRR, and so deal with it
-            elif running_ctx_keys[0].startswith('interface') or running_ctx_keys[0].startswith('vrf'):
+            elif running_ctx_keys[0].startswith("interface") or running_ctx_keys[
+                0
+            ].startswith("vrf"):
                 for line in running_ctx.lines:
                     lines_to_del.append((running_ctx_keys, line))
 
             # If this is an address-family under 'router bgp' and we are already deleting the
             # entire 'router bgp' context then ignore this sub-context
-            elif "router bgp" in running_ctx_keys[0] and len(running_ctx_keys) > 1 and delete_bgpd:
+            elif (
+                "router bgp" in running_ctx_keys[0]
+                and len(running_ctx_keys) > 1
+                and delete_bgpd
+            ):
                 continue
 
             # Delete an entire vni sub-context under "address-family l2vpn evpn"
-            elif ("router bgp" in running_ctx_keys[0] and
-                  len(running_ctx_keys) > 2 and
-                  running_ctx_keys[1].startswith('address-family l2vpn evpn') and
-                  running_ctx_keys[2].startswith('vni ')):
+            elif (
+                "router bgp" in running_ctx_keys[0]
+                and len(running_ctx_keys) > 2
+                and running_ctx_keys[1].startswith("address-family l2vpn evpn")
+                and running_ctx_keys[2].startswith("vni ")
+            ):
                 lines_to_del.append((running_ctx_keys, None))
 
-            elif ("router bgp" in running_ctx_keys[0] and
-                  len(running_ctx_keys) > 1 and
-                  running_ctx_keys[1].startswith('address-family')):
+            elif (
+                "router bgp" in running_ctx_keys[0]
+                and len(running_ctx_keys) > 1
+                and running_ctx_keys[1].startswith("address-family")
+            ):
                 # There's no 'no address-family' support and so we have to
                 # delete each line individually again
                 for line in running_ctx.lines:
@@ -1134,24 +1280,31 @@ def compare_context_objects(newconf, running):
             # doing vtysh -c inefficient (and can time out.)  For
             # these commands, instead of adding them to lines_to_del,
             # add the "no " version to lines_to_add.
-            elif (running_ctx_keys[0].startswith('ip route') or
-                  running_ctx_keys[0].startswith('ipv6 route') or
-                  running_ctx_keys[0].startswith('access-list') or
-                  running_ctx_keys[0].startswith('ipv6 access-list') or
-                  running_ctx_keys[0].startswith('ip prefix-list') or
-                  running_ctx_keys[0].startswith('ipv6 prefix-list')):
-                add_cmd = ('no ' + running_ctx_keys[0],)
+            elif (
+                running_ctx_keys[0].startswith("ip route")
+                or running_ctx_keys[0].startswith("ipv6 route")
+                or running_ctx_keys[0].startswith("access-list")
+                or running_ctx_keys[0].startswith("ipv6 access-list")
+                or running_ctx_keys[0].startswith("ip prefix-list")
+                or running_ctx_keys[0].startswith("ipv6 prefix-list")
+            ):
+                add_cmd = ("no " + running_ctx_keys[0],)
                 lines_to_add.append((add_cmd, None))
 
             # if this an interface sub-subcontext in an address-family block in ldpd and
             # we are already deleting the whole context, then ignore this
-            elif (len(running_ctx_keys) > 2 and running_ctx_keys[0].startswith('mpls ldp') and
-                  running_ctx_keys[1].startswith('address-family') and
-                  (running_ctx_keys[:2], None) in lines_to_del):
+            elif (
+                len(running_ctx_keys) > 2
+                and running_ctx_keys[0].startswith("mpls ldp")
+                and running_ctx_keys[1].startswith("address-family")
+                and (running_ctx_keys[:2], None) in lines_to_del
+            ):
                 continue
 
             # Non-global context
-            elif running_ctx_keys and not any("address-family" in key for key in running_ctx_keys):
+            elif running_ctx_keys and not any(
+                "address-family" in key for key in running_ctx_keys
+            ):
                 lines_to_del.append((running_ctx_keys, None))
 
             elif running_ctx_keys and not any("vni" in key for key in running_ctx_keys):
@@ -1186,33 +1339,78 @@ def compare_context_objects(newconf, running):
                 lines_to_add.append((newconf_ctx_keys, line))
 
     (lines_to_add, lines_to_del) = check_for_exit_vrf(lines_to_add, lines_to_del)
-    (lines_to_add, lines_to_del) = ignore_delete_re_add_lines(lines_to_add, lines_to_del)
-    (lines_to_add, lines_to_del) = ignore_unconfigurable_lines(lines_to_add, lines_to_del)
+    (lines_to_add, lines_to_del) = ignore_delete_re_add_lines(
+        lines_to_add, lines_to_del
+    )
+    (lines_to_add, lines_to_del) = ignore_unconfigurable_lines(
+        lines_to_add, lines_to_del
+    )
 
     return (lines_to_add, lines_to_del)
 
 
-if __name__ == '__main__':
+if __name__ == "__main__":
     # Command line options
-    parser = argparse.ArgumentParser(description='Dynamically apply diff in frr configs')
-    parser.add_argument('--input', help='Read running config from file instead of "show running"')
+    parser = argparse.ArgumentParser(
+        description="Dynamically apply diff in frr configs"
+    )
+    parser.add_argument(
+        "--input", help='Read running config from file instead of "show running"'
+    )
     group = parser.add_mutually_exclusive_group(required=True)
-    group.add_argument('--reload', action='store_true', help='Apply the deltas', default=False)
-    group.add_argument('--test', action='store_true', help='Show the deltas', default=False)
+    group.add_argument(
+        "--reload", action="store_true", help="Apply the deltas", default=False
+    )
+    group.add_argument(
+        "--test", action="store_true", help="Show the deltas", default=False
+    )
     level_group = parser.add_mutually_exclusive_group()
-    level_group.add_argument('--debug', action='store_true',
-                             help='Enable debugs (synonym for --log-level=debug)', default=False)
-    level_group.add_argument('--log-level', help='Log level', default="info",
-                             choices=("critical", "error", "warning", "info", "debug"))
-    parser.add_argument('--stdout', action='store_true', help='Log to STDOUT', default=False)
-    parser.add_argument('--pathspace', '-N', metavar='NAME', help='Reload specified path/namespace', default=None)
-    parser.add_argument('filename', help='Location of new frr config file')
-    parser.add_argument('--overwrite', action='store_true', help='Overwrite frr.conf with running config output', default=False)
-    parser.add_argument('--bindir', help='path to the vtysh executable', default='/usr/bin')
-    parser.add_argument('--confdir', help='path to the daemon config files', default='/etc/frr')
-    parser.add_argument('--rundir', help='path for the temp config file', default='/var/run/frr')
-    parser.add_argument('--vty_socket', help='socket to be used by vtysh to connect to the daemons', default=None)
-    parser.add_argument('--daemon', help='daemon for which want to replace the config', default='')
+    level_group.add_argument(
+        "--debug",
+        action="store_true",
+        help="Enable debugs (synonym for --log-level=debug)",
+        default=False,
+    )
+    level_group.add_argument(
+        "--log-level",
+        help="Log level",
+        default="info",
+        choices=("critical", "error", "warning", "info", "debug"),
+    )
+    parser.add_argument(
+        "--stdout", action="store_true", help="Log to STDOUT", default=False
+    )
+    parser.add_argument(
+        "--pathspace",
+        "-N",
+        metavar="NAME",
+        help="Reload specified path/namespace",
+        default=None,
+    )
+    parser.add_argument("filename", help="Location of new frr config file")
+    parser.add_argument(
+        "--overwrite",
+        action="store_true",
+        help="Overwrite frr.conf with running config output",
+        default=False,
+    )
+    parser.add_argument(
+        "--bindir", help="path to the vtysh executable", default="/usr/bin"
+    )
+    parser.add_argument(
+        "--confdir", help="path to the daemon config files", default="/etc/frr"
+    )
+    parser.add_argument(
+        "--rundir", help="path for the temp config file", default="/var/run/frr"
+    )
+    parser.add_argument(
+        "--vty_socket",
+        help="socket to be used by vtysh to connect to the daemons",
+        default=None,
+    )
+    parser.add_argument(
+        "--daemon", help="daemon for which want to replace the config", default=""
+    )
 
     args = parser.parse_args()
 
@@ -1220,22 +1418,28 @@ if __name__ == '__main__':
     # For --test log to stdout
     # For --reload log to /var/log/frr/frr-reload.log
     if args.test or args.stdout:
-        logging.basicConfig(format='%(asctime)s %(levelname)5s: %(message)s')
+        logging.basicConfig(format="%(asctime)s %(levelname)5s: %(message)s")
 
         # Color the errors and warnings in red
-        logging.addLevelName(logging.ERROR, "\033[91m  %s\033[0m" % logging.getLevelName(logging.ERROR))
-        logging.addLevelName(logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING))
+        logging.addLevelName(
+            logging.ERROR, "\033[91m  %s\033[0m" % logging.getLevelName(logging.ERROR)
+        )
+        logging.addLevelName(
+            logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING)
+        )
 
     elif args.reload:
-        if not os.path.isdir('/var/log/frr/'):
-            os.makedirs('/var/log/frr/')
+        if not os.path.isdir("/var/log/frr/"):
+            os.makedirs("/var/log/frr/")
 
-        logging.basicConfig(filename='/var/log/frr/frr-reload.log',
-                            format='%(asctime)s %(levelname)5s: %(message)s')
+        logging.basicConfig(
+            filename="/var/log/frr/frr-reload.log",
+            format="%(asctime)s %(levelname)5s: %(message)s",
+        )
 
     # argparse should prevent this from happening but just to be safe...
     else:
-        raise Exception('Must specify --reload or --test')
+        raise Exception("Must specify --reload or --test")
     log = logging.getLogger(__name__)
 
     if args.debug:
@@ -1269,40 +1473,59 @@ if __name__ == '__main__':
         sys.exit(1)
 
     # Verify that bindir is correct
-    if not os.path.isdir(args.bindir) or not os.path.isfile(args.bindir + '/vtysh'):
+    if not os.path.isdir(args.bindir) or not os.path.isfile(args.bindir + "/vtysh"):
         log.error("Bindir %s is not a valid path to vtysh" % args.bindir)
         sys.exit(1)
 
     # verify that the vty_socket, if specified, is valid
     if args.vty_socket and not os.path.isdir(args.vty_socket):
-        log.error('vty_socket %s is not a valid path' % args.vty_socket)
+        log.error("vty_socket %s is not a valid path" % args.vty_socket)
         sys.exit(1)
 
     # verify that the daemon, if specified, is valid
-    if args.daemon and args.daemon not in ['zebra', 'bgpd', 'fabricd', 'isisd', 'ospf6d', 'ospfd', 'pbrd', 'pimd', 'ripd', 'ripngd', 'sharpd', 'staticd', 'vrrpd', 'ldpd']:
-        log.error("Daemon %s is not a valid option for 'show running-config'" % args.daemon)
+    if args.daemon and args.daemon not in [
+        "zebra",
+        "bgpd",
+        "fabricd",
+        "isisd",
+        "ospf6d",
+        "ospfd",
+        "pbrd",
+        "pimd",
+        "ripd",
+        "ripngd",
+        "sharpd",
+        "staticd",
+        "vrrpd",
+        "ldpd",
+    ]:
+        log.error(
+            "Daemon %s is not a valid option for 'show running-config'" % args.daemon
+        )
         sys.exit(1)
 
     vtysh = Vtysh(args.bindir, args.confdir, args.vty_socket, args.pathspace)
 
     # Verify that 'service integrated-vtysh-config' is configured
     if args.pathspace:
-        vtysh_filename = args.confdir + '/' + args.pathspace + '/vtysh.conf'
+        vtysh_filename = args.confdir + "/" + args.pathspace + "/vtysh.conf"
     else:
-        vtysh_filename = args.confdir + '/vtysh.conf'
+        vtysh_filename = args.confdir + "/vtysh.conf"
     service_integrated_vtysh_config = True
 
     if os.path.isfile(vtysh_filename):
-        with open(vtysh_filename, 'r') as fh:
+        with open(vtysh_filename, "r") as fh:
             for line in fh.readlines():
                 line = line.strip()
 
-                if line == 'no service integrated-vtysh-config':
+                if line == "no service integrated-vtysh-config":
                     service_integrated_vtysh_config = False
                     break
 
     if not service_integrated_vtysh_config and not args.daemon:
-        log.error("'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'")
+        log.error(
+            "'service integrated-vtysh-config' is not configured, this is required for 'service frr reload'"
+        )
         sys.exit(1)
 
     log.info('Called via "%s"', str(args))
@@ -1335,10 +1558,10 @@ if __name__ == '__main__':
 
             for (ctx_keys, line) in lines_to_del:
 
-                if line == '!':
+                if line == "!":
                     continue
 
-                cmd = '\n'.join(lines_to_config(ctx_keys, line, True))
+                cmd = "\n".join(lines_to_config(ctx_keys, line, True))
                 lines_to_configure.append(cmd)
                 print(cmd)
 
@@ -1348,10 +1571,10 @@ if __name__ == '__main__':
 
             for (ctx_keys, line) in lines_to_add:
 
-                if line == '!':
+                if line == "!":
                     continue
 
-                cmd = '\n'.join(lines_to_config(ctx_keys, line, False))
+                cmd = "\n".join(lines_to_config(ctx_keys, line, False))
                 lines_to_configure.append(cmd)
                 print(cmd)
 
@@ -1361,7 +1584,7 @@ if __name__ == '__main__':
         if not vtysh.is_config_available():
             sys.exit(1)
 
-        log.debug('New Frr Config\n%s', newconf.get_lines())
+        log.debug("New Frr Config\n%s", newconf.get_lines())
 
         # This looks a little odd but we have to do this twice...here is why
         # If the user had this running bgp config:
@@ -1403,7 +1626,7 @@ if __name__ == '__main__':
         for x in range(2):
             running = Config(vtysh)
             running.load_from_show_running(args.daemon)
-            log.debug('Running Frr Config (Pass #%d)\n%s', x, running.get_lines())
+            log.debug("Running Frr Config (Pass #%d)\n%s", x, running.get_lines())
 
             (lines_to_add, lines_to_del) = compare_context_objects(newconf, running)
 
@@ -1428,7 +1651,7 @@ if __name__ == '__main__':
             if lines_to_del and x == 0:
                 for (ctx_keys, line) in lines_to_del:
 
-                    if line == '!':
+                    if line == "!":
                         continue
 
                     # 'no' commands are tricky, we can't just put them in a file and
@@ -1453,7 +1676,7 @@ if __name__ == '__main__':
 
                     while True:
                         try:
-                            vtysh(['configure'] + cmd)
+                            vtysh(["configure"] + cmd)
 
                         except VtyshException:
 
@@ -1461,17 +1684,20 @@ if __name__ == '__main__':
                             #   'no ip ospf authentication message-digest 1.1.1.1' in
                             #   our example above
                             # - Split that last entry by whitespace and drop the last word
-                            log.info('Failed to execute %s', ' '.join(cmd))
-                            last_arg = cmd[-1].split(' ')
+                            log.info("Failed to execute %s", " ".join(cmd))
+                            last_arg = cmd[-1].split(" ")
 
                             if len(last_arg) <= 2:
-                                log.error('"%s" we failed to remove this command', ' -- '.join(original_cmd))
+                                log.error(
+                                    '"%s" we failed to remove this command',
+                                    " -- ".join(original_cmd),
+                                )
                                 break
 
                             new_last_arg = last_arg[0:-1]
-                            cmd[-1] = ' '.join(new_last_arg)
+                            cmd[-1] = " ".join(new_last_arg)
                         else:
-                            log.info('Executed "%s"', ' '.join(cmd))
+                            log.info('Executed "%s"', " ".join(cmd))
                             break
 
             if lines_to_add:
@@ -1479,28 +1705,31 @@ if __name__ == '__main__':
 
                 for (ctx_keys, line) in lines_to_add:
 
-                    if line == '!':
+                    if line == "!":
                         continue
 
                     # Don't run "no" commands twice since they can error
                     # out the second time due to first deletion
-                    if x == 1 and ctx_keys[0].startswith('no '):
+                    if x == 1 and ctx_keys[0].startswith("no "):
                         continue
 
-                    cmd = '\n'.join(lines_to_config(ctx_keys, line, False)) + '\n'
+                    cmd = "\n".join(lines_to_config(ctx_keys, line, False)) + "\n"
                     lines_to_configure.append(cmd)
 
                 if lines_to_configure:
-                    random_string = ''.join(random.SystemRandom().choice(
-                                            string.ascii_uppercase +
-                                            string.digits) for _ in range(6))
+                    random_string = "".join(
+                        random.SystemRandom().choice(
+                            string.ascii_uppercase + string.digits
+                        )
+                        for _ in range(6)
+                    )
 
                     filename = args.rundir + "/reload-%s.txt" % random_string
                     log.info("%s content\n%s" % (filename, pformat(lines_to_configure)))
 
-                    with open(filename, 'w') as fh:
+                    with open(filename, "w") as fh:
                         for line in lines_to_configure:
-                            fh.write(line + '\n')
+                            fh.write(line + "\n")
 
                     try:
                         vtysh.exec_file(filename)
@@ -1510,9 +1739,9 @@ if __name__ == '__main__':
                     os.unlink(filename)
 
         # Make these changes persistent
-        target = str(args.confdir + '/frr.conf')
+        target = str(args.confdir + "/frr.conf")
         if args.overwrite or (not args.daemon and args.filename != target):
-            vtysh('write')
+            vtysh("write")
 
     if not reload_ok:
         sys.exit(1)
index 9a144b2b06d4527023ff7932ac9861c4e25de8ab..312ee88bf4571d537b50a9b41804546a70077630 100644 (file)
@@ -152,7 +152,7 @@ daemon_start() {
        daemon_prep "$daemon" "$inst" || return 1
        if test ! -d "$V_PATH"; then
                mkdir -p "$V_PATH"
-               chown frr "$V_PATH"
+               chownfrr "$V_PATH"
        fi
 
        eval wrap="\$${daemon}_wrap"
index df2437d5bcf661590f727e23b3bdbaae63e99cec..ddf71aa0ef8f8b7083d2135da89df38fe3e4eca8 100644 (file)
@@ -4,58 +4,71 @@ import shlex
 import os
 import re
 
-os.environ['LC_ALL'] = 'C'
-os.environ['LANG'] = 'C'
+os.environ["LC_ALL"] = "C"
+os.environ["LANG"] = "C"
 for k in list(os.environ.keys()):
-    if k.startswith('LC_'):
+    if k.startswith("LC_"):
         os.environ.pop(k)
 
 if len(sys.argv) < 2:
-    sys.stderr.write('start as format-test.py gcc-123.45 [-options ...]\n')
+    sys.stderr.write("start as format-test.py gcc-123.45 [-options ...]\n")
     sys.exit(1)
 
-c_re = re.compile(r'//\s+(NO)?WARN')
+c_re = re.compile(r"//\s+(NO)?WARN")
 expect = {}
 lines = {}
 
-with open('format-test.c', 'r') as fd:
+with open("format-test.c", "r") as fd:
     for lno, line in enumerate(fd.readlines(), 1):
         lines[lno] = line.strip()
         m = c_re.search(line)
         if m is None:
             continue
         if m.group(1) is None:
-            expect[lno] = 'warn'
+            expect[lno] = "warn"
         else:
-            expect[lno] = 'nowarn'
+            expect[lno] = "nowarn"
 
-cmd = shlex.split('-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c')
+cmd = shlex.split(
+    "-Wall -Wextra -Wno-unused -fplugin=./frr-format.so -fno-diagnostics-show-caret -c -o format-test.o format-test.c"
+)
 
-gcc = subprocess.Popen(sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+gcc = subprocess.Popen(
+    sys.argv[1:] + cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+)
 sout, serr = gcc.communicate()
 gcc.wait()
 
-gcclines = serr.decode('UTF-8').splitlines()
-line_re = re.compile(r'^format-test\.c:(\d+):(.*)$')
+gcclines = serr.decode("UTF-8").splitlines()
+line_re = re.compile(r"^format-test\.c:(\d+):(.*)$")
 gcc_warns = {}
 
 for line in gcclines:
-    if line.find('In function') >= 0:
+    if line.find("In function") >= 0:
         continue
     m = line_re.match(line)
     if m is None:
-        sys.stderr.write('cannot process GCC output: %s\n' % line)
+        sys.stderr.write("cannot process GCC output: %s\n" % line)
         continue
 
     lno = int(m.group(1))
     gcc_warns.setdefault(lno, []).append(line)
 
 for lno, val in expect.items():
-    if val == 'nowarn' and lno in gcc_warns:
-        sys.stderr.write('unexpected gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno])))
-    if val == 'warn' and lno not in gcc_warns:
-        sys.stderr.write('expected warning on line %d but did not get one\n\t%s\n' % (lno, lines[lno]))
+    if val == "nowarn" and lno in gcc_warns:
+        sys.stderr.write(
+            "unexpected gcc warning on line %d:\n\t%s\n\t%s\n"
+            % (lno, lines[lno], "\n\t".join(gcc_warns[lno]))
+        )
+    if val == "warn" and lno not in gcc_warns:
+        sys.stderr.write(
+            "expected warning on line %d but did not get one\n\t%s\n"
+            % (lno, lines[lno])
+        )
 
 leftover = set(gcc_warns.keys()) - set(expect.keys())
 for lno in sorted(leftover):
-    sys.stderr.write('unmarked gcc warning on line %d:\n\t%s\n\t%s\n' % (lno, lines[lno], '\n\t'.join(gcc_warns[lno])))
+    sys.stderr.write(
+        "unmarked gcc warning on line %d:\n\t%s\n\t%s\n"
+        % (lno, lines[lno], "\n\t".join(gcc_warns[lno]))
+    )
index be56517171280ef32a4e5560855c905f56c6b744..6d91d2cdcd034c2d3f1e87028d17ba8a565368bf 100644 (file)
@@ -2729,6 +2729,16 @@ tree type_normalize (tree type, tree *cousin, tree target = NULL)
   return type;
 }
 
+/* gcc-10 asserts when you give a TYPE_DECL instead of the actual TYPE */
+static tree
+decl_deref(tree typ)
+{
+  while (TREE_CODE (typ) == TYPE_DECL)
+    typ = DECL_ORIGINAL_TYPE (typ);
+
+  return typ;
+}
+
 static void
 check_format_types (const substring_loc &fmt_loc,
                    format_wanted_type *types, const format_kind_info *fki,
@@ -2750,6 +2760,8 @@ check_format_types (const substring_loc &fmt_loc,
       wanted_type = types->wanted_type;
       arg_num = types->arg_num;
 
+      wanted_type = decl_deref(wanted_type);
+
       /* The following should not occur here.  */
       gcc_assert (wanted_type);
       gcc_assert (wanted_type != void_type_node || types->pointer_count);
@@ -2873,7 +2885,7 @@ check_format_types (const substring_loc &fmt_loc,
                          || cur_type == signed_char_type_node
                          || cur_type == unsigned_char_type_node);
 
-      int compat = lang_hooks.types_compatible_p (wanted_type, cur_type);
+      int compat = lang_hooks.types_compatible_p (decl_deref (wanted_type), decl_deref (cur_type));
       /* Check the type of the "real" argument, if there's a type we want.  */
       if ((TREE_CODE (wanted_type) != INTEGER_TYPE || types->pointer_count)
          && compat)
@@ -3180,6 +3192,9 @@ matching_type_p (tree spec_type, tree arg_type)
   gcc_assert (spec_type);
   gcc_assert (arg_type);
 
+  spec_type = decl_deref (spec_type);
+  arg_type = decl_deref (arg_type);
+
   /* If any of the types requires structural equality, we can't compare
      their canonical types.  */
   if (TYPE_STRUCTURAL_EQUALITY_P (spec_type)
index eaab932228f2a30bb68ce712fb2e74c650171cc2..a785f43cdf090b074255bcd4576e528045213dcd 100644 (file)
@@ -368,13 +368,12 @@ int main(int argc, char *argv[])
        /* Generate callback prototypes. */
        if (!static_cbs) {
                printf("/* prototypes */\n");
-               yang_snodes_iterate_module(module->info, generate_prototypes, 0,
-                                          NULL);
+               yang_snodes_iterate(module->info, generate_prototypes, 0, NULL);
                printf("\n");
        }
 
        /* Generate callback functions. */
-       yang_snodes_iterate_module(module->info, generate_callbacks, 0, NULL);
+       yang_snodes_iterate(module->info, generate_callbacks, 0, NULL);
 
        strlcpy(module_name_underscores, module->name,
                sizeof(module_name_underscores));
@@ -386,7 +385,7 @@ int main(int argc, char *argv[])
               "\t.name = \"%s\",\n"
               "\t.nodes = {\n",
               module_name_underscores, module->name);
-       yang_snodes_iterate_module(module->info, generate_nb_nodes, 0, NULL);
+       yang_snodes_iterate(module->info, generate_nb_nodes, 0, NULL);
        printf("\t\t{\n"
               "\t\t\t.xpath = NULL,\n"
               "\t\t},\n");
index f908e1fc691b9a32969f8220cfec715abedf2e88..53a53c943c478521f365f059756181d0423d7110 100644 (file)
@@ -71,8 +71,8 @@ int main(int argc, char *argv[])
        module = yang_module_load(argv[0]);
 
        /* Generate deviations. */
-       yang_snodes_iterate_module(module->info, generate_yang_deviation,
-                                  YANG_ITER_FILTER_IMPLICIT, NULL);
+       yang_snodes_iterate(module->info, generate_yang_deviation,
+                           YANG_ITER_FILTER_IMPLICIT, NULL);
 
        /* Cleanup and exit. */
        yang_terminate();
index 540b7a1357755d2fe5e95ec264ae3982e5e07f47..ae258bddfe39915db33e653df25e2d5cf08168f9 100755 (executable)
@@ -7,9 +7,9 @@ import os
 import subprocess
 import datetime
 
-TOOLS_DIR="tools/"
-ETC_DIR="/etc/frr/"
-LOG_DIR="/var/log/frr/"
+TOOLS_DIR = "tools/"
+ETC_DIR = "/etc/frr/"
+LOG_DIR = "/var/log/frr/"
 SUCCESS = 1
 FAIL = 0
 
@@ -17,96 +17,103 @@ inputFile = ETC_DIR + "support_bundle_commands.conf"
 
 # Open support bundle configuration file
 def openConfFile(i_file):
-  try:
-    with open(i_file) as supportBundleConfFile:
-      lines = filter(None, (line.rstrip() for line in supportBundleConfFile))
-    return lines
-  except IOError:
-    return ([])
+    try:
+        with open(i_file) as supportBundleConfFile:
+            lines = filter(None, (line.rstrip() for line in supportBundleConfFile))
+        return lines
+    except IOError:
+        return []
+
 
 # Create the output file name
 def createOutputFile(procName):
-  fileName = procName + "_support_bundle.log"
-  oldFile = LOG_DIR + fileName
-  cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev"
-  rmFileCmd = "rm -rf " + oldFile
-  print("Making backup of " + oldFile)
-  os.system(cpFileCmd)
-  print("Removing " + oldFile)
-  os.system(rmFileCmd)
-  return fileName
+    fileName = procName + "_support_bundle.log"
+    oldFile = LOG_DIR + fileName
+    cpFileCmd = "cp " + oldFile + " " + oldFile + ".prev"
+    rmFileCmd = "rm -rf " + oldFile
+    print("Making backup of " + oldFile)
+    os.system(cpFileCmd)
+    print("Removing " + oldFile)
+    os.system(rmFileCmd)
+    return fileName
+
 
 # Open the output file for this process
 def openOutputFile(fileName):
-  crt_file_cmd = LOG_DIR + fileName
-  print(crt_file_cmd)
-  try:
-    outputFile = open(crt_file_cmd, "w")
-    return outputFile
-  except IOError:
-    return ()
+    crt_file_cmd = LOG_DIR + fileName
+    print(crt_file_cmd)
+    try:
+        outputFile = open(crt_file_cmd, "w")
+        return outputFile
+    except IOError:
+        return ()
+
 
 # Close the output file for this process
 def closeOutputFile(file):
-  try:
-    file.close()
-    return SUCCESS
-  except IOError:
-    return FAIL
+    try:
+        file.close()
+        return SUCCESS
+    except IOError:
+        return FAIL
+
 
 # Execute the command over vtysh and store in the
 # output file
 def executeCommand(cmd, outputFile):
-  cmd_exec_str = "vtysh -c \"" + cmd + "\" "
-  try:
-    cmd_output = subprocess.check_output(cmd_exec_str, shell=True)
+    cmd_exec_str = 'vtysh -c "' + cmd + '" '
     try:
-      dateTime = datetime.datetime.now()
-      outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
-      outputFile.write(cmd_output)
-      outputFile.write("########################################################\n")
-      outputFile.write('\n')
-    except:
-      print("Writing to ouptut file Failed")
-  except subprocess.CalledProcessError as e:
-    dateTime = datetime.datetime.now()
-    outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
-    outputFile.write(e.output)
-    outputFile.write("########################################################\n")
-    outputFile.write('\n')
-    print("Error:" + e.output)
+        cmd_output = subprocess.check_output(cmd_exec_str, shell=True)
+        try:
+            dateTime = datetime.datetime.now()
+            outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
+            outputFile.write(cmd_output)
+            outputFile.write(
+                "########################################################\n"
+            )
+            outputFile.write("\n")
+        except:
+            print("Writing to ouptut file Failed")
+    except subprocess.CalledProcessError as e:
+        dateTime = datetime.datetime.now()
+        outputFile.write(">>[" + str(dateTime) + "]" + cmd + "\n")
+        outputFile.write(e.output)
+        outputFile.write("########################################################\n")
+        outputFile.write("\n")
+        print("Error:" + e.output)
 
 
 # Process the support bundle configuration file
 # and call appropriate functions
 def processConfFile(lines):
-  for line in lines:
-    if line[0][0] == '#':
-      continue
-    cmd_line = line.split(':')
-    if cmd_line[0] == "PROC_NAME":
-      outputFileName = createOutputFile(cmd_line[1])
-      if outputFileName:
-        print(outputFileName, "created for", cmd_line[1])
-    elif cmd_line[0] == "CMD_LIST_START":
-      outputFile = openOutputFile(outputFileName)
-      if outputFile:
-        print(outputFileName, "opened")
-      else:
-        print(outputFileName, "open failed")
-        return FAIL
-    elif cmd_line[0] == "CMD_LIST_END":
-      if closeOutputFile(outputFile):
-        print(outputFileName, "closed")
-      else:
-        print(outputFileName, "close failed")
-    else:
-      print("Execute:" , cmd_line[0])
-      executeCommand(cmd_line[0], outputFile)
-      
+    for line in lines:
+        if line[0][0] == "#":
+            continue
+        cmd_line = line.split(":")
+        if cmd_line[0] == "PROC_NAME":
+            outputFileName = createOutputFile(cmd_line[1])
+            if outputFileName:
+                print(outputFileName, "created for", cmd_line[1])
+        elif cmd_line[0] == "CMD_LIST_START":
+            outputFile = openOutputFile(outputFileName)
+            if outputFile:
+                print(outputFileName, "opened")
+            else:
+                print(outputFileName, "open failed")
+                return FAIL
+        elif cmd_line[0] == "CMD_LIST_END":
+            if closeOutputFile(outputFile):
+                print(outputFileName, "closed")
+            else:
+                print(outputFileName, "close failed")
+        else:
+            print("Execute:", cmd_line[0])
+            executeCommand(cmd_line[0], outputFile)
+
+
 # Main Function
 lines = openConfFile(inputFile)
 if not lines:
-  print("File support_bundle_commands.conf not present in /etc/frr/ directory")
+    print("File support_bundle_commands.conf not present in /etc/frr/ directory")
 else:
-  processConfFile(lines)
+    processConfFile(lines)
index c207f5946fdf2a99bad26772bf7e089aa8c90539..5f821b06c708c02dc05bd39e6e9831927990f3af 100644 (file)
@@ -5,85 +5,100 @@ import sys, os
 import subprocess, argparse, tempfile
 import indent
 
+
 def run(cmd):
-    proc = subprocess.Popen(cmd, stdout = subprocess.PIPE)
-    rv = proc.communicate('')[0].decode('UTF-8')
+    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+    rv = proc.communicate("")[0].decode("UTF-8")
     proc.wait()
     return rv
 
-clangfmt = run(['git', 'show', 'master:.clang-format'])
 
-argp = argparse.ArgumentParser(description = 'git whitespace-fixing tool')
-argp.add_argument('branch', metavar='BRANCH', type = str, nargs = '?', default = 'HEAD')
+clangfmt = run(["git", "show", "master:.clang-format"])
+
+argp = argparse.ArgumentParser(description="git whitespace-fixing tool")
+argp.add_argument("branch", metavar="BRANCH", type=str, nargs="?", default="HEAD")
 args = argp.parse_args()
 
 branch = args.branch
-commit   = run(['git', 'rev-list', '-n', '1', branch, '--']).strip()
+commit = run(["git", "rev-list", "-n", "1", branch, "--"]).strip()
 
 # frr-3.1-dev = first commit that is on master but not on stable/3.0
-masterid = run(['git', 'rev-list', '-n', '1', 'frr-3.1-dev', '--']).strip()
-masterbase = run(['git', 'merge-base', commit, masterid]).strip()
+masterid = run(["git", "rev-list", "-n", "1", "frr-3.1-dev", "--"]).strip()
+masterbase = run(["git", "merge-base", commit, masterid]).strip()
 
 if masterbase == masterid:
-    refbranch = 'master'
+    refbranch = "master"
 else:
-    refbranch = '3.0'
+    refbranch = "3.0"
 
-sys.stderr.write('autodetected base: %s (can be 3.0 or master)\n' % refbranch)
+sys.stderr.write("autodetected base: %s (can be 3.0 or master)\n" % refbranch)
 
-beforeid = run(['git', 'rev-list', '-n', '1', 'reindent-%s-before' % refbranch, '--']).strip()
-afterid  = run(['git', 'rev-list', '-n', '1', 'reindent-%s-after' % refbranch, '--']).strip()
+beforeid = run(
+    ["git", "rev-list", "-n", "1", "reindent-%s-before" % refbranch, "--"]
+).strip()
+afterid = run(
+    ["git", "rev-list", "-n", "1", "reindent-%s-after" % refbranch, "--"]
+).strip()
 
-beforebase = run(['git', 'merge-base', commit, beforeid]).strip()
-afterbase  = run(['git', 'merge-base', commit, afterid]).strip()
+beforebase = run(["git", "merge-base", commit, beforeid]).strip()
+afterbase = run(["git", "merge-base", commit, afterid]).strip()
 
 if afterbase == afterid:
-    sys.stderr.write('this branch was already rebased\n')
+    sys.stderr.write("this branch was already rebased\n")
     sys.exit(1)
 
 if beforebase != beforeid:
-    sys.stderr.write('you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch)
+    sys.stderr.write(
+        'you need to rebase your branch onto the tag "reindent-%s-before"\n' % refbranch
+    )
     sys.exit(1)
 
-revs = run(['git', 'rev-list', 'reindent-%s-before..%s' % (refbranch, commit)]).strip().split('\n')
+revs = (
+    run(["git", "rev-list", "reindent-%s-before..%s" % (refbranch, commit)])
+    .strip()
+    .split("\n")
+)
 revs.reverse()
 
 srcdir = os.getcwd()
-tmpdir = tempfile.mkdtemp('frrindent')
+tmpdir = tempfile.mkdtemp("frrindent")
 os.chdir(tmpdir)
 
-sys.stderr.write('using temporary directory %s; %d revisions\n' % (tmpdir, len(revs)))
-run(['git', 'clone', '-s', '-b', 'reindent-%s-after' % refbranch, srcdir, 'repo'])
-os.chdir('repo')
+sys.stderr.write("using temporary directory %s; %d revisions\n" % (tmpdir, len(revs)))
+run(["git", "clone", "-s", "-b", "reindent-%s-after" % refbranch, srcdir, "repo"])
+os.chdir("repo")
 
-with open('.clang-format', 'w') as fd:
+with open(".clang-format", "w") as fd:
     fd.write(clangfmt)
 
 prev = beforeid
 for rev in revs:
-    filestat = run(['git', 'diff', '-z', '--name-status', prev, rev]).rstrip('\0').split('\0')
+    filestat = (
+        run(["git", "diff", "-z", "--name-status", prev, rev]).rstrip("\0").split("\0")
+    )
     changes = zip(filestat[0::2], filestat[1::2])
-    sys.stderr.write('%s: %d files\n' % (rev, len(changes)))
+    sys.stderr.write("%s: %d files\n" % (rev, len(changes)))
 
     for typ, name in changes:
-        if typ == 'D':
-            run(['git', 'rm', name])
-        elif typ in ['A', 'M']:
-            run(['git', 'checkout', rev, '--', name])
-            if name.endswith('.c') or name.endswith('.h'):
-                for d in ['babeld/', 'ldpd/', 'nhrpd/']:
+        if typ == "D":
+            run(["git", "rm", name])
+        elif typ in ["A", "M"]:
+            run(["git", "checkout", rev, "--", name])
+            if name.endswith(".c") or name.endswith(".h"):
+                for d in ["babeld/", "ldpd/", "nhrpd/"]:
                     if name.startswith(d):
                         break
                 else:
-                    sys.stderr.write('\t%s\n' % name)
+                    sys.stderr.write("\t%s\n" % name)
                     indent.wrap_file(name)
-            run(['git', 'add', name])
+            run(["git", "add", name])
 
-    run(['git', 'commit', '-C', rev])
+    run(["git", "commit", "-C", rev])
     prev = rev
 
-run(['git', 'push', 'origin', 'HEAD:refs/heads/reindented-branch'])
+run(["git", "push", "origin", "HEAD:refs/heads/reindented-branch"])
 sys.stderr.write('\n\n"reindented-branch" should now be OK.\n')
-sys.stderr.write('you could use "git reset --hard reindented-branch" to set your current branch to the reindented output\n')
-sys.stderr.write('\033[31;1mplease always double-check the output\033[m\n')
-
+sys.stderr.write(
+    'you could use "git reset --hard reindented-branch" to set your current branch to the reindented output\n'
+)
+sys.stderr.write("\033[31;1mplease always double-check the output\033[m\n")
index d2c41e1865df64a0c339d5cf71d264d3e3fe3717..61a0fd4454e819b5515c778b30b39117cecda202 100755 (executable)
@@ -6,42 +6,47 @@ import sys, re, subprocess, os
 
 # find all DEFUNs
 defun_re = re.compile(
-        r'^((DEF(UN(|_ATTR|_CMD_(ELEMENT|FUNC_(DECL|TEXT))|_DEPRECATED|_NOSH|_HIDDEN|SH(|_ATTR|_DEPRECATED|_HIDDEN))?|PY|PY_ATTR|PY_HIDDEN)|ALIAS)\s*\(.*?)^(?=\s*\{)',
-        re.M | re.S)
-define_re = re.compile(
-        r'((^#\s*define[^\n]+[^\\]\n)+)',
-        re.M | re.S)
+    r"^((DEF(UN(|_ATTR|_CMD_(ELEMENT|FUNC_(DECL|TEXT))|_DEPRECATED|_NOSH|_HIDDEN|SH(|_ATTR|_DEPRECATED|_HIDDEN))?|PY|PY_ATTR|PY_HIDDEN)|ALIAS)\s*\(.*?)^(?=\s*\{)",
+    re.M | re.S,
+)
+define_re = re.compile(r"((^#\s*define[^\n]+[^\\]\n)+)", re.M | re.S)
 # find clang-format control that we just inserted
 clean_re = re.compile(
-        r'^.*/\* \$FRR indent\$ \*/\s*\n\s*/\* clang-format (on|off) \*/\s*\n',
-        re.M)
+    r"^.*/\* \$FRR indent\$ \*/\s*\n\s*/\* clang-format (on|off) \*/\s*\n", re.M
+)
+
 
 def wrap_file(fn):
-    with open(fn, 'r') as fd:
+    with open(fn, "r") as fd:
         text = fd.read()
 
-        repl = r'/* $FRR indent$ */\n/* clang-format off */\n' + \
-                r'\1' + \
-                r'/* $FRR indent$ */\n/* clang-format on */\n'
+        repl = (
+            r"/* $FRR indent$ */\n/* clang-format off */\n"
+            + r"\1"
+            + r"/* $FRR indent$ */\n/* clang-format on */\n"
+        )
 
         # around each DEFUN, insert an indent-on/off comment
         text = defun_re.sub(repl, text)
         text = define_re.sub(repl, text)
 
-        ci = subprocess.Popen(['clang-format'], stdin = subprocess.PIPE, stdout = subprocess.PIPE)
+        ci = subprocess.Popen(
+            ["clang-format"], stdin=subprocess.PIPE, stdout=subprocess.PIPE
+        )
         stdout, ign = ci.communicate(text)
         ci.wait()
         if ci.returncode != 0:
-            raise IOError('clang-format returned %d' % (ci.returncode))
+            raise IOError("clang-format returned %d" % (ci.returncode))
 
         # remove the bits we inserted above
-        final = clean_re.sub('', stdout)
+        final = clean_re.sub("", stdout)
 
-        tmpname = fn + '.indent'
-        with open(tmpname, 'w') as ofd:
+        tmpname = fn + ".indent"
+        with open(tmpname, "w") as ofd:
             ofd.write(final)
         os.rename(tmpname, fn)
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     for fn in sys.argv[1:]:
         wrap_file(fn)
index 16c4bbe8a30e0446759a284a5919394d4d2a7861..7636496b62dc547da0dd853458d8cffd7f8c4e5c 100644 (file)
@@ -2,7 +2,7 @@
 # written 2016 by David Lamparter, placed in Public Domain.
 import sys, markdown
 
-template = '''<html><head><meta charset="UTF-8"><style type="text/css">
+template = """<html><head><meta charset="UTF-8"><style type="text/css">
 body { max-width: 45em; margin: auto; margin-top: 2em; margin-bottom: 2em;
     font-family:Fira Sans,sans-serif; text-align: justify;
     counter-reset: ch2; }
@@ -18,11 +18,13 @@ img[alt~="float-right"] { float:right; margin-left:2em; margin-bottom:2em; }
 </style></head><body>
 %s
 </body></html>
-'''
+"""
 
-md = markdown.Markdown(extensions=['extra', 'toc'])
+md = markdown.Markdown(extensions=["extra", "toc"])
 
 for fn in sys.argv[1:]:
-    with open(fn, 'r') as ifd:
-        with open('%s.html' % (fn), 'w') as ofd:
-            ofd.write((template % (md.convert(ifd.read().decode('UTF-8')))).encode('UTF-8'))
+    with open(fn, "r") as ifd:
+        with open("%s.html" % (fn), "w") as ofd:
+            ofd.write(
+                (template % (md.convert(ifd.read().decode("UTF-8")))).encode("UTF-8")
+            )
index a2eb37336a70cc27ae2dd720dab7dc330ced439b..1c75c86a0d7abbf19efbd54d4e09484db1877a1e 100644 (file)
@@ -6,23 +6,24 @@ import re
 import argparse
 
 wrap_res = [
-    (re.compile(r'(?<!\\n)"\s*\n\s*"', re.M),           r''),
+    (re.compile(r'(?<!\\n)"\s*\n\s*"', re.M), r""),
 ]
 pri_res = [
-    (re.compile(r'(PRI[udx][0-9]+)\s*\n\s*"', re.M),    r'\1"'),
-    (re.compile(r'"\s*PRI([udx])32\s*"'),               r'\1'),
-    (re.compile(r'"\s*PRI([udx])32'),                   r'\1"'),
-    (re.compile(r'"\s*PRI([udx])16\s*"'),               r'h\1'),
-    (re.compile(r'"\s*PRI([udx])16'),                   r'h\1"'),
-    (re.compile(r'"\s*PRI([udx])8\s*"'),                r'hh\1'),
-    (re.compile(r'"\s*PRI([udx])8'),                    r'hh\1"'),
+    (re.compile(r'(PRI[udx][0-9]+)\s*\n\s*"', re.M), r'\1"'),
+    (re.compile(r'"\s*PRI([udx])32\s*"'), r"\1"),
+    (re.compile(r'"\s*PRI([udx])32'), r'\1"'),
+    (re.compile(r'"\s*PRI([udx])16\s*"'), r"h\1"),
+    (re.compile(r'"\s*PRI([udx])16'), r'h\1"'),
+    (re.compile(r'"\s*PRI([udx])8\s*"'), r"hh\1"),
+    (re.compile(r'"\s*PRI([udx])8'), r'hh\1"'),
 ]
 
+
 def main():
-    argp = argparse.ArgumentParser(description = 'C string mangler')
-    argp.add_argument('--unwrap', action = 'store_const', const = True)
-    argp.add_argument('--pri8-16-32', action = 'store_const', const = True)
-    argp.add_argument('files', type = str, nargs = '+')
+    argp = argparse.ArgumentParser(description="C string mangler")
+    argp.add_argument("--unwrap", action="store_const", const=True)
+    argp.add_argument("--pri8-16-32", action="store_const", const=True)
+    argp.add_argument("files", type=str, nargs="+")
     args = argp.parse_args()
 
     regexes = []
@@ -31,14 +32,14 @@ def main():
     if args.pri8_16_32:
         regexes.extend(pri_res)
     if len(regexes) == 0:
-        sys.stderr.write('no action selected to execute\n')
+        sys.stderr.write("no action selected to execute\n")
         sys.exit(1)
 
     l = 0
 
     for fn in args.files:
-        sys.stderr.write(fn + '\033[K\r')
-        with open(fn, 'r') as ifd:
+        sys.stderr.write(fn + "\033[K\r")
+        with open(fn, "r") as ifd:
             data = ifd.read()
 
         newdata = data
@@ -48,12 +49,13 @@ def main():
             n += m
 
         if n > 0:
-            sys.stderr.write('changed: %s\n' % fn)
-            with open(fn + '.new', 'w') as ofd:
+            sys.stderr.write("changed: %s\n" % fn)
+            with open(fn + ".new", "w") as ofd:
                 ofd.write(newdata)
-            os.rename(fn + '.new', fn)
+            os.rename(fn + ".new", fn)
             l += 1
 
-    sys.stderr.write('%d files changed.\n' % (l))
+    sys.stderr.write("%d files changed.\n" % (l))
+
 
 main()
index cff21f9f9339e93d1b06db4d454f6170579f37c2..ce0bfde0a50001998c71b9f3727a991b1e2302d1 100755 (executable)
@@ -21,18 +21,40 @@ import sys, os, subprocess
 import re
 from collections import namedtuple
 
-sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'python'))
+sys.path.insert(
+    0,
+    os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "python"),
+)
 
 from makevars import MakeVars
 
-SymRowBase = namedtuple('SymRow', ['target', 'object', 'name', 'address', 'klass', 'typ', 'size', 'line', 'section', 'loc'])
+SymRowBase = namedtuple(
+    "SymRow",
+    [
+        "target",
+        "object",
+        "name",
+        "address",
+        "klass",
+        "typ",
+        "size",
+        "line",
+        "section",
+        "loc",
+    ],
+)
+
+
 class SymRow(SymRowBase):
-    '''
+    """
     wrapper around a line of `nm` output
-    '''
-    lib_re = re.compile(r'/lib[^/]+\.(so|la)$')
+    """
+
+    lib_re = re.compile(r"/lib[^/]+\.(so|la)$")
+
     def is_global(self):
-        return self.klass.isupper() or self.klass in 'uvw'
+        return self.klass.isupper() or self.klass in "uvw"
+
     def scope(self):
         if self.lib_re.search(self.target) is None:
             return self.target
@@ -40,28 +62,29 @@ class SymRow(SymRowBase):
         return None
 
     def is_export(self):
-        '''
+        """
         FRR-specific list of symbols which are considered "externally used"
 
         e.g. hooks are by design APIs for external use, same for qobj_t_*
         frr_inet_ntop is here because it's used through an ELF alias to
         "inet_ntop()"
-        '''
-        if self.name in ['main', 'frr_inet_ntop', '_libfrr_version']:
+        """
+        if self.name in ["main", "frr_inet_ntop", "_libfrr_version"]:
             return True
-        if self.name.startswith('_hook_'):
+        if self.name.startswith("_hook_"):
             return True
-        if self.name.startswith('qobj_t_'):
+        if self.name.startswith("qobj_t_"):
             return True
         return False
 
+
 class Symbols(dict):
-    '''
+    """
     dict of all symbols in all libs & executables
-    '''
+    """
 
-    from_re = re.compile(r'^Symbols from (.*?):$')
-    lt_re = re.compile(r'^(.*/)([^/]+)\.l[oa]$')
+    from_re = re.compile(r"^Symbols from (.*?):$")
+    lt_re = re.compile(r"^(.*/)([^/]+)\.l[oa]$")
 
     def __init__(self):
         super().__init__()
@@ -69,26 +92,35 @@ class Symbols(dict):
     class ReportSym(object):
         def __init__(self, sym):
             self.sym = sym
+
         def __repr__(self):
-            return '<%-25s %-40s [%s]>' % (self.__class__.__name__ + ':', self.sym.name, self.sym.loc)
+            return "<%-25s %-40s [%s]>" % (
+                self.__class__.__name__ + ":",
+                self.sym.name,
+                self.sym.loc,
+            )
+
         def __lt__(self, other):
             return self.sym.name.__lt__(other.sym.name)
 
     class ReportSymCouldBeStaticAlreadyLocal(ReportSym):
-        idshort = 'Z'
-        idlong = 'extrastatic'
+        idshort = "Z"
+        idlong = "extrastatic"
         title = "symbol is local to library, but only used in its source file (make static?)"
+
     class ReportSymCouldBeStatic(ReportSym):
-        idshort = 'S'
-        idlong = 'static'
+        idshort = "S"
+        idlong = "static"
         title = "symbol is only used in its source file (make static?)"
+
     class ReportSymCouldBeLibLocal(ReportSym):
-        idshort = 'L'
-        idlong = 'liblocal'
+        idshort = "L"
+        idlong = "liblocal"
         title = "symbol is only used inside of library"
+
     class ReportSymModuleAPI(ReportSym):
-        idshort = 'A'
-        idlong = 'api'
+        idshort = "A"
+        idlong = "api"
         title = "symbol (in executable) is referenced externally from a module"
 
     class Symbol(object):
@@ -100,31 +132,38 @@ class Symbols(dict):
 
         def process(self, row):
             scope = row.scope()
-            if row.section == '*UND*':
+            if row.section == "*UND*":
                 self.refs.append(row)
             else:
                 self.defs.setdefault(scope, []).append(row)
 
         def evaluate(self, out):
-            '''
+            """
             generate output report
 
             invoked after all object files have been read in, so it can look
             at inter-object-file relationships
-            '''
+            """
             if len(self.defs) == 0:
                 out.extsyms.add(self.name)
                 return
 
             for scopename, symdefs in self.defs.items():
-                common_defs = [symdef for symdef in symdefs if symdef.section == '*COM*']
-                proper_defs = [symdef for symdef in symdefs if symdef.section != '*COM*']
+                common_defs = [
+                    symdef for symdef in symdefs if symdef.section == "*COM*"
+                ]
+                proper_defs = [
+                    symdef for symdef in symdefs if symdef.section != "*COM*"
+                ]
 
                 if len(proper_defs) > 1:
-                    print(self.name, ' DUPLICATE')
-                    print('\tD: %s %s' % (scopename, '\n\t\t'.join([repr(s) for s in symdefs])))
+                    print(self.name, " DUPLICATE")
+                    print(
+                        "\tD: %s %s"
+                        % (scopename, "\n\t\t".join([repr(s) for s in symdefs]))
+                    )
                     for syms in self.refs:
-                        print('\tR: %s' % (syms, ))
+                        print("\tR: %s" % (syms,))
                     return
 
                 if len(proper_defs):
@@ -140,7 +179,9 @@ class Symbols(dict):
 
                 if scopename is not None and len(self.refs) > 0:
                     for ref in self.refs:
-                        if ref.target != primary_def.target and ref.target.endswith('.la'):
+                        if ref.target != primary_def.target and ref.target.endswith(
+                            ".la"
+                        ):
                             outobj = out.report.setdefault(primary_def.object, [])
                             outobj.append(out.ReportSymModuleAPI(primary_def))
                             break
@@ -152,7 +193,9 @@ class Symbols(dict):
                     if primary_def.visible:
                         outobj.append(out.ReportSymCouldBeStatic(primary_def))
                     else:
-                        outobj.append(out.ReportSymCouldBeStaticAlreadyLocal(primary_def))
+                        outobj.append(
+                            out.ReportSymCouldBeStaticAlreadyLocal(primary_def)
+                        )
                     continue
 
                 if scopename is None and primary_def.visible:
@@ -164,7 +207,6 @@ class Symbols(dict):
                         outobj = out.report.setdefault(primary_def.object, [])
                         outobj.append(out.ReportSymCouldBeLibLocal(primary_def))
 
-
     def evaluate(self):
         self.extsyms = set()
         self.report = {}
@@ -177,14 +219,14 @@ class Symbols(dict):
             m = self.lt_re.match(fn)
             if m is None:
                 return fn
-            return m.group(1) + '.libs/' + m.group(2) + '.o'
+            return m.group(1) + ".libs/" + m.group(2) + ".o"
 
         def libtooltargetmustdie(fn):
             m = self.lt_re.match(fn)
             if m is None:
-                a, b = fn.rsplit('/', 1)
-                return '%s/.libs/%s' % (a, b)
-            return m.group(1) + '.libs/' + m.group(2) + '.so'
+                a, b = fn.rsplit("/", 1)
+                return "%s/.libs/%s" % (a, b)
+            return m.group(1) + ".libs/" + m.group(2) + ".so"
 
         files = list(set([libtoolmustdie(fn) for fn in files]))
 
@@ -192,30 +234,30 @@ class Symbols(dict):
             filename = None
             path_rel_to = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
 
-            for line in text.split('\n'):
-                if line.strip() == '':
+            for line in text.split("\n"):
+                if line.strip() == "":
                     continue
                 m = self.from_re.match(line)
                 if m is not None:
                     filename = m.group(1)
                     continue
-                if line.startswith('Name'):
+                if line.startswith("Name"):
                     continue
 
-                items = [i.strip() for i in line.split('|')]
+                items = [i.strip() for i in line.split("|")]
                 loc = None
-                if '\t' in items[-1]:
-                    items[-1], loc = items[-1].split('\t', 1)
-                    fn, lno = loc.rsplit(':', 1)
+                if "\t" in items[-1]:
+                    items[-1], loc = items[-1].split("\t", 1)
+                    fn, lno = loc.rsplit(":", 1)
                     fn = os.path.relpath(fn, path_rel_to)
-                    loc = '%s:%s' % (fn, lno)
+                    loc = "%s:%s" % (fn, lno)
 
-                items[1] = int(items[1] if items[1] != '' else '0', 16)
-                items[4] = int(items[4] if items[4] != '' else '0', 16)
+                items[1] = int(items[1] if items[1] != "" else "0", 16)
+                items[4] = int(items[4] if items[4] != "" else "0", 16)
                 items.append(loc)
                 row = SymRow(target, filename, *items)
 
-                if row.section == '.group' or row.name == '_GLOBAL_OFFSET_TABLE_':
+                if row.section == ".group" or row.name == "_GLOBAL_OFFSET_TABLE_":
                     continue
                 if not row.is_global():
                     continue
@@ -230,14 +272,19 @@ class Symbols(dict):
         # in the linked result (this covers ELF "hidden"/"internal" linkage)
 
         libfile = libtooltargetmustdie(target)
-        nmlib = subprocess.Popen(['nm', '-l', '-g', '--defined-only', '-f', 'sysv', libfile], stdout = subprocess.PIPE)
-        out = nmlib.communicate()[0].decode('US-ASCII')
+        nmlib = subprocess.Popen(
+            ["nm", "-l", "-g", "--defined-only", "-f", "sysv", libfile],
+            stdout=subprocess.PIPE,
+        )
+        out = nmlib.communicate()[0].decode("US-ASCII")
 
         for row in parse_nm_output(out):
             visible_syms.add(row.name)
 
-        nm = subprocess.Popen(['nm', '-l', '-f', 'sysv'] + files, stdout = subprocess.PIPE)
-        out = nm.communicate()[0].decode('US-ASCII')
+        nm = subprocess.Popen(
+            ["nm", "-l", "-f", "sysv"] + files, stdout=subprocess.PIPE
+        )
+        out = nm.communicate()[0].decode("US-ASCII")
 
         for row in parse_nm_output(out):
             row.visible = row.name in visible_syms
@@ -249,95 +296,111 @@ def write_html_report(syms):
     try:
         import jinja2
     except ImportError:
-        sys.stderr.write('jinja2 could not be imported, not writing HTML report!\n')
+        sys.stderr.write("jinja2 could not be imported, not writing HTML report!\n")
         return
 
     self_path = os.path.dirname(os.path.abspath(__file__))
     jenv = jinja2.Environment(loader=jinja2.FileSystemLoader(self_path))
-    template = jenv.get_template('symalyzer.html')
+    template = jenv.get_template("symalyzer.html")
 
     dirgroups = {}
     for fn, reports in syms.report.items():
-        dirname, filename = fn.replace('.libs/', '').rsplit('/', 1)
+        dirname, filename = fn.replace(".libs/", "").rsplit("/", 1)
         dirgroups.setdefault(dirname, {})[fn] = reports
 
     klasses = {
-        'T': 'code / plain old regular function (Text)',
-        'D': 'global variable, read-write, with nonzero initializer (Data)',
-        'B': 'global variable, read-write, with zero initializer (BSS)',
-        'C': 'global variable, read-write, with zero initializer (Common)',
-        'R': 'global variable, read-only (Rodata)',
+        "T": "code / plain old regular function (Text)",
+        "D": "global variable, read-write, with nonzero initializer (Data)",
+        "B": "global variable, read-write, with zero initializer (BSS)",
+        "C": "global variable, read-write, with zero initializer (Common)",
+        "R": "global variable, read-only (Rodata)",
     }
 
-    with open('symalyzer_report.html.tmp', 'w') as fd:
-        fd.write(template.render(dirgroups = dirgroups, klasses = klasses))
-    os.rename('symalyzer_report.html.tmp', 'symalyzer_report.html')
+    with open("symalyzer_report.html.tmp", "w") as fd:
+        fd.write(template.render(dirgroups=dirgroups, klasses=klasses))
+    os.rename("symalyzer_report.html.tmp", "symalyzer_report.html")
 
-    if not os.path.exists('jquery-3.4.1.min.js'):
-        url = 'https://code.jquery.com/jquery-3.4.1.min.js'
+    if not os.path.exists("jquery-3.4.1.min.js"):
+        url = "https://code.jquery.com/jquery-3.4.1.min.js"
         sys.stderr.write(
-            'trying to grab a copy of jquery from %s\nif this fails, please get it manually (the HTML output is done.)\n' % (url))
+            "trying to grab a copy of jquery from %s\nif this fails, please get it manually (the HTML output is done.)\n"
+            % (url)
+        )
         import requests
-        r = requests.get('https://code.jquery.com/jquery-3.4.1.min.js')
+
+        r = requests.get("https://code.jquery.com/jquery-3.4.1.min.js")
         if r.status_code != 200:
-            sys.stderr.write('failed -- please download jquery-3.4.1.min.js and put it next to the HTML report\n')
+            sys.stderr.write(
+                "failed -- please download jquery-3.4.1.min.js and put it next to the HTML report\n"
+            )
         else:
-            with open('jquery-3.4.1.min.js.tmp', 'w') as fd:
+            with open("jquery-3.4.1.min.js.tmp", "w") as fd:
                 fd.write(r.text)
-            os.rename('jquery-3.4.1.min.js.tmp', 'jquery-3.4.1.min.js')
-            sys.stderr.write('done.\n')
+            os.rename("jquery-3.4.1.min.js.tmp", "jquery-3.4.1.min.js")
+            sys.stderr.write("done.\n")
+
 
 def automake_escape(s):
-    return s.replace('.', '_').replace('/', '_')
+    return s.replace(".", "_").replace("/", "_")
 
-if __name__ == '__main__':
+
+if __name__ == "__main__":
     mv = MakeVars()
 
-    if not (os.path.exists('config.version') and os.path.exists('lib/.libs/libfrr.so')):
-        sys.stderr.write('please execute this script in the root directory of an FRR build tree\n')
-        sys.stderr.write('./configure && make need to have completed successfully\n')
+    if not (os.path.exists("config.version") and os.path.exists("lib/.libs/libfrr.so")):
+        sys.stderr.write(
+            "please execute this script in the root directory of an FRR build tree\n"
+        )
+        sys.stderr.write("./configure && make need to have completed successfully\n")
         sys.exit(1)
 
-    amtargets = ['bin_PROGRAMS', 'sbin_PROGRAMS', 'lib_LTLIBRARIES', 'module_LTLIBRARIES']
+    amtargets = [
+        "bin_PROGRAMS",
+        "sbin_PROGRAMS",
+        "lib_LTLIBRARIES",
+        "module_LTLIBRARIES",
+    ]
     targets = []
 
     mv.getvars(amtargets)
     for amtarget in amtargets:
-        targets.extend([item for item in mv[amtarget].strip().split() if item != 'tools/ssd'])
+        targets.extend(
+            [item for item in mv[amtarget].strip().split() if item != "tools/ssd"]
+        )
 
-    mv.getvars(['%s_LDADD' % automake_escape(t) for t in targets])
+    mv.getvars(["%s_LDADD" % automake_escape(t) for t in targets])
     ldobjs = targets[:]
     for t in targets:
-        ldadd = mv['%s_LDADD' % automake_escape(t)].strip().split()
+        ldadd = mv["%s_LDADD" % automake_escape(t)].strip().split()
         for item in ldadd:
-            if item.startswith('-'):
+            if item.startswith("-"):
                 continue
-            if item.endswith('.a'):
+            if item.endswith(".a"):
                 ldobjs.append(item)
 
-    mv.getvars(['%s_OBJECTS' % automake_escape(o) for o in ldobjs])
+    mv.getvars(["%s_OBJECTS" % automake_escape(o) for o in ldobjs])
 
     syms = Symbols()
 
     for t in targets:
-        objs = mv['%s_OBJECTS' % automake_escape(t)].strip().split()
-        ldadd = mv['%s_LDADD' % automake_escape(t)].strip().split()
+        objs = mv["%s_OBJECTS" % automake_escape(t)].strip().split()
+        ldadd = mv["%s_LDADD" % automake_escape(t)].strip().split()
         for item in ldadd:
-            if item.startswith('-'):
+            if item.startswith("-"):
                 continue
-            if item.endswith('.a'):
-                objs.extend(mv['%s_OBJECTS' % automake_escape(item)].strip().split())
+            if item.endswith(".a"):
+                objs.extend(mv["%s_OBJECTS" % automake_escape(item)].strip().split())
 
-        sys.stderr.write('processing %s...\n' % t)
+        sys.stderr.write("processing %s...\n" % t)
         sys.stderr.flush()
-        #print(t, '\n\t', objs)
+        # print(t, '\n\t', objs)
         syms.load(t, objs)
 
     syms.evaluate()
 
     for obj, reports in sorted(syms.report.items()):
-        print('%s:' % obj)
+        print("%s:" % obj)
         for report in reports:
-            print('\t%r' % report)
+            print("\t%r" % report)
 
     write_html_report(syms)
index d3f9b0c7303e5eb5cabf5d9a1ac58161b43d0eb6..7728717e993b1e2d4d106099c145fef92208bb19 100644 (file)
@@ -700,7 +700,6 @@ static int vrrp_master_down_timer_expire(struct thread *thread);
  */
 static int vrrp_bind_to_primary_connected(struct vrrp_router *r)
 {
-       char ipstr[INET6_ADDRSTRLEN];
        struct interface *ifp;
 
        /*
@@ -754,20 +753,15 @@ static int vrrp_bind_to_primary_connected(struct vrrp_router *r)
        if (bind(r->sock_tx, (const struct sockaddr *)&su, sizeof(su)) < 0) {
                zlog_err(
                        VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
-                       "Failed to bind Tx socket to primary IP address %s: %s",
-                       r->vr->vrid, family2str(r->family),
-                       inet_ntop(r->family,
-                                 (const void *)&c->address->u.prefix, ipstr,
-                                 sizeof(ipstr)),
+                       "Failed to bind Tx socket to primary IP address %pFX: %s",
+                       r->vr->vrid, family2str(r->family), c->address,
                        safe_strerror(errno));
                ret = -1;
        } else {
                DEBUGD(&vrrp_dbg_sock,
                       VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
-                      "Bound Tx socket to primary IP address %s",
-                      r->vr->vrid, family2str(r->family),
-                      inet_ntop(r->family, (const void *)&c->address->u.prefix,
-                                ipstr, sizeof(ipstr)));
+                      "Bound Tx socket to primary IP address %pFX",
+                      r->vr->vrid, family2str(r->family), c->address);
        }
 
        return ret;
@@ -1717,7 +1711,6 @@ static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r)
        struct listnode *ln;
        struct connected *c = NULL;
        bool is_v6_ll;
-       char ipbuf[INET6_ADDRSTRLEN];
 
        if (!r->mvl_ifp)
                return;
@@ -1730,12 +1723,10 @@ static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r)
                is_v6_ll = (c->address->family == AF_INET6
                            && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6));
                if (c->address->family == r->family && !is_v6_ll) {
-                       inet_ntop(r->family, &c->address->u.prefix, ipbuf,
-                                 sizeof(ipbuf));
                        DEBUGD(&vrrp_dbg_auto,
                               VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
-                              "Adding %s",
-                              r->vr->vrid, family2str(r->family), ipbuf);
+                              "Adding %pFX",
+                              r->vr->vrid, family2str(r->family), c->address);
                        if (r->family == AF_INET)
                                vrrp_add_ipv4(r->vr, c->address->u.prefix4);
                        else if (r->vr->version == 3)
index 3165ea119af243b45444e1c301ae311e7a521b0d..7d9cea3adc6e05124accace3a321a960cf323923 100644 (file)
@@ -775,8 +775,8 @@ void vrrp_vty_init(void)
 
        install_element(VIEW_NODE, &vrrp_vrid_show_cmd);
        install_element(VIEW_NODE, &vrrp_vrid_show_summary_cmd);
-       install_element(VIEW_NODE, &show_debugging_vrrp_cmd);
-       install_element(VIEW_NODE, &debug_vrrp_cmd);
+       install_element(ENABLE_NODE, &show_debugging_vrrp_cmd);
+       install_element(ENABLE_NODE, &debug_vrrp_cmd);
        install_element(CONFIG_NODE, &debug_vrrp_cmd);
        install_element(CONFIG_NODE, &vrrp_autoconfigure_cmd);
        install_element(CONFIG_NODE, &vrrp_default_cmd);
index a578921df636666c472c2032e8d24d98efcb507c..37a1e4a624bcdf98206dd83e4063e8af21740576 100644 (file)
@@ -56,8 +56,8 @@ static void vrrp_zebra_debug_if_dump_address(struct interface *ifp,
        for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
                struct prefix *p = ifc->address;
 
-               DEBUGD(&vrrp_dbg_zebra, "%s: interface %s address %s %s", func,
-                      ifp->name, inet_ntoa(p->u.prefix4),
+               DEBUGD(&vrrp_dbg_zebra, "%s: interface %s address %pFX %s",
+                      func, ifp->name, p,
                       CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) ? "secondary"
                                                                   : "primary");
        }
index c1a39b8a12a41a08e65eae250cc9f6be9392da2b..118b84407beb97816bf9fe85dc05e7e841b9a95b 100644 (file)
@@ -1,3 +1,4 @@
 vtysh
 vtysh_cmd.c
 extract.pl
+vtysh_daemons.h
index 63610a328750af3ce1ba4fa50f0aa8d21e45f2ad..8a1e71a37dc6bb8e57b902bf45f4a362034eee55 100644 (file)
@@ -40,7 +40,6 @@
 #include "vtysh/vtysh.h"
 #include "vtysh/vtysh_daemons.h"
 #include "log.h"
-#include "bgpd/bgp_vty.h"
 #include "ns.h"
 #include "vrf.h"
 #include "libfrr.h"
@@ -1773,6 +1772,24 @@ DEFUNSH(VTYSH_BGPD, vnc_l2_group, vnc_l2_group_cmd, "vnc l2-group NAME",
        vty->node = BGP_VNC_L2_GROUP_NODE;
        return CMD_SUCCESS;
 }
+
+DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc",
+       "Exit from VNC configuration mode\n")
+{
+       if (vty->node == BGP_VNC_DEFAULTS_NODE
+           || vty->node == BGP_VNC_NVE_GROUP_NODE
+           || vty->node == BGP_VNC_L2_GROUP_NODE)
+               vty->node = BGP_NODE;
+       return CMD_SUCCESS;
+}
+
+DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy",
+       "Exit from VRF policy configuration mode\n")
+{
+       if (vty->node == BGP_VRF_POLICY_NODE)
+               vty->node = BGP_NODE;
+       return CMD_SUCCESS;
+}
 #endif
 #endif /* HAVE_BGPD */
 
@@ -2106,17 +2123,6 @@ DEFUNSH(VTYSH_BGPD, exit_vni, exit_vni_cmd, "exit-vni", "Exit from VNI mode\n")
        return CMD_SUCCESS;
 }
 
-DEFUNSH(VTYSH_BGPD, exit_vnc_config, exit_vnc_config_cmd, "exit-vnc",
-       "Exit from VNC configuration mode\n")
-{
-       if (vty->node == BGP_VNC_DEFAULTS_NODE
-           || vty->node == BGP_VNC_NVE_GROUP_NODE
-           || vty->node == BGP_VNC_L2_GROUP_NODE)
-               vty->node = BGP_NODE;
-       return CMD_SUCCESS;
-
-}
-
 DEFUNSH(VTYSH_BGPD, rpki_exit, rpki_exit_cmd, "exit",
        "Exit current mode and down to previous mode\n")
 {
@@ -2142,14 +2148,6 @@ DEFUNSH(VTYSH_BGPD, bmp_quit, bmp_quit_cmd, "quit",
 {
        return bmp_exit(self, vty, argc, argv);
 }
-
-DEFUNSH(VTYSH_BGPD, exit_vrf_policy, exit_vrf_policy_cmd, "exit-vrf-policy",
-       "Exit from VRF policy configuration mode\n")
-{
-       if (vty->node == BGP_VRF_POLICY_NODE)
-               vty->node = BGP_NODE;
-       return CMD_SUCCESS;
-}
 #endif /* HAVE_BGPD */
 
 DEFUNSH(VTYSH_VRF, exit_vrf_config, exit_vrf_config_cmd, "exit-vrf",
@@ -4272,9 +4270,9 @@ void vtysh_init_vty(void)
 #endif
 
        /* debugging */
-       install_element(VIEW_NODE, &vtysh_show_debugging_cmd);
        install_element(VIEW_NODE, &vtysh_show_error_code_cmd);
-       install_element(VIEW_NODE, &vtysh_show_debugging_hashtable_cmd);
+       install_element(ENABLE_NODE, &vtysh_show_debugging_cmd);
+       install_element(ENABLE_NODE, &vtysh_show_debugging_hashtable_cmd);
        install_element(ENABLE_NODE, &vtysh_debug_all_cmd);
        install_element(CONFIG_NODE, &vtysh_debug_all_cmd);
        install_element(ENABLE_NODE, &vtysh_debug_memstats_cmd);
index d1003ad5fac38785672e54710b57a66daa27b380..319bd6a771f5424a5a266d2b79033e27e05c9ce4 100644 (file)
@@ -409,8 +409,8 @@ static void sigchild(void)
                what = restart->what;
                restart->pid = 0;
                gs.numpids--;
-               thread_cancel(restart->t_kill);
-               restart->t_kill = NULL;
+               thread_cancel(&restart->t_kill);
+
                /* Update restart time to reflect the time the command
                 * completed. */
                gettimeofday(&restart->time, NULL);
@@ -585,8 +585,8 @@ static void restart_done(struct daemon *dmn)
                        dmn->name, state_str[dmn->state]);
                return;
        }
-       if (dmn->t_wakeup)
-               THREAD_OFF(dmn->t_wakeup);
+       THREAD_OFF(dmn->t_wakeup);
+
        if (try_connect(dmn) < 0)
                SET_WAKEUP_DOWN(dmn);
 }
@@ -679,8 +679,7 @@ static int handle_read(struct thread *t_read)
                           dmn->name, (long)delay.tv_sec, (long)delay.tv_usec);
 
        SET_READ_HANDLER(dmn);
-       if (dmn->t_wakeup)
-               thread_cancel(dmn->t_wakeup);
+       thread_cancel(&dmn->t_wakeup);
        SET_WAKEUP_ECHO(dmn);
 
        return 0;
@@ -867,9 +866,8 @@ static int phase_hanging(struct thread *t_hanging)
 static void set_phase(restart_phase_t new_phase)
 {
        gs.phase = new_phase;
-       if (gs.t_phase_hanging)
-               thread_cancel(gs.t_phase_hanging);
-       gs.t_phase_hanging = NULL;
+       thread_cancel(&gs.t_phase_hanging);
+
        thread_add_timer(master, phase_hanging, NULL, PHASE_TIMEOUT,
                         &gs.t_phase_hanging);
 }
index 0a25c93da7cd98db512826fd951dd240ce306616..39bf2bb9226c1a3fb3edf95b0977ced8285727d0 100644 (file)
@@ -19,13 +19,13 @@ if not os.path.isdir(outdir):
 # or python-yang.  Cross-compiling FRR is already somewhat involved, no need
 # to make it even harder.
 
-re_name = re.compile(r'\bmodule\s+([^\s]+)\s+\{')
-re_subname = re.compile(r'\bsubmodule\s+([^\s]+)\s+\{')
-re_mainname = re.compile(r'\bbelongs-to\s+([^\s]+)\s+\{')
-re_rev = re.compile(r'\brevision\s+([\d-]+)\s+\{')
+re_name = re.compile(r"\bmodule\s+([^\s]+)\s+\{")
+re_subname = re.compile(r"\bsubmodule\s+([^\s]+)\s+\{")
+re_mainname = re.compile(r"\bbelongs-to\s+([^\s]+)\s+\{")
+re_rev = re.compile(r"\brevision\s+([\d-]+)\s+\{")
 
 
-template = '''/* autogenerated by embedmodel.py.  DO NOT EDIT */
+template = """/* autogenerated by embedmodel.py.  DO NOT EDIT */
 
 #include <zebra.h>
 #include "yang.h"
@@ -47,23 +47,28 @@ static void embed_register(void)
 {
 \tyang_module_embed(&embed);
 }
-'''
+"""
+
+passchars = set(string.printable) - set("\\'\"%\r\n\t\x0b\x0c")
+
 
-passchars = set(string.printable) - set('\\\'"%\r\n\t\x0b\x0c')
 def escapech(char):
     if char in passchars:
         return char
-    if char == '\n':
-        return '\\n'
-    if char == '\t':
-        return '\\t'
-    if char in '"\\\'':
-        return '\\' + char
-    return '\\x%02x' % (ord(char))
+    if char == "\n":
+        return "\\n"
+    if char == "\t":
+        return "\\t"
+    if char in "\"\\'":
+        return "\\" + char
+    return "\\x%02x" % (ord(char))
+
+
 def escape(line):
-    return ''.join([escapech(i) for i in line])
+    return "".join([escapech(i) for i in line])
+
 
-with open(inname, 'r') as fd:
+with open(inname, "r") as fd:
     data = fd.read()
 
 sub_name = ""
@@ -72,29 +77,33 @@ sub_rev = ""
 
 # XML support isn't actively used currently, but it's here in case the need
 # arises.  It does avoid the regex'ing.
-if '<?xml' in data:
+if "<?xml" in data:
     from xml.etree import ElementTree
+
     xml = ElementTree.fromstring(data)
-    name = xml.get('name')
-    rev = xml.find('{urn:ietf:params:xml:ns:yang:yin:1}revision').get('date')
-    fmt = 'LYS_YIN'
+    name = xml.get("name")
+    rev = xml.find("{urn:ietf:params:xml:ns:yang:yin:1}revision").get("date")
+    fmt = "LYS_YIN"
 else:
     search_name = re_name.search(data)
-    if search_name :
-       name = search_name.group(1)
-       rev = re_rev.search(data).group(1)
-    else :
-       search_name = re_subname.search(data)
-       sub_name = search_name.group(1)
-       name = re_mainname.search(data).group(1)
-       sub_rev = re_rev.search(data).group(1)
-    fmt = 'LYS_YANG'
+    if search_name:
+        name = search_name.group(1)
+        rev = re_rev.search(data).group(1)
+    else:
+        search_name = re_subname.search(data)
+        sub_name = search_name.group(1)
+        name = re_mainname.search(data).group(1)
+        sub_rev = re_rev.search(data).group(1)
+    fmt = "LYS_YANG"
 
 if name is None or rev is None:
-    raise ValueError('cannot determine YANG module name and revision')
+    raise ValueError("cannot determine YANG module name and revision")
 
-lines = [escape(row) for row in data.split('\n')]
+lines = [escape(row) for row in data.split("\n")]
 text = '\\n"\n\t"'.join(lines)
 
-with open(outname, 'w') as fd:
-    fd.write(template % (text, escape(name), escape(rev), escape(sub_name), escape(sub_rev), fmt))
+with open(outname, "w") as fd:
+    fd.write(
+        template
+        % (text, escape(name), escape(rev), escape(sub_name), escape(sub_rev), fmt)
+    )
index 96ec9dc969d11c08d87826efccdcf648db966390..de78758dbb40b2e5cec8ed3002ec3f8512e287a0 100644 (file)
@@ -195,7 +195,7 @@ submodule frr-bgp-common {
 
       leaf external-compare-router-id {
         type boolean;
-        default "true";
+        default "false";
         description
           "When comparing similar routes received from external BGP
            peers, use the router-id as a criterion to select the
@@ -779,6 +779,48 @@ submodule frr-bgp-common {
       description
         "Apply route map to aggregate network.";
     }
+
+    leaf origin {
+      type enumeration {
+        enum "igp" {
+          value 0;
+          description
+            "Local IGP.";
+        }
+        enum "egp" {
+          value 1;
+          description
+            "Remote EGP.";
+        }
+        enum "incomplete" {
+          value 2;
+          description
+            "Unknown heritage.";
+        }
+        enum "unspecified" {
+          value 255;
+          description
+            "Unspecified.";
+        }
+      }
+      default "unspecified";
+      description
+        "BGP origin type.";
+    }
+
+    leaf match-med {
+      type boolean;
+      default "false";
+      description
+        "When set to 'true' aggregate-route matches only
+         med.";
+    }
+
+    leaf suppress-map {
+      type string;
+      description
+        "Suppress more specific routes specified in route-map.";
+    }
   }
 
   grouping admin-distance {
@@ -791,6 +833,7 @@ submodule frr-bgp-common {
         type uint8 {
           range "1..255";
         }
+        default "20";
         description
           "Administrative distance for routes learned from
            external BGP (EBGP).";
@@ -800,6 +843,7 @@ submodule frr-bgp-common {
         type uint8 {
           range "1..255";
         }
+        default "200";
         description
           "Administrative distance for routes learned from
            internal BGP (IBGP).";
@@ -809,6 +853,7 @@ submodule frr-bgp-common {
         type uint8 {
           range "1..255";
         }
+        default "200";
         description
           "Administrative distance for routes learned from
            local.";
@@ -1017,6 +1062,7 @@ submodule frr-bgp-common {
       case import-export {
         uses rt-list;
       }
+
       case both {
         leaf-list rt-list {
           type rt-types:route-target;
@@ -1064,7 +1110,11 @@ submodule frr-bgp-common {
 
   grouping global-afi-safi-vpn-config {
     container vpn-config {
-      uses route-distinguisher-params;
+      leaf rd {
+        type string;
+        description
+          "Route distinguisher value as per RFC4364.";
+      }
 
       uses vpn-label-params;
 
index 3e5b1da7d3dc2a99ed6564b9c73830d3059e4dda..820c4b2861a89805e856daa79bd1b97559cd3f89 100644 (file)
@@ -90,10 +90,10 @@ module frr-bgp {
           "BGP protocol augmentation of ietf-routing module
            control-plane-protocol.";
       }
+      presence "Enables configuration of BGP";
       description
         "Top-level configuration for the BGP router.";
       container global {
-        presence "Enables global configuration of BGP";
         description
           "Global configuration for the BGP router.";
         leaf local-as {
@@ -353,6 +353,8 @@ module frr-bgp {
       uses distance-per-route-config;
     }
 
+    uses route-flap-dampening;
+
     uses mp-afi-unicast-common;
 
     uses global-filter-config;
@@ -362,10 +364,14 @@ module frr-bgp {
 
   augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv4-labeled-unicast" {
     uses global-group-use-multiple-paths;
+
+    uses route-flap-dampening;
   }
 
   augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv6-labeled-unicast" {
     uses global-group-use-multiple-paths;
+
+    uses route-flap-dampening;
   }
 
   augment "/frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/bgp/global/afi-safis/afi-safi/ipv4-multicast" {
@@ -411,6 +417,8 @@ module frr-bgp {
         description
           "IPv4 multicast destination prefix.";
       }
+
+      uses distance-per-route-config;
     }
 
     uses admin-distance;
@@ -463,8 +471,12 @@ module frr-bgp {
         description
           "IPv6 multicast destination prefix.";
       }
+
+      uses distance-per-route-config;
     }
 
+    uses route-flap-dampening;
+
     uses admin-distance;
   }
 
index 1e44c2569eb00fc03f8ddb3c3456cd80c854e97e..400a09317895377f585b8d5a52689630bb2264a1 100644 (file)
@@ -158,9 +158,17 @@ module frr-filter {
                   description "Host to match";
                   type inet:ipv4-address;
                 }
-                leaf network {
-                  description "Network to match";
-                  type inet:ipv4-prefix;
+                container network {
+                  leaf address {
+                    mandatory true;
+                    description "Network address part.";
+                    type inet:ipv4-address;
+                  }
+                  leaf mask {
+                    mandatory true;
+                    description "Network mask/wildcard part.";
+                    type inet:ipv4-address;
+                  }
                 }
                 leaf source-any {
                   /*
@@ -178,9 +186,17 @@ module frr-filter {
                     description "Host to match";
                     type inet:ipv4-address;
                   }
-                  leaf destination-network {
-                    description "Network to match";
-                    type inet:ipv4-prefix;
+                  container destination-network {
+                    leaf address {
+                      mandatory true;
+                      description "Network address part.";
+                      type inet:ipv4-address;
+                    }
+                    leaf mask {
+                      mandatory true;
+                      description "Network mask/wildcard part.";
+                      type inet:ipv4-address;
+                    }
                   }
                   leaf destination-any {
                     description "Match any";
index 79941a50e7d15b0507b53652260f3015b4ed9ad2..c3b39e3750800e1ead3a60c75e6e47093187e1d0 100644 (file)
@@ -336,6 +336,26 @@ module frr-isisd {
     }
   }
 
+  grouping interface-config-ti-lfa {
+    container ti-lfa {
+      description
+        "TI-LFA configuration.";
+      leaf enable {
+        type boolean;
+        default false;
+        description
+          "Enables TI-LFA computation.";
+      }
+      leaf node-protection {
+        type boolean;
+        must ". = 'false' or ../enable = 'true'";
+        default false;
+        description
+          "Node protection is provided by the alternate.";
+      }
+    }
+  }
+
   grouping interface-config {
     description
       "Interface configuration grouping";
@@ -638,6 +658,20 @@ module frr-isisd {
       }
     }
 
+    container fast-reroute {
+      description
+        "Interface IP Fast-reroute configuration.";
+      container level-1 {
+        description
+          "Level-1 IP Fast-reroute configuration.";
+        uses interface-config-ti-lfa;
+      }
+      container level-2 {
+        description
+          "Level-2 IP Fast-reroute configuration.";
+        uses interface-config-ti-lfa;
+      }
+    }
   }
 
   grouping adjacency-state {
@@ -1347,6 +1381,12 @@ module frr-isisd {
               description
                 "Configure last hop behavior.";
             }
+            leaf n-flag-clear {
+              type boolean;
+              default "false";
+              description
+                "Not a node SID";
+            }
           }
         }
       }
index 52155dcd1664796ace6c7bc2f691d1c4b35b1b08..619514de7d4b2e50a8981f4c006fa7160dd20345 100644 (file)
@@ -275,7 +275,7 @@ module frr-nexthop {
       description
         "List of nexthop groups, each contains group of nexthops";
       leaf name {
-        type nexthop-group-ref;
+        type string;
         description
           "The nexthop-group name.";
       }
index 057c32a7e7c4fb122a84992fc5d150844f42c51d..5a0f58071fd88dd0f7d388b9cb72fdef992cae9a 100644 (file)
@@ -76,6 +76,9 @@ module frr-route-types {
       enum vnc {
         value 17;
       }
+      enum vnc-direct {
+        value 18;
+      }
       enum babel {
         value 22;
       }
@@ -120,6 +123,9 @@ module frr-route-types {
       enum vnc {
         value 17;
       }
+      enum vnc-direct {
+        value 18;
+      }
       enum babel {
         value 22;
       }
index 6aae0e470104d2453adcdcf74965ebba5a01927e..5be93dc4e9967664b1d08187af40a9c3b4d24697 100644 (file)
@@ -30,6 +30,7 @@ dist_yangmodels_DATA += yang/frr-route-types.yang
 dist_yangmodels_DATA += yang/frr-routing.yang
 dist_yangmodels_DATA += yang/ietf/ietf-routing-types.yang
 dist_yangmodels_DATA += yang/ietf/ietf-interfaces.yang
+dist_yangmodels_DATA += yang/ietf/ietf-bgp-types.yang
 
 if BFDD
 dist_yangmodels_DATA += yang/frr-bfdd.yang
@@ -68,3 +69,16 @@ dist_yangmodels_DATA += yang/frr-igmp.yang
 dist_yangmodels_DATA += yang/frr-pim.yang
 dist_yangmodels_DATA += yang/frr-pim-rp.yang
 endif
+
+if BGPD
+dist_yangmodels_DATA += yang/frr-bgp-common-structure.yang
+dist_yangmodels_DATA += yang/frr-bgp-common.yang
+dist_yangmodels_DATA += yang/frr-bgp-common-multiprotocol.yang
+dist_yangmodels_DATA += yang/frr-bgp-neighbor.yang
+dist_yangmodels_DATA += yang/frr-bgp-peer-group.yang
+dist_yangmodels_DATA += yang/frr-deviations-bgp-datacenter.yang
+dist_yangmodels_DATA += yang/frr-bgp-rpki.yang
+dist_yangmodels_DATA += yang/frr-bgp-bmp.yang
+dist_yangmodels_DATA += yang/frr-bgp-types.yang
+dist_yangmodels_DATA += yang/frr-bgp.yang
+endif
index 8c4ba163bdfb475cfeb0b33afd7bb8d67ea7a7d8..6a1efc3e65d4cc168262fe7a60eb2271c27a7d59 100644 (file)
@@ -259,14 +259,10 @@ void connected_up(struct interface *ifp, struct connected *ifc)
 
        /* Schedule LSP forwarding entries for processing, if appropriate. */
        if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
-               if (IS_ZEBRA_DEBUG_MPLS) {
-                       char buf[PREFIX_STRLEN];
-
+               if (IS_ZEBRA_DEBUG_MPLS)
                        zlog_debug(
-                               "%u: IF %s IP %s address add/up, scheduling MPLS processing",
-                               zvrf->vrf->vrf_id, ifp->name,
-                               prefix2str(&p, buf, sizeof(buf)));
-               }
+                               "%u: IF %s IP %pFX address add/up, scheduling MPLS processing",
+                               zvrf->vrf->vrf_id, ifp->name, &p);
                mpls_mark_lsps_for_processing(zvrf, &p);
        }
 }
@@ -312,8 +308,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
                        if (IPV4_ADDR_SAME(addr, dest))
                                flog_warn(
                                        EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
-                                       "warning: interface %s has same local and peer address %s, routing protocols may malfunction",
-                                       ifp->name, inet_ntoa(*addr));
+                                       "warning: interface %s has same local and peer address %pI4, routing protocols may malfunction",
+                                       ifp->name, addr);
                } else {
                        zlog_debug(
                                "warning: %s called for interface %s with peer flag set, but no peer address supplied",
@@ -326,8 +322,8 @@ void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
        if (!dest && (prefixlen == IPV4_MAX_PREFIXLEN)
                && if_is_pointopoint(ifp))
                zlog_debug(
-                       "warning: PtP interface %s with addr %s/%d needs a peer address",
-                       ifp->name, inet_ntoa(*addr), prefixlen);
+                       "warning: PtP interface %s with addr %pI4/%d needs a peer address",
+                       ifp->name, addr, prefixlen);
 
        /* Label of this address. */
        if (label)
@@ -400,14 +396,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)
 
        /* Schedule LSP forwarding entries for processing, if appropriate. */
        if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
-               if (IS_ZEBRA_DEBUG_MPLS) {
-                       char buf[PREFIX_STRLEN];
-
+               if (IS_ZEBRA_DEBUG_MPLS)
                        zlog_debug(
-                               "%u: IF %s IP %s address down, scheduling MPLS processing",
-                               zvrf->vrf->vrf_id, ifp->name,
-                               prefix2str(&p, buf, sizeof(buf)));
-               }
+                               "%u: IF %s IP %pFX address down, scheduling MPLS processing",
+                               zvrf->vrf->vrf_id, ifp->name, &p);
                mpls_mark_lsps_for_processing(zvrf, &p);
        }
 }
@@ -424,14 +416,10 @@ static void connected_delete_helper(struct connected *ifc, struct prefix *p)
 
        /* Schedule LSP forwarding entries for processing, if appropriate. */
        if (ifp->vrf_id == VRF_DEFAULT) {
-               if (IS_ZEBRA_DEBUG_MPLS) {
-                       char buf[PREFIX_STRLEN];
-
+               if (IS_ZEBRA_DEBUG_MPLS)
                        zlog_debug(
-                               "%u: IF %s IP %s address delete, scheduling MPLS processing",
-                               ifp->vrf_id, ifp->name,
-                               prefix2str(p, buf, sizeof(buf)));
-               }
+                               "%u: IF %s IP %pFX address delete, scheduling MPLS processing",
+                               ifp->vrf_id, ifp->name, p);
                mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p);
        }
 }
index 8c53ab73e4a35a3889b772f7c305c65d429d4e5e..87a10ea65df606c66b08eed2d4949d1404cff94b 100644 (file)
@@ -671,7 +671,7 @@ void zebra_debug_init(void)
 
        install_node(&debug_node);
 
-       install_element(VIEW_NODE, &show_debugging_zebra_cmd);
+       install_element(ENABLE_NODE, &show_debugging_zebra_cmd);
 
        install_element(ENABLE_NODE, &debug_zebra_events_cmd);
        install_element(ENABLE_NODE, &debug_zebra_nht_cmd);
index 90a08bbd6c4d897154f4945705be465739a57cc3..a68873882d58027ededa8e7b8d51c40bb28bda78 100644 (file)
@@ -691,6 +691,36 @@ static int netlink_bridge_interface(struct nlmsghdr *h, int len, ns_id_t ns_id,
        return 0;
 }
 
+/* If the interface is and es bond member then it must follow EVPN's
+ * protodown setting
+ */
+static void netlink_proc_dplane_if_protodown(struct zebra_if *zif,
+                                            bool protodown)
+{
+       bool zif_protodown;
+
+       zif_protodown = !!(zif->flags & ZIF_FLAG_PROTODOWN);
+       if (protodown == zif_protodown)
+               return;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+               zlog_debug("interface %s dplane change, protdown %s",
+                          zif->ifp->name, protodown ? "on" : "off");
+
+       if (zebra_evpn_is_es_bond_member(zif->ifp)) {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+                       zlog_debug(
+                               "bond mbr %s re-instate protdown %s in the dplane",
+                               zif->ifp->name, zif_protodown ? "on" : "off");
+               netlink_protodown(zif->ifp, zif_protodown);
+       } else {
+               if (protodown)
+                       zif->flags |= ZIF_FLAG_PROTODOWN;
+               else
+                       zif->flags &= ~ZIF_FLAG_PROTODOWN;
+       }
+}
+
 /*
  * Called from interface_lookup_netlink().  This function is only used
  * during bootstrap.
@@ -849,11 +879,20 @@ static int netlink_interface(struct nlmsghdr *h, ns_id_t ns_id, int startup)
         */
        netlink_interface_update_l2info(ifp, linkinfo[IFLA_INFO_DATA],
                                        1, link_nsid);
+       if (IS_ZEBRA_IF_BOND(ifp))
+               zebra_l2if_update_bond(ifp, true);
        if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp))
                zebra_l2if_update_bridge_slave(ifp, bridge_ifindex, ns_id);
        else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
                zebra_l2if_update_bond_slave(ifp, bond_ifindex);
 
+       if (tb[IFLA_PROTO_DOWN]) {
+               uint8_t protodown;
+
+               protodown = *(uint8_t *)RTA_DATA(tb[IFLA_PROTO_DOWN]);
+               netlink_proc_dplane_if_protodown(zif, !!protodown);
+       }
+
        return 0;
 }
 
@@ -1284,6 +1323,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        uint8_t old_hw_addr[INTERFACE_HWADDR_MAX];
        struct zebra_if *zif;
        ns_id_t link_nsid = ns_id;
+       ifindex_t master_infindex = IFINDEX_INTERNAL;
 
        zns = zebra_ns_lookup(ns_id);
        ifi = NLMSG_DATA(h);
@@ -1373,16 +1413,17 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                        if (slave_kind && (strcmp(slave_kind, "vrf") == 0)
                            && !vrf_is_backend_netns()) {
                                zif_slave_type = ZEBRA_IF_SLAVE_VRF;
-                               vrf_id = *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]);
+                               master_infindex = vrf_id =
+                                       *(uint32_t *)RTA_DATA(tb[IFLA_MASTER]);
                        } else if (slave_kind
                                   && (strcmp(slave_kind, "bridge") == 0)) {
                                zif_slave_type = ZEBRA_IF_SLAVE_BRIDGE;
-                               bridge_ifindex =
+                               master_infindex = bridge_ifindex =
                                        *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
                        } else if (slave_kind
                                   && (strcmp(slave_kind, "bond") == 0)) {
                                zif_slave_type = ZEBRA_IF_SLAVE_BOND;
-                               bond_ifindex =
+                               master_infindex = bond_ifindex =
                                        *(ifindex_t *)RTA_DATA(tb[IFLA_MASTER]);
                        } else
                                zif_slave_type = ZEBRA_IF_SLAVE_OTHER;
@@ -1396,7 +1437,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                zlog_debug(
                                        "RTM_NEWLINK ADD for %s(%u) vrf_id %u type %d sl_type %d master %u flags 0x%x",
                                        name, ifi->ifi_index, vrf_id, zif_type,
-                                       zif_slave_type, bridge_ifindex,
+                                       zif_slave_type, master_infindex,
                                        ifi->ifi_flags);
 
                        if (ifp == NULL) {
@@ -1446,6 +1487,15 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                                               ns_id);
                        else if (IS_ZEBRA_IF_BOND_SLAVE(ifp))
                                zebra_l2if_update_bond_slave(ifp, bond_ifindex);
+
+                       if (tb[IFLA_PROTO_DOWN]) {
+                               uint8_t protodown;
+
+                               protodown = *(uint8_t *)RTA_DATA(
+                                       tb[IFLA_PROTO_DOWN]);
+                               netlink_proc_dplane_if_protodown(ifp->info,
+                                                                !!protodown);
+                       }
                } else if (ifp->vrf_id != vrf_id) {
                        /* VRF change for an interface. */
                        if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1463,7 +1513,7 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                                zlog_debug(
                                        "RTM_NEWLINK update for %s(%u) sl_type %d master %u flags 0x%x",
                                        name, ifp->ifindex, zif_slave_type,
-                                       bridge_ifindex, ifi->ifi_flags);
+                                       master_infindex, ifi->ifi_flags);
 
                        set_ifindex(ifp, ifi->ifi_index, zns);
                        if (!tb[IFLA_MTU]) {
@@ -1542,12 +1592,23 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                        netlink_interface_update_l2info(
                                ifp, linkinfo[IFLA_INFO_DATA],
                                0, link_nsid);
+                       if (IS_ZEBRA_IF_BOND(ifp))
+                               zebra_l2if_update_bond(ifp, true);
                        if (IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) || was_bridge_slave)
                                zebra_l2if_update_bridge_slave(ifp,
                                                               bridge_ifindex,
                                                               ns_id);
                        else if (IS_ZEBRA_IF_BOND_SLAVE(ifp) || was_bond_slave)
                                zebra_l2if_update_bond_slave(ifp, bond_ifindex);
+
+                       if (tb[IFLA_PROTO_DOWN]) {
+                               uint8_t protodown;
+
+                               protodown = *(uint8_t *)RTA_DATA(
+                                       tb[IFLA_PROTO_DOWN]);
+                               netlink_proc_dplane_if_protodown(ifp->info,
+                                                                !!protodown);
+                       }
                }
 
                zif = ifp->info;
@@ -1572,6 +1633,8 @@ int netlink_link_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
 
                UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK);
 
+               if (IS_ZEBRA_IF_BOND(ifp))
+                       zebra_l2if_update_bond(ifp, false);
                /* Special handling for bridge or VxLAN interfaces. */
                if (IS_ZEBRA_IF_BRIDGE(ifp))
                        zebra_l2_bridge_del(ifp);
index 321085580155db88f52777bd2d15a4c6b96c3ef0..ddad9c9e56e3d89da8c21a6dba01daba211b2706 100644 (file)
@@ -1069,6 +1069,9 @@ void if_up(struct interface *ifp)
 
        if (zif->es_info.es)
                zebra_evpn_es_if_oper_state_change(zif, true /*up*/);
+
+       if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
+               zebra_evpn_mh_uplink_oper_update(zif);
 }
 
 /* Interface goes down.  We have to manage different behavior of based
@@ -1106,6 +1109,9 @@ void if_down(struct interface *ifp)
        if (zif->es_info.es)
                zebra_evpn_es_if_oper_state_change(zif, false /*up*/);
 
+       if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
+               zebra_evpn_mh_uplink_oper_update(zif);
+
        /* Notify to the protocol daemons. */
        zebra_interface_down_update(ifp);
 
@@ -1156,6 +1162,18 @@ void zebra_if_update_all_links(void)
                if (!ifp)
                        continue;
                zif = ifp->info;
+               /* update bond-member to bond linkages */
+               if ((IS_ZEBRA_IF_BOND_SLAVE(ifp))
+                   && (zif->bondslave_info.bond_ifindex != IFINDEX_INTERNAL)
+                   && !zif->bondslave_info.bond_if) {
+                       if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_KERNEL)
+                               zlog_debug("bond mbr %s map to bond %d",
+                                          zif->ifp->name,
+                                          zif->bondslave_info.bond_ifindex);
+                       zebra_l2_map_slave_to_bond(zif, ifp->vrf_id);
+               }
+
+               /* update SVI linkages */
                if ((zif->link_ifindex != IFINDEX_INTERNAL) && !zif->link) {
                        zif->link = if_lookup_by_index_per_ns(ns,
                                                         zif->link_ifindex);
@@ -1296,8 +1314,6 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
        bool print_header = true;
 
        FOR_ALL_INTERFACES (vrf, ifp) {
-               char global_pfx[PREFIX_STRLEN] = {0};
-               char buf[PREFIX_STRLEN] = {0};
                bool first_pfx_printed = false;
 
                if (print_header) {
@@ -1329,17 +1345,17 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
                                if (!CHECK_FLAG(connected->flags,
                                                ZEBRA_IFA_SECONDARY)) {
                                        p = connected->address;
-                                       prefix2str(p, buf, sizeof(buf));
                                        if (first_pfx_printed) {
-                                               /* padding to prepare row only for ip addr */
+                                               /* padding to prepare row only
+                                                * for ip addr */
                                                vty_out(vty, "%-40s", "");
                                                if (list_size > 1)
                                                        vty_out(vty, "+ ");
-                                               vty_out(vty, "%s\n", buf);
+                                               vty_out(vty, "%pFX\n", p);
                                        } else {
                                                if (list_size > 1)
                                                        vty_out(vty, "+ ");
-                                               vty_out(vty, "%s\n", buf);
+                                               vty_out(vty, "%pFX\n", p);
                                        }
                                        first_pfx_printed = true;
                                        break;
@@ -1361,17 +1377,17 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
                                p = connected->address;
                                /* Don't print link local pfx */
                                if (!IN6_IS_ADDR_LINKLOCAL(&p->u.prefix6)) {
-                                       prefix2str(p, global_pfx, PREFIX_STRLEN);
                                        if (first_pfx_printed) {
-                                               /* padding to prepare row only for ip addr */
+                                               /* padding to prepare row only
+                                                * for ip addr */
                                                vty_out(vty, "%-40s", "");
                                                if (v6_list_size > 1)
                                                        vty_out(vty, "+ ");
-                                               vty_out(vty, "%s\n", global_pfx);
+                                               vty_out(vty, "%pFX\n", p);
                                        } else {
                                                if (v6_list_size > 1)
                                                        vty_out(vty, "+ ");
-                                               vty_out(vty, "%s\n", global_pfx);
+                                               vty_out(vty, "%pFX\n", p);
                                        }
                                        first_pfx_printed = true;
                                        break;
@@ -1384,6 +1400,34 @@ static void ifs_dump_brief_vty(struct vty *vty, struct vrf *vrf)
        vty_out(vty, "\n");
 }
 
+const char *zebra_protodown_rc_str(enum protodown_reasons protodown_rc,
+                                  char *pd_buf, uint32_t pd_buf_len)
+{
+       bool first = true;
+
+       pd_buf[0] = '\0';
+
+       strlcat(pd_buf, "(", pd_buf_len);
+
+       if (protodown_rc & ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY) {
+               if (first)
+                       first = false;
+               else
+                       strlcat(pd_buf, ",", pd_buf_len);
+               strlcat(pd_buf, "startup-delay", pd_buf_len);
+       }
+
+       if (protodown_rc & ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN) {
+               if (!first)
+                       strlcat(pd_buf, ",", pd_buf_len);
+               strlcat(pd_buf, "uplinks-down", pd_buf_len);
+       }
+
+       strlcat(pd_buf, ")", pd_buf_len);
+
+       return pd_buf;
+}
+
 /* Interface's information print out to vty interface. */
 static void if_dump_vty(struct vty *vty, struct interface *ifp)
 {
@@ -1393,6 +1437,7 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
        struct route_node *rn;
        struct zebra_if *zebra_if;
        struct vrf *vrf;
+       char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
 
        zebra_if = ifp->info;
 
@@ -1496,14 +1541,14 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
                vxlan_info = &zebra_if->l2info.vxl;
                vty_out(vty, "  VxLAN Id %u", vxlan_info->vni);
                if (vxlan_info->vtep_ip.s_addr != INADDR_ANY)
-                       vty_out(vty, " VTEP IP: %s",
-                               inet_ntoa(vxlan_info->vtep_ip));
+                       vty_out(vty, " VTEP IP: %pI4",
+                               &vxlan_info->vtep_ip);
                if (vxlan_info->access_vlan)
                        vty_out(vty, " Access VLAN Id %u\n",
                                vxlan_info->access_vlan);
                if (vxlan_info->mcast_grp.s_addr != INADDR_ANY)
-                       vty_out(vty, "  Mcast Group %s",
-                                       inet_ntoa(vxlan_info->mcast_grp));
+                       vty_out(vty, "  Mcast Group %pI4",
+                                       &vxlan_info->mcast_grp);
                if (vxlan_info->ifindex_link &&
                    (vxlan_info->link_nsid != NS_UNKNOWN)) {
                                struct interface *ifp;
@@ -1547,6 +1592,14 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
        }
 
        zebra_evpn_if_es_print(vty, zebra_if);
+       vty_out(vty, "  protodown: %s",
+               (zebra_if->flags & ZIF_FLAG_PROTODOWN) ? "on" : "off");
+       if (zebra_if->protodown_rc)
+               vty_out(vty, " rc: %s\n",
+                       zebra_protodown_rc_str(zebra_if->protodown_rc, pd_buf,
+                                              sizeof(pd_buf)));
+       else
+               vty_out(vty, "\n");
 
        if (zebra_if->link_ifindex != IFINDEX_INTERNAL) {
                if (zebra_if->link)
@@ -1609,8 +1662,8 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
                        vty_out(vty, "    Utilized Bandwidth %g (Byte/s)\n",
                                iflp->use_bw);
                if (IS_PARAM_SET(iflp, LP_RMT_AS))
-                       vty_out(vty, "    Neighbor ASBR IP: %s AS: %u \n",
-                               inet_ntoa(iflp->rmt_ip), iflp->rmt_as);
+                       vty_out(vty, "    Neighbor ASBR IP: %pI4 AS: %u \n",
+                               &iflp->rmt_ip, iflp->rmt_as);
        }
 
        hook_call(zebra_if_extra_info, vty, ifp);
@@ -3498,7 +3551,7 @@ static int link_params_config_write(struct vty *vty, struct interface *ifp)
        if (IS_PARAM_SET(iflp, LP_USE_BW))
                vty_out(vty, "  use-bw %g\n", iflp->use_bw);
        if (IS_PARAM_SET(iflp, LP_RMT_AS))
-               vty_out(vty, "  neighbor %s as %u\n", inet_ntoa(iflp->rmt_ip),
+               vty_out(vty, "  neighbor %pI4 as %u\n", &iflp->rmt_ip,
                        iflp->rmt_as);
        vty_out(vty, "  exit-link-params\n");
        return 0;
index 626225836e0e802172f1da607a622bd4e7af0893..ab1a245e5e164a0c31b0f1e5269c47682e441968 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "zebra/zebra_l2.h"
 #include "zebra/zebra_nhg_private.h"
+#include "zebra/zebra_router.h"
 
 #ifdef __cplusplus
 extern "C" {
@@ -280,14 +281,28 @@ struct zebra_evpn_es;
 struct zebra_es_if_info {
        struct ethaddr sysmac;
        uint32_t lid; /* local-id; has to be unique per-ES-sysmac */
+       uint16_t df_pref;
        struct zebra_evpn_es *es; /* local ES */
 };
 
+enum zebra_if_flags {
+       /* device has been configured as an uplink for
+        * EVPN multihoming
+        */
+       ZIF_FLAG_EVPN_MH_UPLINK = (1 << 0),
+       ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP = (1 << 1),
+
+       /* Dataplane protodown-on */
+       ZIF_FLAG_PROTODOWN = (1 << 2)
+};
+
 /* `zebra' daemon local interface structure. */
 struct zebra_if {
        /* back pointer to the interface */
        struct interface *ifp;
 
+       enum zebra_if_flags flags;
+
        /* Shutdown configuration. */
        uint8_t shutdown;
 
@@ -351,6 +366,7 @@ struct zebra_if {
        struct zebra_l2info_brslave brslave_info;
 
        struct zebra_l2info_bondslave bondslave_info;
+       struct zebra_l2info_bond bond_info;
 
        /* ethernet segment */
        struct zebra_es_if_info es_info;
@@ -358,6 +374,14 @@ struct zebra_if {
        /* bitmap of vlans associated with this interface */
        bitfield_t vlan_bitmap;
 
+       /* An interface can be error-disabled if a protocol (such as EVPN or
+        * VRRP) detects a problem with keeping it operationally-up.
+        * If any of the protodown bits are set protodown-on is programmed
+        * in the dataplane. This results in a carrier/L1 down on the
+        * physical device.
+        */
+       enum protodown_reasons protodown_rc;
+
        /* Link fields - for sub-interfaces. */
        ifindex_t link_ifindex;
        struct interface *link;
@@ -399,6 +423,9 @@ DECLARE_HOOK(zebra_if_config_wr, (struct vty * vty, struct interface *ifp),
 #define IS_ZEBRA_IF_VETH(ifp)                                               \
        (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_VETH)
 
+#define IS_ZEBRA_IF_BOND(ifp)                                                  \
+       (((struct zebra_if *)(ifp->info))->zif_type == ZEBRA_IF_BOND)
+
 #define IS_ZEBRA_IF_BRIDGE_SLAVE(ifp)                                  \
        (((struct zebra_if *)(ifp->info))->zif_slave_type                      \
         == ZEBRA_IF_SLAVE_BRIDGE)
@@ -462,6 +489,10 @@ extern unsigned int if_nhg_dependents_count(const struct interface *ifp);
 extern bool if_nhg_dependents_is_empty(const struct interface *ifp);
 
 extern void vrf_add_update(struct vrf *vrfp);
+extern void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf);
+extern void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif);
+extern const char *zebra_protodown_rc_str(enum protodown_reasons protodown_rc,
+                                         char *pd_buf, uint32_t pd_buf_len);
 
 #ifdef HAVE_PROC_NET_DEV
 extern void ifstat_update_proc(void);
index 11b252fc18e60c891ef0666a9b0f2feb512f562b..42a5bfd9db426f68476013ef1e68fcd0ecb0c86e 100644 (file)
@@ -411,47 +411,91 @@ void if_get_flags(struct interface *ifp)
 {
        int ret;
        struct ifreq ifreq;
-#ifdef HAVE_BSD_LINK_DETECT
-       struct ifmediareq ifmr;
-#endif /* HAVE_BSD_LINK_DETECT */
 
        ifreq_set_name(&ifreq, ifp);
 
        ret = vrf_if_ioctl(SIOCGIFFLAGS, (caddr_t)&ifreq, ifp->vrf_id);
        if (ret < 0) {
                flog_err_sys(EC_LIB_SYSTEM_CALL,
-                            "vrf_if_ioctl(SIOCGIFFLAGS) failed: %s",
-                            safe_strerror(errno));
+                            "vrf_if_ioctl(SIOCGIFFLAGS %s) failed: %s",
+                            ifp->name, safe_strerror(errno));
                return;
        }
-#ifdef HAVE_BSD_LINK_DETECT /* Detect BSD link-state at start-up */
 
-       /* Per-default, IFF_RUNNING is held high, unless link-detect says
-        * otherwise - we abuse IFF_RUNNING inside zebra as a link-state flag,
-        * following practice on Linux and Solaris kernels
+       if (!CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
+               goto out;
+
+       /* Per-default, IFF_RUNNING is held high, unless link-detect
+        * says otherwise - we abuse IFF_RUNNING inside zebra as a
+        * link-state flag, following practice on Linux and Solaris
+        * kernels
+        */
+
+#ifdef SIOCGIFDATA
+       /*
+        * BSD gets link state from ifi_link_link in struct if_data.
+        * All BSD's have this in getifaddrs(3) ifa_data for AF_LINK
+        * addresses. We can also access it via SIOCGIFDATA.
+        */
+
+#ifdef __NetBSD__
+       struct ifdatareq ifdr = {.ifdr_data.ifi_link_state = 0};
+       struct if_data *ifdata = &ifdr.ifdr_data;
+
+       strlcpy(ifdr.ifdr_name, ifp->name, sizeof(ifdr.ifdr_name));
+       ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifdr, ifp->vrf_id);
+#else
+       struct if_data ifd = {.ifi_link_state = 0};
+       struct if_data *ifdata = &ifd;
+
+       ifreq.ifr_data = (caddr_t)ifdata;
+       ret = vrf_if_ioctl(SIOCGIFDATA, (caddr_t)&ifreq, ifp->vrf_id);
+#endif
+
+       if (ret == -1)
+               /* Very unlikely. Did the interface disappear? */
+               flog_err_sys(EC_LIB_SYSTEM_CALL,
+                            "if_ioctl(SIOCGIFDATA %s) failed: %s", ifp->name,
+                            safe_strerror(errno));
+       else {
+               if (ifdata->ifi_link_state >= LINK_STATE_UP)
+                       SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+               else if (ifdata->ifi_link_state == LINK_STATE_UNKNOWN)
+                       /* BSD traditionally treats UNKNOWN as UP */
+                       SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+               else
+                       UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+       }
+
+#elif defined(HAVE_BSD_LINK_DETECT)
+       /*
+        * This is only needed for FreeBSD older than FreeBSD-13.
+        * Valid and active media generally means the link state is
+        * up, but this is not always the case.
+        * For example, some BSD's with a net80211 interface in MONITOR
+        * mode will treat the media as valid and active but the
+        * link state is down - because we cannot send anything.
+        * Also, virtual interfaces such as PPP, VLAN, etc generally
+        * don't support media at all, so the ioctl will just fail.
         */
-       SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+       struct ifmediareq ifmr = {.ifm_status = 0};
 
-       if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
-               (void)memset(&ifmr, 0, sizeof(ifmr));
-               strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
+       strlcpy(ifmr.ifm_name, ifp->name, sizeof(ifmr.ifm_name));
 
-               /* Seems not all interfaces implement this ioctl */
-               if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1 &&
-                   errno != EINVAL)
+       if (if_ioctl(SIOCGIFMEDIA, (caddr_t)&ifmr) == -1) {
+               if (errno != EINVAL)
                        flog_err_sys(EC_LIB_SYSTEM_CALL,
-                                    "if_ioctl(SIOCGIFMEDIA) failed: %s",
-                                    safe_strerror(errno));
-               else if (ifmr.ifm_status & IFM_AVALID) /* Link state is valid */
-               {
-                       if (ifmr.ifm_status & IFM_ACTIVE)
-                               SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
-                       else
-                               UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
-               }
+                                    "if_ioctl(SIOCGIFMEDIA %s) failed: %s",
+                                    ifp->name, safe_strerror(errno));
+       } else if (ifmr.ifm_status & IFM_AVALID) { /* media state is valid */
+               if (ifmr.ifm_status & IFM_ACTIVE)  /* media is active */
+                       SET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
+               else
+                       UNSET_FLAG(ifreq.ifr_flags, IFF_RUNNING);
        }
 #endif /* HAVE_BSD_LINK_DETECT */
 
+out:
        if_flags_update(ifp, (ifreq.ifr_flags & 0x0000ffff));
 }
 
index b868d23a94249efa566d197715fc6689ea8aebd4..936206641f9dcf7a9ce436c83a99ebe3cf84b5c1 100644 (file)
@@ -175,7 +175,6 @@ static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s)
 {
        struct zebra_if *zi = ifp->info;
        struct irdp_interface *irdp = zi->irdp;
-       char buf[PREFIX_STRLEN];
        uint32_t dst;
        uint32_t ttl = 1;
 
@@ -190,10 +189,11 @@ static void irdp_send(struct interface *ifp, struct prefix *p, struct stream *s)
                dst = htonl(INADDR_ALLHOSTS_GROUP);
 
        if (irdp->flags & IF_DEBUG_MESSAGES)
-               zlog_debug("IRDP: TX Advert on %s %s Holdtime=%d Preference=%d",
-                          ifp->name, prefix2str(p, buf, sizeof(buf)),
-                          irdp->flags & IF_SHUTDOWN ? 0 : irdp->Lifetime,
-                          get_pref(irdp, p));
+               zlog_debug(
+                       "IRDP: TX Advert on %s %pFX Holdtime=%d Preference=%d",
+                       ifp->name, p,
+                       irdp->flags & IF_SHUTDOWN ? 0 : irdp->Lifetime,
+                       get_pref(irdp, p));
 
        send_packet(ifp, s, dst, p, ttl);
 }
@@ -263,9 +263,7 @@ void irdp_advert_off(struct interface *ifp)
        if (!irdp)
                return;
 
-       if (irdp->t_advertise)
-               thread_cancel(irdp->t_advertise);
-       irdp->t_advertise = NULL;
+       thread_cancel(&irdp->t_advertise);
 
        if (ifp->connected)
                for (ALL_LIST_ELEMENTS(ifp->connected, node, nnode, ifc)) {
@@ -300,9 +298,7 @@ void process_solicit(struct interface *ifp)
                return;
 
        irdp->flags |= IF_SOLICIT;
-       if (irdp->t_advertise)
-               thread_cancel(irdp->t_advertise);
-       irdp->t_advertise = NULL;
+       thread_cancel(&irdp->t_advertise);
 
        timer = (frr_weak_random() % MAX_RESPONSE_DELAY) + 1;
 
index 502a2f277cbbb937a46d88db321ced3b88c843ed..56fd35a7366cb5b60766cd3efa9937234fbc34cf 100644 (file)
@@ -79,6 +79,7 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
        struct zebra_if *zi;
        struct irdp_interface *irdp;
        uint16_t saved_chksum;
+       char buf[PREFIX_STRLEN];
 
        zi = ifp->info;
        if (!zi)
@@ -104,8 +105,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
 
        if (iplen < ICMP_MINLEN) {
                flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH,
-                        "IRDP: RX ICMP packet too short from %s\n",
-                        inet_ntoa(src));
+                        "IRDP: RX ICMP packet too short from %pI4\n",
+                        &src);
                return;
        }
 
@@ -115,8 +116,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
         len of IP-header) 14+20 */
        if (iplen > IRDP_RX_BUF - 34) {
                flog_err(EC_ZEBRA_IRDP_LEN_MISMATCH,
-                        "IRDP: RX ICMP packet too long from %s\n",
-                        inet_ntoa(src));
+                        "IRDP: RX ICMP packet too long from %pI4\n",
+                        &src);
                return;
        }
 
@@ -128,8 +129,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
        if (in_cksum(icmp, datalen) != saved_chksum) {
                flog_warn(
                        EC_ZEBRA_IRDP_BAD_CHECKSUM,
-                       "IRDP: RX ICMP packet from %s. Bad checksum, silently ignored",
-                       inet_ntoa(src));
+                       "IRDP: RX ICMP packet from %pI4 Bad checksum, silently ignored",
+                       &src);
                return;
        }
 
@@ -141,8 +142,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
        if (icmp->code != 0) {
                flog_warn(
                        EC_ZEBRA_IRDP_BAD_TYPE_CODE,
-                       "IRDP: RX packet type %d from %s. Bad ICMP type code, silently ignored",
-                       icmp->type, inet_ntoa(src));
+                       "IRDP: RX packet type %d from %pI4 Bad ICMP type code, silently ignored",
+                       icmp->type, &src);
                return;
        }
 
@@ -152,11 +153,12 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
                && !(irdp->flags & IF_BROADCAST))) {
                flog_warn(
                        EC_ZEBRA_IRDP_BAD_RX_FLAGS,
-                       "IRDP: RX illegal from %s to %s while %s operates in %s; Please correct settings\n",
-                       inet_ntoa(src),
+                       "IRDP: RX illegal from %pI4 to %s while %s operates in %s; Please correct settings\n",
+                       &src,
                        ntohl(ip->ip_dst.s_addr) == INADDR_ALLRTRS_GROUP
                                ? "multicast"
-                               : inet_ntoa(ip->ip_dst),
+                               : inet_ntop(AF_INET, &ip->ip_dst,
+                                           buf, sizeof(buf)),
                        ifp->name,
                        irdp->flags & IF_BROADCAST ? "broadcast" : "multicast");
                return;
@@ -169,8 +171,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
        case ICMP_ROUTERSOLICIT:
 
                if (irdp->flags & IF_DEBUG_MESSAGES)
-                       zlog_debug("IRDP: RX Solicit on %s from %s",
-                                  ifp->name, inet_ntoa(src));
+                       zlog_debug("IRDP: RX Solicit on %s from %pI4",
+                                  ifp->name, &src);
 
                process_solicit(ifp);
                break;
@@ -178,8 +180,8 @@ static void parse_irdp_packet(char *p, int len, struct interface *ifp)
        default:
                flog_warn(
                        EC_ZEBRA_IRDP_BAD_TYPE_CODE,
-                       "IRDP: RX packet type %d from %s. Bad ICMP type code, silently ignored",
-                       icmp->type, inet_ntoa(src));
+                       "IRDP: RX packet type %d from %pI4 Bad ICMP type code, silently ignored",
+                       icmp->type, &src);
        }
 }
 
index c53d28a18ccf82720ece455773a5986dfadf20e9..76da00c61910e2328919033f7303cb45165f8dc4 100644 (file)
@@ -1051,7 +1051,7 @@ static int nl_batch_read_resp(struct nl_batch *bth)
 {
        struct nlmsghdr *h;
        struct sockaddr_nl snl;
-       struct msghdr msg;
+       struct msghdr msg = {};
        int status, seq;
        const struct nlsock *nl;
        struct zebra_dplane_ctx *ctx;
@@ -1321,6 +1321,7 @@ static enum netlink_msg_status nl_put_msg(struct nl_batch *bth,
        case DPLANE_OP_SYS_ROUTE_DELETE:
        case DPLANE_OP_ROUTE_NOTIFY:
        case DPLANE_OP_LSP_NOTIFY:
+       case DPLANE_OP_BR_PORT_UPDATE:
                return FRR_NETLINK_SUCCESS;
 
        case DPLANE_OP_NONE:
@@ -1501,7 +1502,7 @@ void kernel_init(struct zebra_ns *zns)
 
 void kernel_terminate(struct zebra_ns *zns, bool complete)
 {
-       THREAD_READ_OFF(zns->t_netlink);
+       thread_cancel(&zns->t_netlink);
 
        if (zns->netlink.sock >= 0) {
                close(zns->netlink.sock);
index 40ac44b77f9f8dce8d94f92304b982fdc4096583..9d74aeca285090f995b55f1670080ca13f179514 100644 (file)
@@ -1001,7 +1001,7 @@ static int rtm_read_mesg(struct rt_msghdr *rtm, union sockunion *dest,
 void rtm_read(struct rt_msghdr *rtm)
 {
        int flags;
-       uint8_t zebra_flags;
+       uint32_t zebra_flags;
        union sockunion dest, mask, gate;
        char ifname[INTERFACE_NAMSIZ + 1];
        short ifnlen = 0;
@@ -1340,13 +1340,27 @@ static int kernel_read(struct thread *thread)
 
        nbytes = read(sock, &buf, sizeof(buf));
 
-       if (nbytes <= 0) {
-               if (nbytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN)
+       if (nbytes < 0) {
+               if (errno == ENOBUFS) {
+                       flog_err(EC_ZEBRA_RECVMSG_OVERRUN,
+                                "routing socket overrun: %s",
+                                safe_strerror(errno));
+                       /*
+                        *  In this case we are screwed.
+                        *  There is no good way to
+                        *  recover zebra at this point.
+                        */
+                       exit(-1);
+               }
+               if (errno != EAGAIN && errno != EWOULDBLOCK)
                        flog_err_sys(EC_LIB_SOCKET, "routing socket error: %s",
                                     safe_strerror(errno));
                return 0;
        }
 
+       if (nbytes == 0)
+               return 0;
+
        thread_add_read(zrouter.master, kernel_read, NULL, sock, NULL);
 
        if (IS_ZEBRA_DEBUG_KERNEL)
@@ -1412,6 +1426,15 @@ static void routing_socket(struct zebra_ns *zns)
                return;
        }
 
+#ifdef SO_RERROR
+       /* Allow reporting of route(4) buffer overflow errors */
+       int n = 1;
+
+       if (setsockopt(routing_sock, SOL_SOCKET, SO_RERROR, &n, sizeof(n)) < 0)
+               flog_err_sys(EC_LIB_SOCKET,
+                            "Can't set SO_RERROR on routing socket");
+#endif
+
        /* XXX: Socket should be NONBLOCK, however as we currently
         * discard failed writes, this will lead to inconsistencies.
         * For now, socket must be blocking.
index 2afef46bb2163cf5f621b1d7c48a10b555fb1452..ced29e1a25fc1550d8c0292b0ecdaab1ea4b6474 100644 (file)
@@ -87,7 +87,6 @@ uint32_t nl_rcvbufsize = 4194304;
 const struct option longopts[] = {
        {"batch", no_argument, NULL, 'b'},
        {"allow_delete", no_argument, NULL, 'a'},
-       {"keep_kernel", no_argument, NULL, 'k'},
        {"socket", required_argument, NULL, 'z'},
        {"ecmp", required_argument, NULL, 'e'},
        {"retain", no_argument, NULL, 'r'},
@@ -171,12 +170,14 @@ static void sigint(void)
 
        zebra_ptm_finish();
 
-       if (retain_mode)
+       if (retain_mode) {
+               zebra_nhg_mark_keep();
                RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
                        zvrf = vrf->info;
                        if (zvrf)
                                SET_FLAG(zvrf->flags, ZEBRA_VRF_RETAIN);
                }
+       }
        if (zrouter.lsp_process_q)
                work_queue_free_and_null(&zrouter.lsp_process_q);
 
index c0f89e6afeb721a91776e3fde3611416380fbc72..1f075cfb4b59ff2db045abd229e433bbe9172844 100644 (file)
@@ -119,18 +119,17 @@ static void zebra_redistribute(struct zserv *client, int type,
        for (rn = route_top(table); rn; rn = srcdest_route_next(rn))
                RNODE_FOREACH_RE (rn, newre) {
                        const struct prefix *dst_p, *src_p;
-                       char buf[PREFIX_STRLEN];
 
                        srcdest_rnode_prefixes(rn, &dst_p, &src_p);
 
                        if (IS_ZEBRA_DEBUG_RIB)
                                zlog_debug(
-                                       "%s: client %s %s(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
+                                       "%s: client %s %pFX(%u) checking: selected=%d, type=%d, distance=%d, metric=%d zebra_check_addr=%d",
                                        __func__,
                                        zebra_route_string(client->proto),
-                                       prefix2str(dst_p, buf, sizeof(buf)),
-                                       vrf_id, CHECK_FLAG(newre->flags,
-                                                          ZEBRA_FLAG_SELECTED),
+                                       dst_p, vrf_id,
+                                       CHECK_FLAG(newre->flags,
+                                                  ZEBRA_FLAG_SELECTED),
                                        newre->type, newre->distance,
                                        newre->metric, zebra_check_addr(dst_p));
 
@@ -196,15 +195,13 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p,
        struct listnode *node, *nnode;
        struct zserv *client;
        int afi;
-       char buf[PREFIX_STRLEN];
 
-       if (IS_ZEBRA_DEBUG_RIB) {
+       if (IS_ZEBRA_DEBUG_RIB)
                zlog_debug(
-                       "(%u:%u):%s: Redist update re %p (%s), old %p (%s)",
-                       re->vrf_id, re->table, prefix2str(p, buf, sizeof(buf)),
-                       re, zebra_route_string(re->type), prev_re,
+                       "(%u:%u):%pFX: Redist update re %p (%s), old %p (%s)",
+                       re->vrf_id, re->table, p, re,
+                       zebra_route_string(re->type), prev_re,
                        prev_re ? zebra_route_string(prev_re->type) : "None");
-       }
 
        afi = family2afi(p->family);
        if (!afi) {
@@ -214,8 +211,7 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p,
        }
        if (!zebra_check_addr(p)) {
                if (IS_ZEBRA_DEBUG_RIB)
-                       zlog_debug("Redist update filter prefix %s",
-                                  prefix2str(p, buf, sizeof(buf)));
+                       zlog_debug("Redist update filter prefix %pFX", p);
                return;
        }
 
@@ -224,10 +220,9 @@ void redistribute_update(const struct prefix *p, const struct prefix *src_p,
                if (zebra_redistribute_check(re, client, p, afi)) {
                        if (IS_ZEBRA_DEBUG_RIB) {
                                zlog_debug(
-                                       "%s: client %s %s(%u:%u), type=%d, distance=%d, metric=%d",
+                                       "%s: client %s %pFX(%u:%u), type=%d, distance=%d, metric=%d",
                                        __func__,
-                                       zebra_route_string(client->proto),
-                                       prefix2str(p, buf, sizeof(buf)),
+                                       zebra_route_string(client->proto), p,
                                        re->vrf_id, re->table, re->type,
                                        re->distance, re->metric);
                        }
@@ -254,7 +249,6 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
        struct listnode *node, *nnode;
        struct zserv *client;
        int afi;
-       char buf[PREFIX_STRLEN];
        vrf_id_t vrfid;
 
        if (old_re)
@@ -265,13 +259,11 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
                return;
 
        if (IS_ZEBRA_DEBUG_RIB) {
-               zlog_debug(
-                       "%u:%s: Redist del: re %p (%s), new re %p (%s)",
-                       vrfid, prefix2str(p, buf, sizeof(buf)),
-                       old_re,
-                       old_re ? zebra_route_string(old_re->type) : "None",
-                       new_re,
-                       new_re ? zebra_route_string(new_re->type) : "None");
+               zlog_debug("%u:%pFX: Redist del: re %p (%s), new re %p (%s)",
+                          vrfid, p, old_re,
+                          old_re ? zebra_route_string(old_re->type) : "None",
+                          new_re,
+                          new_re ? zebra_route_string(new_re->type) : "None");
        }
 
        /* Add DISTANCE_INFINITY check. */
@@ -293,8 +285,8 @@ void redistribute_delete(const struct prefix *p, const struct prefix *src_p,
        if (!zebra_check_addr(p)) {
                if (IS_ZEBRA_DEBUG_RIB) {
                        zlog_debug(
-                               "%u:%s: Redist del old: skipping invalid prefix",
-                               vrfid, prefix2str(p, buf, sizeof(buf)));
+                               "%u:%pFX: Redist del old: skipping invalid prefix",
+                               vrfid, p);
                }
                return;
        }
@@ -541,12 +533,10 @@ void zebra_interface_address_add_update(struct interface *ifp,
        struct prefix *p;
 
        if (IS_ZEBRA_DEBUG_EVENT) {
-               char buf[PREFIX_STRLEN];
-
                p = ifc->address;
-               zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %s on %s(%u)",
-                          prefix2str(p, buf, sizeof(buf)), ifp->name,
-                          ifp->vrf_id);
+               zlog_debug(
+                       "MESSAGE: ZEBRA_INTERFACE_ADDRESS_ADD %pFX on %s(%u)",
+                       p, ifp->name, ifp->vrf_id);
        }
 
        if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
@@ -580,12 +570,10 @@ void zebra_interface_address_delete_update(struct interface *ifp,
        struct prefix *p;
 
        if (IS_ZEBRA_DEBUG_EVENT) {
-               char buf[PREFIX_STRLEN];
-
                p = ifc->address;
-               zlog_debug("MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %s on %s(%u)",
-                          prefix2str(p, buf, sizeof(buf)),
-                          ifp->name, ifp->vrf_id);
+               zlog_debug(
+                       "MESSAGE: ZEBRA_INTERFACE_ADDRESS_DELETE %pFX on %s(%u)",
+                       p, ifp->name, ifp->vrf_id);
        }
 
        zebra_vxlan_add_del_gw_macip(ifp, ifc->address, 0);
index 9ddc35b09198623073b2ef623928e5cf33c74af5..3bce62bfa8c2a4c226e553fe8020fd118cabd7d0 100644 (file)
@@ -165,13 +165,15 @@ struct route_entry {
 
 /* meta-queue structure:
  * sub-queue 0: nexthop group objects
- * sub-queue 1: connected, kernel
- * sub-queue 2: static
- * sub-queue 3: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP
- * sub-queue 4: iBGP, eBGP
- * sub-queue 5: any other origin (if any)
+ * sub-queue 1: connected
+ * sub-queue 2: kernel
+ * sub-queue 3: static
+ * sub-queue 4: RIP, RIPng, OSPF, OSPF6, IS-IS, EIGRP, NHRP
+ * sub-queue 5: iBGP, eBGP
+ * sub-queue 6: any other origin (if any) typically those that
+ *              don't generate routes
  */
-#define MQ_SIZE 6
+#define MQ_SIZE 7
 struct meta_queue {
        struct list *subq[MQ_SIZE];
        uint32_t size; /* sum of lengths of all subqueues */
@@ -364,7 +366,7 @@ extern void rib_uninstall_kernel(struct route_node *rn, struct route_entry *re);
  * All rib_add function will not just add prefix into RIB, but
  * also implicitly withdraw equal prefix of same type. */
 extern int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
-                  unsigned short instance, int flags, struct prefix *p,
+                  unsigned short instance, uint32_t flags, struct prefix *p,
                   struct prefix_ipv6 *src_p, const struct nexthop *nh,
                   uint32_t nhe_id, uint32_t table_id, uint32_t metric,
                   uint32_t mtu, uint8_t distance, route_tag_t tag);
@@ -380,10 +382,11 @@ extern int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
                                 struct nhg_hash_entry *nhe);
 
 extern void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
-                      unsigned short instance, int flags, struct prefix *p,
-                      struct prefix_ipv6 *src_p, const struct nexthop *nh,
-                      uint32_t nhe_id, uint32_t table_id, uint32_t metric,
-                      uint8_t distance, bool fromkernel, bool connected_down);
+                      unsigned short instance, uint32_t flags,
+                      struct prefix *p, struct prefix_ipv6 *src_p,
+                      const struct nexthop *nh, uint32_t nhe_id,
+                      uint32_t table_id, uint32_t metric, uint8_t distance,
+                      bool fromkernel, bool connected_down);
 
 extern struct route_entry *rib_match(afi_t afi, safi_t safi, vrf_id_t vrf_id,
                                     union g_addr *addr,
index 7e81f29827927ca59ae33deb622129b98a42457b..7af60a389bd47f234b2a2f802889bf4bb86882d8 100644 (file)
@@ -331,7 +331,7 @@ DEFUN (ip_router_id_in_vrf,
        ip_router_id_in_vrf_cmd,
        "ip router-id A.B.C.D",
        IP_STR
-       "Manuall set the router-id\n"
+       "Manually set the router-id\n"
        "IP address to use for router-id\n")
 {
        ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
@@ -361,7 +361,7 @@ DEFUN (ipv6_router_id_in_vrf,
        ipv6_router_id_in_vrf_cmd,
        "ipv6 router-id X:X::X:X",
        IP6_STR
-       "Manuall set the IPv6 router-id\n"
+       "Manually set the IPv6 router-id\n"
        "IPV6 address to use for router-id\n")
 {
        ZEBRA_DECLVAR_CONTEXT(vrf, zvrf);
index 1ce3c435feda5e65e10b03b4ff00d709685502c2..ef51989a0c3586b8455ebb64e87ad7282df88021 100644 (file)
@@ -574,7 +574,7 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
        int len;
        struct rtmsg *rtm;
        struct rtattr *tb[RTA_MAX + 1];
-       uint8_t flags = 0;
+       uint32_t flags = 0;
        struct prefix p;
        struct prefix_ipv6 src_p = {};
        vrf_id_t vrf_id;
@@ -731,11 +731,10 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
                p.prefixlen = rtm->rtm_dst_len;
 
                if (rtm->rtm_src_len != 0) {
-                       char buf[PREFIX_STRLEN];
                        flog_warn(
                                EC_ZEBRA_UNSUPPORTED_V4_SRCDEST,
-                               "unsupported IPv4 sourcedest route (dest %s vrf %u)",
-                               prefix2str(&p, buf, sizeof(buf)), vrf_id);
+                               "unsupported IPv4 sourcedest route (dest %pFX vrf %u)",
+                               &p, vrf_id);
                        return 0;
                }
 
@@ -786,12 +785,11 @@ static int netlink_route_change_read_unicast(struct nlmsghdr *h, ns_id_t ns_id,
        }
 
        if (IS_ZEBRA_DEBUG_KERNEL) {
-               char buf[PREFIX_STRLEN];
                char buf2[PREFIX_STRLEN];
+
                zlog_debug(
-                       "%s %s%s%s vrf %s(%u) table_id: %u metric: %d Admin Distance: %d",
-                       nl_msg_type_to_str(h->nlmsg_type),
-                       prefix2str(&p, buf, sizeof(buf)),
+                       "%s %pFX%s%s vrf %s(%u) table_id: %u metric: %d Admin Distance: %d",
+                       nl_msg_type_to_str(h->nlmsg_type), &p,
                        src_p.prefixlen ? " from " : "",
                        src_p.prefixlen ? prefix2str(&src_p, buf2, sizeof(buf2))
                                        : "",
@@ -905,8 +903,6 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h,
        int count;
        int oif[256];
        int oif_count = 0;
-       char sbuf[40];
-       char gbuf[40];
        char oif_list[256] = "\0";
        vrf_id_t vrf;
        int table;
@@ -968,8 +964,6 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h,
                struct interface *ifp = NULL;
                struct zebra_vrf *zvrf = NULL;
 
-               strlcpy(sbuf, inet_ntoa(m->sg.src), sizeof(sbuf));
-               strlcpy(gbuf, inet_ntoa(m->sg.grp), sizeof(gbuf));
                for (count = 0; count < oif_count; count++) {
                        ifp = if_lookup_by_index(oif[count], vrf);
                        char temp[256];
@@ -981,9 +975,10 @@ static int netlink_route_change_read_multicast(struct nlmsghdr *h,
                zvrf = zebra_vrf_lookup_by_id(vrf);
                ifp = if_lookup_by_index(iif, vrf);
                zlog_debug(
-                       "MCAST VRF: %s(%d) %s (%s,%s) IIF: %s(%d) OIF: %s jiffies: %lld",
+                       "MCAST VRF: %s(%d) %s (%pI4,%pI4) IIF: %s(%d) OIF: %s jiffies: %lld",
                        zvrf_name(zvrf), vrf, nl_msg_type_to_str(h->nlmsg_type),
-                       sbuf, gbuf, ifp ? ifp->name : "Unknown", iif, oif_list,
+                       &m->sg.src, &m->sg.grp, ifp ? ifp->name : "Unknown",
+                       iif, oif_list,
                        m->lastused);
        }
        return 0;
@@ -2102,6 +2097,8 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
        int num_labels = 0;
        uint32_t id = dplane_ctx_get_nhe_id(ctx);
        int type = dplane_ctx_get_nhe_type(ctx);
+       struct rtattr *nest;
+       uint16_t encap;
 
        if (!id) {
                flog_err(
@@ -2230,34 +2227,21 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
                                 */
                                if (req->nhm.nh_family == AF_MPLS)
                                        goto nexthop_done;
-#if 0
-                                       if (!nl_attr_put(&req->n, buflen, NHA_NEWDST,
-                                                 &out_lse,
-                                                 num_labels
-                                                         * sizeof(mpls_lse_t)))
-                                               return 0;
-#endif
-                               else {
-                                       struct rtattr *nest;
-                                       uint16_t encap = LWTUNNEL_ENCAP_MPLS;
-
-                                       if (!nl_attr_put16(&req->n, buflen,
-                                                          NHA_ENCAP_TYPE,
-                                                          encap))
-                                               return 0;
-                                       nest = nl_attr_nest(&req->n, buflen,
-                                                           NHA_ENCAP);
-                                       if (!nest)
-                                               return 0;
-                                       if (!nl_attr_put(
-                                                   &req->n, buflen,
-                                                   MPLS_IPTUNNEL_DST, &out_lse,
-                                                   num_labels
-                                                           * sizeof(
-                                                                   mpls_lse_t)))
-                                               return 0;
-                                       nl_attr_nest_end(&req->n, nest);
-                               }
+
+                               encap = LWTUNNEL_ENCAP_MPLS;
+                               if (!nl_attr_put16(&req->n, buflen,
+                                                  NHA_ENCAP_TYPE, encap))
+                                       return 0;
+                               nest = nl_attr_nest(&req->n, buflen, NHA_ENCAP);
+                               if (!nest)
+                                       return 0;
+                               if (!nl_attr_put(
+                                           &req->n, buflen, MPLS_IPTUNNEL_DST,
+                                           &out_lse,
+                                           num_labels * sizeof(mpls_lse_t)))
+                                       return 0;
+
+                               nl_attr_nest_end(&req->n, nest);
                        }
 
 nexthop_done:
@@ -2267,9 +2251,9 @@ nexthop_done:
                                           __func__, id, nh, nh->ifindex,
                                           vrf_id_to_name(nh->vrf_id),
                                           nh->vrf_id, label_buf);
-}
+               }
 
-req->nhm.nh_protocol = zebra2proto(type);
+               req->nhm.nh_protocol = zebra2proto(type);
 
        } else if (cmd != RTM_DELNEXTHOP) {
                flog_err(
@@ -2892,8 +2876,8 @@ static int netlink_macfdb_change(struct nlmsghdr *h, int len, ns_id_t ns_id)
                dst_present = 1;
                memcpy(&vtep_ip.s_addr, RTA_DATA(tb[NDA_DST]),
                       IPV4_MAX_BYTELEN);
-               snprintf(dst_buf, sizeof(dst_buf), " dst %s",
-                        inet_ntoa(vtep_ip));
+               snprintfrr(dst_buf, sizeof(dst_buf), " dst %pI4",
+                          &vtep_ip);
        }
 
        if (tb[NDA_NH_ID])
@@ -3950,8 +3934,8 @@ static int netlink_fdb_nh_update(uint32_t nh_id, struct in_addr vtep_ip)
                return -1;
 
        if (IS_ZEBRA_DEBUG_KERNEL || IS_ZEBRA_DEBUG_EVPN_MH_NH) {
-               zlog_debug("Tx %s fdb-nh 0x%x %s",
-                          nl_msg_type_to_str(cmd), nh_id, inet_ntoa(vtep_ip));
+               zlog_debug("Tx %s fdb-nh 0x%x %pI4",
+                          nl_msg_type_to_str(cmd), nh_id, &vtep_ip);
        }
 
        return netlink_talk(netlink_talk_filter, &req.n, &zns->netlink_cmd, zns,
index a2e15cbd2b31d827ffd52a29f7f6dfa13ece1248..a0f401c33469fb4b66f503e1fcbc7a83c3bc12b2 100644 (file)
@@ -80,19 +80,15 @@ static int kernel_rtm(int cmd, const struct prefix *p,
        bool gate = false;
        int error;
        char gate_buf[INET6_BUFSIZ];
-       char prefix_buf[PREFIX_STRLEN];
        enum blackhole_type bh_type = BLACKHOLE_UNSPEC;
 
-       prefix2str(p, prefix_buf, sizeof(prefix_buf));
-
        /*
         * We only have the ability to ADD or DELETE at this point
         * in time.
         */
        if (cmd != RTM_ADD && cmd != RTM_DELETE) {
                if (IS_ZEBRA_DEBUG_KERNEL)
-                       zlog_debug("%s: %s odd command %s",
-                                  __func__, prefix_buf,
+                       zlog_debug("%s: %pFX odd command %s", __func__, p,
                                   lookup_msg(rtm_type_str, cmd, NULL));
                return 0;
        }
@@ -237,8 +233,8 @@ static int kernel_rtm(int cmd, const struct prefix *p,
                if (IS_ZEBRA_DEBUG_KERNEL) {
                        if (!gate) {
                                zlog_debug(
-                                       "%s: %s: attention! gate not found for re",
-                                       __func__, prefix_buf);
+                                       "%s: %pFX: attention! gate not found for re",
+                                       __func__, p);
                        } else {
                                switch (p->family) {
                                case AF_INET:
@@ -266,8 +262,8 @@ static int kernel_rtm(int cmd, const struct prefix *p,
                case ZEBRA_ERR_NOERROR:
                        nexthop_num++;
                        if (IS_ZEBRA_DEBUG_KERNEL)
-                               zlog_debug("%s: %s: successfully did NH %s",
-                                          __func__, prefix_buf, gate_buf);
+                               zlog_debug("%s: %pFX: successfully did NH %s",
+                                          __func__, p, gate_buf);
                        if (cmd == RTM_ADD)
                                SET_FLAG(nexthop->flags, NEXTHOP_FLAG_FIB);
                        break;
@@ -289,8 +285,8 @@ static int kernel_rtm(int cmd, const struct prefix *p,
                default:
                        flog_err(
                                EC_LIB_SYSTEM_CALL,
-                               "%s: %s: rtm_write() unexpectedly returned %d for command %s",
-                               __func__, prefix_buf, error,
+                               "%s: %pFX: rtm_write() unexpectedly returned %d for command %s",
+                               __func__, p, error,
                                lookup_msg(rtm_type_str, cmd, NULL));
                        break;
                }
@@ -300,8 +296,8 @@ static int kernel_rtm(int cmd, const struct prefix *p,
        if (nexthop_num == 0) {
                if (IS_ZEBRA_DEBUG_KERNEL)
                        zlog_debug(
-                               "%s: No useful nexthops were found in RIB prefix %s",
-                               __func__, prefix_buf);
+                               "%s: No useful nexthops were found in RIB prefix %pFX",
+                               __func__, p);
                return 1;
        }
 
index 13b7c150a3424643609ee7e9cd83933da30cab41..c3add16c5693a699373a73734f7aea49da630cf9 100644 (file)
@@ -2337,7 +2337,6 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)
        struct rtadv_prefix *rprefix;
        struct rtadv_rdnss *rdnss;
        struct rtadv_dnssl *dnssl;
-       char buf[PREFIX_STRLEN];
        int interval;
 
        zif = ifp->info;
@@ -2408,8 +2407,7 @@ static int rtadv_config_write(struct vty *vty, struct interface *ifp)
        for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvPrefixList, node, rprefix)) {
                if ((rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL)
                    || (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH)) {
-                       vty_out(vty, " ipv6 nd prefix %s",
-                               prefix2str(&rprefix->prefix, buf, sizeof(buf)));
+                       vty_out(vty, " ipv6 nd prefix %pFX", &rprefix->prefix);
                        if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME)
                            || (rprefix->AdvPreferredLifetime
                                != RTADV_PREFERRED_LIFETIME)) {
index d6a34327a6ae20ed454a3afb3d684391241c37de..a63504992eb241171a1e1201039c8fae533d47e7 100644 (file)
@@ -75,8 +75,6 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
        } *req = buf;
 
        const char *ifname = dplane_ctx_rule_get_ifname(ctx);
-       char buf1[PREFIX_STRLEN];
-       char buf2[PREFIX_STRLEN];
 
        if (buflen < sizeof(*req))
                return 0;
@@ -141,11 +139,9 @@ netlink_rule_msg_encode(int cmd, const struct zebra_dplane_ctx *ctx,
 
        if (IS_ZEBRA_DEBUG_KERNEL)
                zlog_debug(
-                       "Tx %s family %s IF %s Pref %u Fwmark %u Src %s Dst %s Table %u",
+                       "Tx %s family %s IF %s Pref %u Fwmark %u Src %pFX Dst %pFX Table %u",
                        nl_msg_type_to_str(cmd), nl_family_to_str(family),
-                       ifname, priority, fwmark,
-                       prefix2str(src_ip, buf1, sizeof(buf1)),
-                       prefix2str(dst_ip, buf2, sizeof(buf2)), table);
+                       ifname, priority, fwmark, src_ip, dst_ip, table);
 
        return NLMSG_ALIGN(req->n.nlmsg_len);
 }
@@ -231,8 +227,6 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
        int len;
        char *ifname;
        struct zebra_pbr_rule rule = {};
-       char buf1[PREFIX_STRLEN];
-       char buf2[PREFIX_STRLEN];
        uint8_t proto = 0;
 
        /* Basic validation followed by extracting attributes. */
@@ -324,17 +318,14 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
                        ret = dplane_pbr_rule_delete(&rule);
 
                        zlog_debug(
-                               "%s: %s leftover rule: family %s IF %s Pref %u Src %s Dst %s Table %u",
+                               "%s: %s leftover rule: family %s IF %s Pref %u Src %pFX Dst %pFX Table %u",
                                __func__,
                                ((ret == ZEBRA_DPLANE_REQUEST_FAILURE)
                                         ? "Failed to remove"
                                         : "Removed"),
                                nl_family_to_str(frh->family), rule.ifname,
-                               rule.rule.priority,
-                               prefix2str(&rule.rule.filter.src_ip, buf1,
-                                          sizeof(buf1)),
-                               prefix2str(&rule.rule.filter.dst_ip, buf2,
-                                          sizeof(buf2)),
+                               rule.rule.priority, &rule.rule.filter.src_ip,
+                               &rule.rule.filter.dst_ip,
                                rule.rule.action.table);
                }
 
@@ -350,15 +341,11 @@ int netlink_rule_change(struct nlmsghdr *h, ns_id_t ns_id, int startup)
 
        if (IS_ZEBRA_DEBUG_KERNEL)
                zlog_debug(
-                       "Rx %s family %s IF %s Pref %u Src %s Dst %s Table %u",
+                       "Rx %s family %s IF %s Pref %u Src %pFX Dst %pFX Table %u",
                        nl_msg_type_to_str(h->nlmsg_type),
                        nl_family_to_str(frh->family), rule.ifname,
-                       rule.rule.priority,
-                       prefix2str(&rule.rule.filter.src_ip, buf1,
-                                  sizeof(buf1)),
-                       prefix2str(&rule.rule.filter.dst_ip, buf2,
-                                  sizeof(buf2)),
-                       rule.rule.action.table);
+                       rule.rule.priority, &rule.rule.filter.src_ip,
+                       &rule.rule.filter.dst_ip, rule.rule.action.table);
 
        return kernel_pbr_rule_del(&rule);
 }
index c33bca3d86fc3ebb90ede9251b56648942bafef4..18017c9700cd4932a3d17dfba3a94fba91cf643f 100644 (file)
@@ -644,17 +644,12 @@ int zsend_redistribute_route(int cmd, struct zserv *client,
                return -1;
        }
 
-       if (IS_ZEBRA_DEBUG_SEND) {
-               char buf_prefix[PREFIX_STRLEN];
-
-               prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
-
-               zlog_debug("%s: %s to client %s: type %s, vrf_id %d, p %s",
+       if (IS_ZEBRA_DEBUG_SEND)
+               zlog_debug("%s: %s to client %s: type %s, vrf_id %d, p %pFX",
                           __func__, zserv_command_string(cmd),
                           zebra_route_string(client->proto),
                           zebra_route_string(api.type), api.vrf_id,
-                          buf_prefix);
-       }
+                          &api.prefix);
        return zserv_send_message(client, s);
 }
 
@@ -755,26 +750,18 @@ static int route_notify_internal(const struct prefix *p, int type,
 
        client = zserv_find_client(type, instance);
        if (!client || !client->notify_owner) {
-               if (IS_ZEBRA_DEBUG_PACKET) {
-                       char buff[PREFIX_STRLEN];
-
+               if (IS_ZEBRA_DEBUG_PACKET)
                        zlog_debug(
-                               "Not Notifying Owner: %s about prefix %s(%u) %d vrf: %u",
-                               zebra_route_string(type),
-                               prefix2str(p, buff, sizeof(buff)), table_id,
-                               note, vrf_id);
-               }
+                               "Not Notifying Owner: %s about prefix %pFX(%u) %d vrf: %u",
+                               zebra_route_string(type), p, table_id, note,
+                               vrf_id);
                return 0;
        }
 
-       if (IS_ZEBRA_DEBUG_PACKET) {
-               char buff[PREFIX_STRLEN];
-
-               zlog_debug("Notifying Owner: %s about prefix %s(%u) %d vrf: %u",
-                          zebra_route_string(type),
-                          prefix2str(p, buff, sizeof(buff)), table_id, note,
-                          vrf_id);
-       }
+       if (IS_ZEBRA_DEBUG_PACKET)
+               zlog_debug(
+                       "Notifying Owner: %s about prefix %pFX(%u) %d vrf: %u",
+                       zebra_route_string(type), p, table_id, note, vrf_id);
 
        s = stream_new(ZEBRA_MAX_PACKET_SIZ);
        stream_reset(s);
@@ -1903,14 +1890,10 @@ static void zread_route_add(ZAPI_HANDLER_ARGS)
 
        vrf_id = zvrf_id(zvrf);
 
-       if (IS_ZEBRA_DEBUG_RECV) {
-               char buf_prefix[PREFIX_STRLEN];
-
-               prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
-               zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x",
-                          __func__, vrf_id, api.tableid, buf_prefix,
+       if (IS_ZEBRA_DEBUG_RECV)
+               zlog_debug("%s: p=(%u:%u)%pFX, msg flags=0x%x, flags=0x%x",
+                          __func__, vrf_id, api.tableid, &api.prefix,
                           (int)api.message, api.flags);
-       }
 
        /* Allocate new route. */
        re = XCALLOC(MTYPE_RE, sizeof(struct route_entry));
@@ -2068,14 +2051,10 @@ static void zread_route_del(ZAPI_HANDLER_ARGS)
        else
                table_id = zvrf->table_id;
 
-       if (IS_ZEBRA_DEBUG_RECV) {
-               char buf_prefix[PREFIX_STRLEN];
-
-               prefix2str(&api.prefix, buf_prefix, sizeof(buf_prefix));
-               zlog_debug("%s: p=(%u:%u)%s, msg flags=0x%x, flags=0x%x",
-                          __func__, zvrf_id(zvrf), table_id, buf_prefix,
+       if (IS_ZEBRA_DEBUG_RECV)
+               zlog_debug("%s: p=(%u:%u)%pFX, msg flags=0x%x, flags=0x%x",
+                          __func__, zvrf_id(zvrf), table_id, &api.prefix,
                           (int)api.message, api.flags);
-       }
 
        rib_delete(afi, api.safi, zvrf_id(zvrf), api.type, api.instance,
                   api.flags, &api.prefix, src_p, NULL, 0, table_id, api.metric,
index 76d7d00e4a3af94304adf22504b128f38627286a..22cc234b2f6da517f3680922dff304b3ac274b60 100644 (file)
 #include "zebra/rt.h"
 #include "zebra/debug.h"
 #include "zebra/zebra_pbr.h"
+#include "printfrr.h"
 
 /* Memory type for context blocks */
 DEFINE_MTYPE_STATIC(ZEBRA, DP_CTX, "Zebra DPlane Ctx")
+DEFINE_MTYPE_STATIC(ZEBRA, DP_INTF, "Zebra DPlane Intf")
 DEFINE_MTYPE_STATIC(ZEBRA, DP_PROV, "Zebra DPlane Provider")
 
 #ifndef AOK
 #  define AOK 0
 #endif
 
+/* Control for collection of extra interface info with route updates; a plugin
+ * can enable the extra info via a dplane api.
+ */
+static bool dplane_collect_extra_intf_info;
+
 /* Enable test dataplane provider */
 /*#define DPLANE_TEST_PROVIDER 1 */
 
@@ -83,6 +90,18 @@ struct dplane_nexthop_info {
        uint8_t nh_grp_count;
 };
 
+/*
+ * Optional extra info about interfaces used in route updates' nexthops.
+ */
+struct dplane_intf_extra {
+       vrf_id_t vrf_id;
+       uint32_t ifindex;
+       uint32_t flags;
+       uint32_t status;
+
+       TAILQ_ENTRY(dplane_intf_extra) link;
+};
+
 /*
  * Route information captured for route updates.
  */
@@ -126,8 +145,8 @@ struct dplane_route_info {
        struct nexthop_group zd_old_ng;
        struct nexthop_group old_backup_ng;
 
-       /* TODO -- use fixed array of nexthops, to avoid mallocs? */
-
+       /* Optional list of extra interface info */
+       TAILQ_HEAD(dp_intf_extra_q, dplane_intf_extra) intf_extra_q;
 };
 
 /*
@@ -148,6 +167,17 @@ struct dplane_pw_info {
        union pw_protocol_fields fields;
 };
 
+/*
+ * Bridge port info for the dataplane
+ */
+struct dplane_br_port_info {
+       uint32_t sph_filter_cnt;
+       struct in_addr sph_filters[ES_VTEP_MAX_CNT];
+       /* DPLANE_BR_PORT_XXX - see zebra_dplane.h*/
+       uint32_t flags;
+       uint32_t backup_nhg_id;
+};
+
 /*
  * Interface/prefix info for the dataplane
  */
@@ -272,6 +302,7 @@ struct zebra_dplane_ctx {
                struct dplane_route_info rinfo;
                zebra_lsp_t lsp;
                struct dplane_pw_info pw;
+               struct dplane_br_port_info br_port;
                struct dplane_intf_info intf;
                struct dplane_mac_info macinfo;
                struct dplane_neigh_info neigh;
@@ -390,6 +421,9 @@ static struct zebra_dplane_globals {
        _Atomic uint32_t dg_pws_in;
        _Atomic uint32_t dg_pw_errors;
 
+       _Atomic uint32_t dg_br_port_in;
+       _Atomic uint32_t dg_br_port_errors;
+
        _Atomic uint32_t dg_intf_addrs_in;
        _Atomic uint32_t dg_intf_addr_errors;
 
@@ -491,6 +525,8 @@ void dplane_enable_sys_route_notifs(void)
  */
 static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
 {
+       struct dplane_intf_extra *if_extra, *if_tmp;
+
        /*
         * Some internal allocations may need to be freed, depending on
         * the type of info captured in the ctx.
@@ -533,6 +569,14 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
                        ctx->u.rinfo.old_backup_ng.nexthop = NULL;
                }
 
+               /* Optional extra interface info */
+               TAILQ_FOREACH_SAFE(if_extra, &ctx->u.rinfo.intf_extra_q,
+                                  link, if_tmp) {
+                       TAILQ_REMOVE(&ctx->u.rinfo.intf_extra_q, if_extra,
+                                    link);
+                       XFREE(MTYPE_DP_INTF, if_extra);
+               }
+
                break;
 
        case DPLANE_OP_NH_INSTALL:
@@ -610,6 +654,7 @@ static void dplane_ctx_free_internal(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_RULE_DELETE:
        case DPLANE_OP_RULE_UPDATE:
        case DPLANE_OP_NEIGH_DISCOVER:
+       case DPLANE_OP_BR_PORT_UPDATE:
        case DPLANE_OP_NONE:
                break;
        }
@@ -803,6 +848,10 @@ const char *dplane_op2str(enum dplane_op_e op)
                ret = "SYS_ROUTE_DEL";
                break;
 
+       case DPLANE_OP_BR_PORT_UPDATE:
+               ret = "BR_PORT_UPDATE";
+               break;
+
        case DPLANE_OP_ADDR_INSTALL:
                ret = "ADDR_INSTALL";
                break;
@@ -1763,10 +1812,80 @@ dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx)
        return &(ctx->u.rule.old.dst_ip);
 }
 
+uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+
+       return ctx->u.br_port.flags;
+}
+
+uint32_t
+dplane_ctx_get_br_port_sph_filter_cnt(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+
+       return ctx->u.br_port.sph_filter_cnt;
+}
+
+const struct in_addr *
+dplane_ctx_get_br_port_sph_filters(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+
+       return ctx->u.br_port.sph_filters;
+}
+
+uint32_t
+dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx)
+{
+       DPLANE_CTX_VALID(ctx);
+
+       return ctx->u.br_port.backup_nhg_id;
+}
+
 /*
  * End of dplane context accessors
  */
 
+/* Optional extra info about interfaces in nexthops - a plugin must enable
+ * this extra info.
+ */
+const struct dplane_intf_extra *
+dplane_ctx_get_intf_extra(const struct zebra_dplane_ctx *ctx)
+{
+       return TAILQ_FIRST(&ctx->u.rinfo.intf_extra_q);
+}
+
+const struct dplane_intf_extra *
+dplane_ctx_intf_extra_next(const struct zebra_dplane_ctx *ctx,
+                          const struct dplane_intf_extra *ptr)
+{
+       return TAILQ_NEXT(ptr, link);
+}
+
+vrf_id_t dplane_intf_extra_get_vrfid(const struct dplane_intf_extra *ptr)
+{
+       return ptr->vrf_id;
+}
+
+uint32_t dplane_intf_extra_get_ifindex(const struct dplane_intf_extra *ptr)
+{
+       return ptr->ifindex;
+}
+
+uint32_t dplane_intf_extra_get_flags(const struct dplane_intf_extra *ptr)
+{
+       return ptr->flags;
+}
+
+uint32_t dplane_intf_extra_get_status(const struct dplane_intf_extra *ptr)
+{
+       return ptr->status;
+}
+
+/*
+ * End of interface extra info accessors
+ */
 
 /*
  * Retrieve the limit on the number of pending, unprocessed updates.
@@ -1835,10 +1954,14 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
        struct zebra_vrf *zvrf;
        struct nexthop *nexthop;
        zebra_l3vni_t *zl3vni;
+       const struct interface *ifp;
+       struct dplane_intf_extra *if_extra;
 
        if (!ctx || !rn || !re)
                goto done;
 
+       TAILQ_INIT(&ctx->u.rinfo.intf_extra_q);
+
        ctx->zd_op = op;
        ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
 
@@ -1900,6 +2023,27 @@ int dplane_ctx_route_init(struct zebra_dplane_ctx *ctx, enum dplane_op_e op,
                        nexthop->nh_encap_type = NET_VXLAN;
                        nexthop->nh_encap.vni = zl3vni->vni;
                }
+
+               /* Optionally capture extra interface info while we're in the
+                * main zebra pthread - a plugin has to ask for this info.
+                */
+               if (dplane_collect_extra_intf_info) {
+                       ifp = if_lookup_by_index(nexthop->ifindex,
+                                                nexthop->vrf_id);
+
+                       if (ifp) {
+                               if_extra = XCALLOC(
+                                       MTYPE_DP_INTF,
+                                       sizeof(struct dplane_intf_extra));
+                               if_extra->vrf_id = nexthop->vrf_id;
+                               if_extra->ifindex = nexthop->ifindex;
+                               if_extra->flags = ifp->flags;
+                               if_extra->status = ifp->status;
+
+                               TAILQ_INSERT_TAIL(&ctx->u.rinfo.intf_extra_q,
+                                                 if_extra, link);
+                       }
+               }
        }
 
        /* Don't need some info when capturing a system notification */
@@ -2224,20 +2368,14 @@ static int dplane_ctx_rule_init(struct zebra_dplane_ctx *ctx,
                                struct zebra_pbr_rule *new_rule,
                                struct zebra_pbr_rule *old_rule)
 {
-       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
-               char buf1[PREFIX_STRLEN];
-               char buf2[PREFIX_STRLEN];
-
+       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                zlog_debug(
-                       "init dplane ctx %s: IF %s Prio %u Fwmark %u Src %s Dst %s Table %u",
+                       "init dplane ctx %s: IF %s Prio %u Fwmark %u Src %pFX Dst %pFX Table %u",
                        dplane_op2str(op), new_rule->ifname,
                        new_rule->rule.priority, new_rule->rule.filter.fwmark,
-                       prefix2str(&new_rule->rule.filter.src_ip, buf1,
-                                  sizeof(buf1)),
-                       prefix2str(&new_rule->rule.filter.dst_ip, buf2,
-                                  sizeof(buf2)),
+                       &new_rule->rule.filter.src_ip,
+                       &new_rule->rule.filter.dst_ip,
                        new_rule->rule.action.table);
-       }
 
        ctx->zd_op = op;
        ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
@@ -2844,6 +2982,80 @@ done:
        return result;
 }
 
+/*
+ * Enqueue access br_port update.
+ */
+enum zebra_dplane_result
+dplane_br_port_update(const struct interface *ifp, bool non_df,
+                     uint32_t sph_filter_cnt,
+                     const struct in_addr *sph_filters, uint32_t backup_nhg_id)
+{
+       enum zebra_dplane_result result = ZEBRA_DPLANE_REQUEST_FAILURE;
+       uint32_t flags = 0;
+       int ret;
+       struct zebra_dplane_ctx *ctx = NULL;
+       struct zebra_ns *zns;
+       enum dplane_op_e op = DPLANE_OP_BR_PORT_UPDATE;
+
+       if (non_df)
+               flags |= DPLANE_BR_PORT_NON_DF;
+
+       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL || IS_ZEBRA_DEBUG_EVPN_MH_ES) {
+               uint32_t i;
+               char vtep_str[ES_VTEP_LIST_STR_SZ];
+
+               vtep_str[0] = '\0';
+               for (i = 0; i < sph_filter_cnt; ++i) {
+                       snprintfrr(vtep_str + strlen(vtep_str),
+                                  sizeof(vtep_str) - strlen(vtep_str), "%pI4 ",
+                                  &sph_filters[i]);
+               }
+               zlog_debug(
+                       "init br_port ctx %s: ifp %s, flags 0x%x backup_nhg 0x%x sph %s",
+                       dplane_op2str(op), ifp->name, flags, backup_nhg_id,
+                       vtep_str);
+       }
+
+       ctx = dplane_ctx_alloc();
+
+       ctx->zd_op = op;
+       ctx->zd_status = ZEBRA_DPLANE_REQUEST_SUCCESS;
+       ctx->zd_vrf_id = ifp->vrf_id;
+
+       zns = zebra_ns_lookup(ifp->vrf_id);
+       dplane_ctx_ns_init(ctx, zns, false);
+
+       ctx->zd_ifindex = ifp->ifindex;
+       strlcpy(ctx->zd_ifname, ifp->name, sizeof(ctx->zd_ifname));
+
+       /* Init the br-port-specific data area */
+       memset(&ctx->u.br_port, 0, sizeof(ctx->u.br_port));
+
+       ctx->u.br_port.flags = flags;
+       ctx->u.br_port.backup_nhg_id = backup_nhg_id;
+       ctx->u.br_port.sph_filter_cnt = sph_filter_cnt;
+       memcpy(ctx->u.br_port.sph_filters, sph_filters,
+              sizeof(ctx->u.br_port.sph_filters[0]) * sph_filter_cnt);
+
+       /* Enqueue for processing on the dplane pthread */
+       ret = dplane_update_enqueue(ctx);
+
+       /* Increment counter */
+       atomic_fetch_add_explicit(&zdplane_info.dg_br_port_in, 1,
+                                 memory_order_relaxed);
+
+       if (ret == AOK) {
+               result = ZEBRA_DPLANE_REQUEST_QUEUED;
+       } else {
+               /* Error counter */
+               atomic_fetch_add_explicit(&zdplane_info.dg_br_port_errors, 1,
+                                         memory_order_relaxed);
+               dplane_ctx_free(&ctx);
+       }
+
+       return result;
+}
+
 /*
  * Enqueue interface address add for the dataplane.
  */
@@ -2895,15 +3107,10 @@ static enum zebra_dplane_result intf_addr_update_internal(
        struct zebra_dplane_ctx *ctx = NULL;
        struct zebra_ns *zns;
 
-       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL) {
-               char addr_str[PREFIX_STRLEN];
-
-               prefix2str(ifc->address, addr_str, sizeof(addr_str));
-
-               zlog_debug("init intf ctx %s: idx %d, addr %u:%s",
+       if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
+               zlog_debug("init intf ctx %s: idx %d, addr %u:%pFX",
                           dplane_op2str(op), ifp->ifindex, ifp->vrf_id,
-                          addr_str);
-       }
+                          ifc->address);
 
        ctx = dplane_ctx_alloc();
 
@@ -3220,8 +3427,8 @@ enum zebra_dplane_result dplane_vtep_add(const struct interface *ifp,
        struct ipaddr addr;
 
        if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Install %s into flood list for VNI %u intf %s(%u)",
-                          inet_ntoa(*ip), vni, ifp->name, ifp->ifindex);
+               zlog_debug("Install %pI4 into flood list for VNI %u intf %s(%u)",
+                          ip, vni, ifp->name, ifp->ifindex);
 
        SET_IPADDR_V4(&addr);
        addr.ipaddr_v4 = *ip;
@@ -3245,8 +3452,8 @@ enum zebra_dplane_result dplane_vtep_delete(const struct interface *ifp,
 
        if (IS_ZEBRA_DEBUG_VXLAN)
                zlog_debug(
-                       "Uninstall %s from flood list for VNI %u intf %s(%u)",
-                       inet_ntoa(*ip), vni, ifp->name, ifp->ifindex);
+                       "Uninstall %pI4 from flood list for VNI %u intf %s(%u)",
+                       ip, vni, ifp->name, ifp->ifindex);
 
        SET_IPADDR_V4(&addr);
        addr.ipaddr_v4 = *ip;
@@ -3461,6 +3668,13 @@ int dplane_show_helper(struct vty *vty, bool detailed)
        vty_out(vty, "Rule updates:             %" PRIu64 "\n", incoming);
        vty_out(vty, "Rule errors:              %" PRIu64 "\n", errs);
 
+       incoming = atomic_load_explicit(&zdplane_info.dg_br_port_in,
+                                       memory_order_relaxed);
+       errs = atomic_load_explicit(&zdplane_info.dg_br_port_errors,
+                                   memory_order_relaxed);
+       vty_out(vty, "Bridge port updates:      %" PRIu64 "\n", incoming);
+       vty_out(vty, "Bridge port errors:       %" PRIu64 "\n", errs);
+
        return CMD_SUCCESS;
 }
 
@@ -3773,11 +3987,9 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_ROUTE_INSTALL:
        case DPLANE_OP_ROUTE_UPDATE:
        case DPLANE_OP_ROUTE_DELETE:
-               prefix2str(dplane_ctx_get_dest(ctx), buf, sizeof(buf));
-
-               zlog_debug("%u:%s Dplane route update ctx %p op %s",
-                          dplane_ctx_get_vrf(ctx), buf, ctx,
-                          dplane_op2str(dplane_ctx_get_op(ctx)));
+               zlog_debug("%u:%pFX Dplane route update ctx %p op %s",
+                          dplane_ctx_get_vrf(ctx), dplane_ctx_get_dest(ctx),
+                          ctx, dplane_op2str(dplane_ctx_get_op(ctx)));
                break;
 
        case DPLANE_OP_NH_INSTALL:
@@ -3804,11 +4016,10 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
 
        case DPLANE_OP_ADDR_INSTALL:
        case DPLANE_OP_ADDR_UNINSTALL:
-               prefix2str(dplane_ctx_get_intf_addr(ctx), buf, sizeof(buf));
-
-               zlog_debug("Dplane intf %s, idx %u, addr %s",
+               zlog_debug("Dplane intf %s, idx %u, addr %pFX",
                           dplane_op2str(dplane_ctx_get_op(ctx)),
-                          dplane_ctx_get_ifindex(ctx), buf);
+                          dplane_ctx_get_ifindex(ctx),
+                          dplane_ctx_get_intf_addr(ctx));
                break;
 
        case DPLANE_OP_MAC_INSTALL:
@@ -3848,6 +4059,7 @@ static void kernel_dplane_log_detail(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_SYS_ROUTE_DELETE:
        case DPLANE_OP_ROUTE_NOTIFY:
        case DPLANE_OP_LSP_NOTIFY:
+       case DPLANE_OP_BR_PORT_UPDATE:
 
        case DPLANE_OP_NONE:
                break;
@@ -3952,6 +4164,7 @@ static void kernel_dplane_handle_result(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_SYS_ROUTE_DELETE:
        case DPLANE_OP_ROUTE_NOTIFY:
        case DPLANE_OP_LSP_NOTIFY:
+       case DPLANE_OP_BR_PORT_UPDATE:
                break;
 
        case DPLANE_OP_NONE:
@@ -4122,6 +4335,14 @@ bool dplane_is_in_shutdown(void)
        return zdplane_info.dg_is_shutdown;
 }
 
+/*
+ * Enable collection of extra info about interfaces in route updates.
+ */
+void dplane_enable_intf_extra_info(void)
+{
+       dplane_collect_extra_intf_info = true;
+}
+
 /*
  * Early or pre-shutdown, de-init notification api. This runs pretty
  * early during zebra shutdown, as a signal to stop new work and prepare
index fd70211f7c8d93e22d989d9f41649e8580a2910d..1b2ea9d96bca2f77a42e3c128c845c5979187e14 100644 (file)
@@ -152,6 +152,9 @@ enum dplane_op_e {
 
        /* Link layer address discovery */
        DPLANE_OP_NEIGH_DISCOVER,
+
+       /* bridge port update */
+       DPLANE_OP_BR_PORT_UPDATE,
 };
 
 /*
@@ -184,6 +187,8 @@ enum dplane_op_e {
 #define DPLANE_NEIGH_SET_STATIC   (1 << 2)
 #define DPLANE_NEIGH_SET_INACTIVE (1 << 3)
 
+#define DPLANE_BR_PORT_NON_DF (1 << 0)
+
 /* Enable system route notifications */
 void dplane_enable_sys_route_notifs(void);
 
@@ -199,6 +204,9 @@ void dplane_enable_sys_route_notifs(void);
  */
 TAILQ_HEAD(dplane_ctx_q, zebra_dplane_ctx);
 
+/* Declare a type for (optional) extended interface info objects. */
+TAILQ_HEAD(dplane_intf_extra_q, dplane_intf_extra);
+
 /* Allocate a context object */
 struct zebra_dplane_ctx *dplane_ctx_alloc(void);
 
@@ -308,6 +316,21 @@ const struct nexthop_group *dplane_ctx_get_ng(
 const struct nexthop_group *dplane_ctx_get_old_ng(
        const struct zebra_dplane_ctx *ctx);
 
+/* Optional extra info about interfaces in nexthops - a plugin must enable
+ * this extra info.
+ */
+const struct dplane_intf_extra *
+dplane_ctx_get_intf_extra(const struct zebra_dplane_ctx *ctx);
+
+const struct dplane_intf_extra *
+dplane_ctx_intf_extra_next(const struct zebra_dplane_ctx *ctx,
+                          const struct dplane_intf_extra *ptr);
+
+vrf_id_t dplane_intf_extra_get_vrfid(const struct dplane_intf_extra *ptr);
+uint32_t dplane_intf_extra_get_ifindex(const struct dplane_intf_extra *ptr);
+uint32_t dplane_intf_extra_get_flags(const struct dplane_intf_extra *ptr);
+uint32_t dplane_intf_extra_get_status(const struct dplane_intf_extra *ptr);
+
 /* Backup nexthop information (list of nexthops) if present. */
 const struct nexthop_group *
 dplane_ctx_get_backup_ng(const struct zebra_dplane_ctx *ctx);
@@ -444,6 +467,15 @@ dplane_ctx_rule_get_dst_ip(const struct zebra_dplane_ctx *ctx);
 const struct prefix *
 dplane_ctx_rule_get_old_dst_ip(const struct zebra_dplane_ctx *ctx);
 
+/* Accessors for bridge port information */
+uint32_t dplane_ctx_get_br_port_flags(const struct zebra_dplane_ctx *ctx);
+uint32_t
+dplane_ctx_get_br_port_sph_filter_cnt(const struct zebra_dplane_ctx *ctx);
+const struct in_addr *
+dplane_ctx_get_br_port_sph_filters(const struct zebra_dplane_ctx *ctx);
+uint32_t
+dplane_ctx_get_br_port_backup_nhg_id(const struct zebra_dplane_ctx *ctx);
+
 /* Namespace info - esp. for netlink communication */
 const struct zebra_dplane_info *dplane_ctx_get_ns(
        const struct zebra_dplane_ctx *ctx);
@@ -479,6 +511,12 @@ enum zebra_dplane_result dplane_route_notif_update(
        enum dplane_op_e op,
        struct zebra_dplane_ctx *ctx);
 
+/*
+ * Enqueue bridge port changes for the dataplane.
+ */
+enum zebra_dplane_result dplane_br_port_update(
+       const struct interface *ifp, bool non_df, uint32_t sph_filter_cnt,
+       const struct in_addr *sph_filters, uint32_t backup_nhg_id);
 
 /* Forward ref of nhg_hash_entry */
 struct nhg_hash_entry;
@@ -723,6 +761,12 @@ void dplane_provider_enqueue_out_ctx(struct zebra_dplane_provider *prov,
 /* Enqueue a context directly to zebra main. */
 void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx);
 
+/* Enable collection of extra info about interfaces in route updates;
+ * this allows a provider/plugin to see some extra info in route update
+ * context objects.
+ */
+void dplane_enable_intf_extra_info(void);
+
 /*
  * Initialize the dataplane modules at zebra startup. This is currently called
  * by the rib module. Zebra registers a results callback with the dataplane.
index 56699c4e8375211b432df2fe68a12941b31ac5d3..6722af117cbe6dfba5e052884b2fb165195f39b9 100644 (file)
@@ -109,6 +109,7 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt)
        json_object *json = NULL;
        json_object *json_vtep_list = NULL;
        json_object *json_ip_str = NULL;
+       char buf[PREFIX_STRLEN];
 
        vty = ctxt[0];
        json = ctxt[1];
@@ -134,18 +135,20 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt)
        if (json == NULL) {
                vty_out(vty, " VxLAN interface: %s\n", zevpn->vxlan_if->name);
                vty_out(vty, " VxLAN ifIndex: %u\n", zevpn->vxlan_if->ifindex);
-               vty_out(vty, " Local VTEP IP: %s\n",
-                       inet_ntoa(zevpn->local_vtep_ip));
-               vty_out(vty, " Mcast group: %s\n",
-                               inet_ntoa(zevpn->mcast_grp));
+               vty_out(vty, " Local VTEP IP: %pI4\n",
+                       &zevpn->local_vtep_ip);
+               vty_out(vty, " Mcast group: %pI4\n",
+                               &zevpn->mcast_grp);
        } else {
                json_object_string_add(json, "vxlanInterface",
                                       zevpn->vxlan_if->name);
                json_object_int_add(json, "ifindex", zevpn->vxlan_if->ifindex);
                json_object_string_add(json, "vtepIp",
-                                      inet_ntoa(zevpn->local_vtep_ip));
+                                      inet_ntop(AF_INET, &zevpn->local_vtep_ip,
+                                                buf, sizeof(buf)));
                json_object_string_add(json, "mcastGroup",
-                               inet_ntoa(zevpn->mcast_grp));
+                                      inet_ntop(AF_INET, &zevpn->mcast_grp,
+                                                buf, sizeof(buf)));
                json_object_string_add(json, "advertiseGatewayMacip",
                                       zevpn->advertise_gw_macip ? "Yes" : "No");
                json_object_int_add(json, "numMacs", num_macs);
@@ -165,12 +168,14 @@ void zebra_evpn_print(zebra_evpn_t *zevpn, void **ctxt)
                                        VXLAN_FLOOD_STR_DEFAULT);
 
                        if (json == NULL) {
-                               vty_out(vty, "  %s flood: %s\n",
-                                               inet_ntoa(zvtep->vtep_ip),
+                               vty_out(vty, "  %pI4 flood: %s\n",
+                                               &zvtep->vtep_ip,
                                                flood_str);
                        } else {
                                json_ip_str = json_object_new_string(
-                                               inet_ntoa(zvtep->vtep_ip));
+                                               inet_ntop(AF_INET,
+                                                         &zvtep->vtep_ip, buf,
+                                                         sizeof(buf)));
                                json_object_array_add(json_vtep_list,
                                                json_ip_str);
                        }
@@ -207,6 +212,7 @@ void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
        json_object *json_evpn = NULL;
        json_object *json_ip_str = NULL;
        json_object *json_vtep_list = NULL;
+       char buf[PREFIX_STRLEN];
 
        vty = ctxt[0];
        json = ctxt[1];
@@ -245,7 +251,8 @@ void zebra_evpn_print_hash(struct hash_bucket *bucket, void *ctxt[])
                        json_vtep_list = json_object_new_array();
                        for (zvtep = zevpn->vteps; zvtep; zvtep = zvtep->next) {
                                json_ip_str = json_object_new_string(
-                                       inet_ntoa(zvtep->vtep_ip));
+                                       inet_ntop(AF_INET, &zvtep->vtep_ip, buf,
+                                                 sizeof(buf)));
                                json_object_array_add(json_vtep_list,
                                                      json_ip_str);
                        }
@@ -349,7 +356,6 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
 {
        struct zserv *client = NULL;
        struct stream *s = NULL;
-       char buf[PREFIX_STRLEN];
 
        client = zserv_find_client(ZEBRA_ROUTE_BGP, 0);
        /* BGP may not be running. */
@@ -365,8 +371,7 @@ static int ip_prefix_send_to_client(vrf_id_t vrf_id, struct prefix *p,
        stream_putw_at(s, 0, stream_get_endp(s));
 
        if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Send ip prefix %s %s on vrf %s",
-                          prefix2str(p, buf, sizeof(buf)),
+               zlog_debug("Send ip prefix %pFX %s on vrf %s", p,
                           (cmd == ZEBRA_IP_PREFIX_ROUTE_ADD) ? "ADD" : "DEL",
                           vrf_id_to_name(vrf_id));
 
@@ -1076,8 +1081,8 @@ int zebra_evpn_send_add_to_client(zebra_evpn_t *zevpn)
        stream_putw_at(s, 0, stream_get_endp(s));
 
        if (IS_ZEBRA_DEBUG_VXLAN)
-               zlog_debug("Send EVPN_ADD %u %s tenant vrf %s to %s", zevpn->vni,
-                          inet_ntoa(zevpn->local_vtep_ip),
+               zlog_debug("Send EVPN_ADD %u %pI4 tenant vrf %s to %s", zevpn->vni,
+                          &zevpn->local_vtep_ip,
                           vrf_id_to_name(zevpn->vrf_id),
                           zebra_route_string(client->proto));
 
index 75031ddba61789c3df462a8eda1936e56e2265ab..4a2d8db42237a5632b10e7f9dc74747bbf090d5e 100644 (file)
@@ -417,11 +417,11 @@ static void zebra_evpn_dup_addr_detect_for_mac(struct zebra_vrf *zvrf,
 
        if (mac->dad_count >= zvrf->dad_max_moves) {
                flog_warn(EC_ZEBRA_DUP_MAC_DETECTED,
-                         "VNI %u: MAC %s detected as duplicate during %s VTEP %s",
+                         "VNI %u: MAC %s detected as duplicate during %s VTEP %pI4",
                          mac->zevpn->vni,
                          prefix_mac2str(&mac->macaddr, buf, sizeof(buf)),
                          is_local ? "local update, last" :
-                         "remote update, from", inet_ntoa(vtep_ip));
+                         "remote update, from", &vtep_ip);
 
                SET_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE);
 
@@ -485,10 +485,13 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
        struct listnode *node = NULL;
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
+       char addr_buf[PREFIX_STRLEN];
        struct zebra_vrf *zvrf;
        struct timeval detect_start_time = {0, 0};
        char timebuf[MONOTIME_STRLEN];
        char thread_buf[THREAD_TIMER_STRLEN];
+       time_t uptime;
+       char up_str[MONOTIME_STRLEN];
 
        zvrf = zebra_vrf_get_evpn();
        if (!zvrf)
@@ -497,6 +500,11 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
        vty = (struct vty *)ctxt;
        prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1));
 
+       uptime = monotime(NULL);
+       uptime -= mac->uptime;
+
+       frrtime_to_interval(uptime, up_str, sizeof(up_str));
+
        if (json) {
                json_object *json_mac = json_object_new_object();
 
@@ -518,7 +526,8 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
                        json_object_string_add(json_mac, "type", "remote");
                        json_object_string_add(
                                json_mac, "remoteVtep",
-                               inet_ntoa(mac->fwd_info.r_vtep_ip));
+                               inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip,
+                                         addr_buf, sizeof(addr_buf)));
                } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO))
                        json_object_string_add(json_mac, "type", "auto");
 
@@ -533,6 +542,7 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
                        json_object_boolean_true_add(json_mac,
                                                     "remoteGatewayMac");
 
+               json_object_string_add(json_mac, "uptime", up_str);
                json_object_int_add(json_mac, "localSequence", mac->loc_seq);
                json_object_int_add(json_mac, "remoteSequence", mac->rem_seq);
 
@@ -617,8 +627,8 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
                                vty_out(vty, " Remote ES: %s",
                                        mac->es->esi_str);
                        else
-                               vty_out(vty, " Remote VTEP: %s",
-                                       inet_ntoa(mac->fwd_info.r_vtep_ip));
+                               vty_out(vty, " Remote VTEP: %pI4",
+                                       &mac->fwd_info.r_vtep_ip);
                } else if (CHECK_FLAG(mac->flags, ZEBRA_MAC_AUTO)) {
                        vty_out(vty, " Auto Mac ");
                }
@@ -646,9 +656,9 @@ void zebra_evpn_print_mac(zebra_mac_t *mac, void *ctxt, json_object *json)
                                                       sizeof(thread_buf),
                                                       mac->hold_timer));
                vty_out(vty, "\n");
-               vty_out(vty, " Local Seq: %u Remote Seq: %u", mac->loc_seq,
+               vty_out(vty, " Local Seq: %u Remote Seq: %u\n", mac->loc_seq,
                        mac->rem_seq);
-               vty_out(vty, "\n");
+               vty_out(vty, " Uptime: %s\n", up_str);
 
                if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
                        vty_out(vty, " Duplicate, detected at %s",
@@ -709,6 +719,7 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
        json_object *json_mac_hdr = NULL, *json_mac = NULL;
        zebra_mac_t *mac;
        char buf1[ETHER_ADDR_STRLEN];
+       char addr_buf[PREFIX_STRLEN];
        struct mac_walk_ctx *wctx = ctxt;
        char flags_buf[6];
 
@@ -785,18 +796,22 @@ void zebra_evpn_print_mac_hash(struct hash_bucket *bucket, void *ctxt)
                                        "Intf/Remote ES/VTEP", "VLAN",
                                        "Seq #'s");
                        }
+                       if (mac->es == NULL)
+                               inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip,
+                                         addr_buf, sizeof(addr_buf));
+
                        vty_out(vty, "%-17s %-6s %-5s %-30s %-5s %u/%u\n", buf1,
                                "remote",
                                zebra_evpn_print_mac_flags(mac, flags_buf,
-                sizeof(flags_buf)),
-                               mac->es ? mac->es->esi_str
-                                       : inet_ntoa(mac->fwd_info.r_vtep_ip),
+                                                          sizeof(flags_buf)),
+                               mac->es ? mac->es->esi_str : addr_buf,
                                "", mac->loc_seq, mac->rem_seq);
                } else {
                        json_object_string_add(json_mac, "type", "remote");
                        json_object_string_add(
                                json_mac, "remoteVtep",
-                               inet_ntoa(mac->fwd_info.r_vtep_ip));
+                               inet_ntop(AF_INET, &mac->fwd_info.r_vtep_ip,
+                                         addr_buf, sizeof(addr_buf)));
                        json_object_object_add(json_mac_hdr, buf1, json_mac);
                        json_object_int_add(json_mac, "localSequence",
                                            mac->loc_seq);
@@ -965,6 +980,7 @@ zebra_mac_t *zebra_evpn_mac_add(zebra_evpn_t *zevpn, struct ethaddr *macaddr)
        mac->neigh_list = list_new();
        mac->neigh_list->cmp = neigh_list_cmp;
 
+       mac->uptime = monotime(NULL);
        if (IS_ZEBRA_DEBUG_VXLAN || IS_ZEBRA_DEBUG_EVPN_MH_MAC) {
                char buf[ETHER_ADDR_STRLEN];
 
@@ -1452,6 +1468,8 @@ zebra_evpn_proc_sync_mac_update(zebra_evpn_t *zevpn, struct ethaddr *macaddr,
                bool sticky;
                bool remote_gw;
 
+               mac->uptime = monotime(NULL);
+
                old_flags = mac->flags;
                sticky = !!CHECK_FLAG(old_flags, ZEBRA_MAC_STICKY);
                remote_gw = !!CHECK_FLAG(old_flags, ZEBRA_MAC_REMOTE_DEF_GW);
@@ -1769,10 +1787,10 @@ int process_mac_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
                        mac = zebra_evpn_mac_add(zevpn, macaddr);
                        if (!mac) {
                                zlog_warn(
-                                       "Failed to add MAC %s VNI %u Remote VTEP %s",
+                                       "Failed to add MAC %s VNI %u Remote VTEP %pI4",
                                        prefix_mac2str(macaddr, buf,
                                                       sizeof(buf)),
-                                       zevpn->vni, inet_ntoa(vtep_ip));
+                                       zevpn->vni, &vtep_ip);
                                return -1;
                        }
 
@@ -2028,10 +2046,10 @@ int zebra_evpn_add_update_local_mac(struct zebra_vrf *zvrf, zebra_evpn_t *zevpn,
                        if (CHECK_FLAG(mac->flags, ZEBRA_MAC_STICKY)) {
                                flog_warn(
                                        EC_ZEBRA_STICKY_MAC_ALREADY_LEARNT,
-                                       "MAC %s already learnt as remote sticky MAC behind VTEP %s VNI %u",
+                                       "MAC %s already learnt as remote sticky MAC behind VTEP %pI4 VNI %u",
                                        prefix_mac2str(macaddr, buf,
                                                       sizeof(buf)),
-                                       inet_ntoa(mac->fwd_info.r_vtep_ip),
+                                       &mac->fwd_info.r_vtep_ip,
                                        zevpn->vni);
                                return 0;
                        }
index f9ca81445f6c7a622e4687f79554900581291634..596fd0faad0a723288fe5d39679a212457d50ccc 100644 (file)
@@ -129,6 +129,8 @@ struct zebra_mac_t_ {
         * ZEBRA_MAC_ES_PEER_ACTIVE or ZEBRA_NEIGH_ES_PEER_PROXY
         */
        uint32_t sync_neigh_cnt;
+
+       time_t uptime;
 };
 
 /*
index f71065cdcffdb1586acc6f02705fcb2dcd9cb950..692dfca5d7c292a7adbf382e8dded8d21c07dad8 100644 (file)
@@ -38,6 +38,7 @@
 #include "zebra/rib.h"
 #include "zebra/rt.h"
 #include "zebra/rt_netlink.h"
+#include "zebra/if_netlink.h"
 #include "zebra/zebra_errors.h"
 #include "zebra/zebra_l2.h"
 #include "zebra/zebra_memory.h"
@@ -63,6 +64,11 @@ static int zebra_evpn_es_evi_send_to_client(struct zebra_evpn_es *es,
 static void zebra_evpn_local_es_del(struct zebra_evpn_es **esp);
 static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid,
                struct ethaddr *sysmac);
+static bool zebra_evpn_es_br_port_dplane_update(struct zebra_evpn_es *es,
+                                               const char *caller);
+static void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set);
+static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es);
+static void zebra_evpn_mh_clear_protodown_es(struct zebra_evpn_es *es);
 
 esi_t zero_esi_buf, *zero_esi = &zero_esi_buf;
 
@@ -253,12 +259,29 @@ static void zebra_evpn_local_es_evi_add(struct zebra_evpn_es *es,
 }
 
 static void zebra_evpn_es_evi_show_entry(struct vty *vty,
-               struct zebra_evpn_es_evi *es_evi, json_object *json)
+                                        struct zebra_evpn_es_evi *es_evi,
+                                        json_object *json_array)
 {
        char type_str[4];
 
-       if (json) {
-               /* XXX */
+       if (json_array) {
+               json_object *json;
+               json_object *json_types;
+
+               /* Separate JSON object for each es-evi entry */
+               json = json_object_new_object();
+
+               json_object_string_add(json, "esi", es_evi->es->esi_str);
+               json_object_int_add(json, "vni", es_evi->zevpn->vni);
+               if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL) {
+                       json_types = json_object_new_array();
+                       if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL)
+                               json_array_string_add(json_types, "local");
+                       json_object_object_add(json, "type", json_types);
+               }
+
+               /* Add es-evi entry to json array */
+               json_object_array_add(json_array, json);
        } else {
                type_str[0] = '\0';
                if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL)
@@ -270,13 +293,36 @@ static void zebra_evpn_es_evi_show_entry(struct vty *vty,
        }
 }
 
-static void zebra_evpn_es_evi_show_entry_detail(struct vty *vty,
-               struct zebra_evpn_es_evi *es_evi, json_object *json)
+static void
+zebra_evpn_es_evi_show_entry_detail(struct vty *vty,
+                                   struct zebra_evpn_es_evi *es_evi,
+                                   json_object *json_array)
 {
        char type_str[4];
 
-       if (json) {
-               /* XXX */
+       if (json_array) {
+               json_object *json;
+               json_object *json_flags;
+
+               /* Separate JSON object for each es-evi entry */
+               json = json_object_new_object();
+
+               json_object_string_add(json, "esi", es_evi->es->esi_str);
+               json_object_int_add(json, "vni", es_evi->zevpn->vni);
+               if (es_evi->flags
+                   & (ZEBRA_EVPNES_EVI_LOCAL
+                      | ZEBRA_EVPNES_EVI_READY_FOR_BGP)) {
+                       json_flags = json_object_new_array();
+                       if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL)
+                               json_array_string_add(json_flags, "local");
+                       if (es_evi->flags & ZEBRA_EVPNES_EVI_READY_FOR_BGP)
+                               json_array_string_add(json_flags,
+                                                     "readyForBgp");
+                       json_object_object_add(json, "flags", json_flags);
+               }
+
+               /* Add es-evi entry to json array */
+               json_object_array_add(json_array, json);
        } else {
                type_str[0] = '\0';
                if (es_evi->flags & ZEBRA_EVPNES_EVI_LOCAL)
@@ -294,15 +340,17 @@ static void zebra_evpn_es_evi_show_entry_detail(struct vty *vty,
 }
 
 static void zebra_evpn_es_evi_show_one_evpn(zebra_evpn_t *zevpn,
-               struct vty *vty, json_object *json, int detail)
+                                           struct vty *vty,
+                                           json_object *json_array, int detail)
 {
        struct zebra_evpn_es_evi *es_evi;
 
        RB_FOREACH(es_evi, zebra_es_evi_rb_head, &zevpn->es_evi_rb_tree) {
                if (detail)
-                       zebra_evpn_es_evi_show_entry_detail(vty, es_evi, json);
+                       zebra_evpn_es_evi_show_entry_detail(vty, es_evi,
+                                                           json_array);
                else
-                       zebra_evpn_es_evi_show_entry(vty, es_evi, json);
+                       zebra_evpn_es_evi_show_entry(vty, es_evi, json_array);
        }
 }
 
@@ -324,42 +372,64 @@ static void zebra_evpn_es_evi_show_one_evpn_hash_cb(struct hash_bucket *bucket,
 
 void zebra_evpn_es_evi_show(struct vty *vty, bool uj, int detail)
 {
-       json_object *json = NULL;
+       json_object *json_array = NULL;
        struct zebra_vrf *zvrf;
        struct evpn_mh_show_ctx wctx;
 
        zvrf = zebra_vrf_get_evpn();
+       if (uj)
+               json_array = json_object_new_array();
 
        memset(&wctx, 0, sizeof(wctx));
        wctx.vty = vty;
-       wctx.json = json;
+       wctx.json = json_array;
        wctx.detail = detail;
 
-       if (!detail && !json) {
+       if (!detail && !json_array) {
                vty_out(vty, "Type: L local, R remote\n");
                vty_out(vty, "%-8s %-30s %-4s\n", "VNI", "ESI", "Type");
        }
        /* Display all L2-VNIs */
        hash_iterate(zvrf->evpn_table, zebra_evpn_es_evi_show_one_evpn_hash_cb,
                        &wctx);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
+       }
 }
 
 void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj, vni_t vni, int detail)
 {
-       json_object *json = NULL;
+       json_object *json_array = NULL;
        zebra_evpn_t *zevpn;
 
        zevpn = zebra_evpn_lookup(vni);
+       if (uj)
+               json_array = json_object_new_array();
+
        if (zevpn) {
-               if (!detail && !json) {
+               if (!detail && !json_array) {
                        vty_out(vty, "Type: L local, R remote\n");
                        vty_out(vty, "%-8s %-30s %-4s\n", "VNI", "ESI", "Type");
                }
        } else {
                if (!uj)
                        vty_out(vty, "VNI %d doesn't exist\n", vni);
+
+               return;
+       }
+
+       zebra_evpn_es_evi_show_one_evpn(zevpn, vty, json_array, detail);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
        }
-       zebra_evpn_es_evi_show_one_evpn(zevpn, vty, json, detail);
 }
 
 /* Initialize the ES tables maintained per-L2_VNI */
@@ -687,6 +757,37 @@ void zebra_evpn_vl_mbr_deref(uint16_t vid, struct zebra_if *zif)
        zebra_evpn_acc_bd_free_on_deref(acc_bd);
 }
 
+static void zebra_evpn_acc_vl_json_fill(struct zebra_evpn_access_bd *acc_bd,
+                                       json_object *json, bool detail)
+{
+       json_object_int_add(json, "vlan", acc_bd->vid);
+       if (acc_bd->vxlan_zif)
+               json_object_string_add(json, "vxlanIf",
+                                      acc_bd->vxlan_zif->ifp->name);
+       if (acc_bd->zevpn)
+               json_object_int_add(json, "vni", acc_bd->zevpn->vni);
+       if (acc_bd->mbr_zifs)
+               json_object_int_add(json, "memberIfCount",
+                                   listcount(acc_bd->mbr_zifs));
+
+       if (detail) {
+               json_object *json_mbrs;
+               json_object *json_mbr;
+               struct zebra_if *zif;
+               struct listnode *node;
+
+
+               json_mbrs = json_object_new_array();
+               for (ALL_LIST_ELEMENTS_RO(acc_bd->mbr_zifs, node, zif)) {
+                       json_mbr = json_object_new_object();
+                       json_object_string_add(json_mbr, "ifName",
+                                              zif->ifp->name);
+                       json_object_array_add(json_mbrs, json_mbr);
+               }
+               json_object_object_add(json, "members", json_mbrs);
+       }
+}
+
 static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty,
                struct zebra_evpn_access_bd *acc_bd, json_object *json)
 {
@@ -694,7 +795,7 @@ static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty,
        struct listnode *node;
 
        if (json) {
-               /* XXX */
+               zebra_evpn_acc_vl_json_fill(acc_bd, json, true);
        } else {
                vty_out(vty, "VLAN: %u\n", acc_bd->vid);
                vty_out(vty, " VxLAN Interface: %s\n",
@@ -714,58 +815,83 @@ static void zebra_evpn_acc_vl_show_entry_detail(struct vty *vty,
 static void zebra_evpn_acc_vl_show_entry(struct vty *vty,
                struct zebra_evpn_access_bd *acc_bd, json_object *json)
 {
-       if (!json)
+       if (json) {
+               zebra_evpn_acc_vl_json_fill(acc_bd, json, false);
+       } else {
                vty_out(vty, "%-5u %21s %-8d %u\n",
                                acc_bd->vid,
                                acc_bd->vxlan_zif ?
                                acc_bd->vxlan_zif->ifp->name : "-",
                                acc_bd->zevpn ? acc_bd->zevpn->vni : 0,
                                listcount(acc_bd->mbr_zifs));
+       }
 }
 
 static void zebra_evpn_acc_vl_show_hash(struct hash_bucket *bucket, void *ctxt)
 {
        struct evpn_mh_show_ctx *wctx = ctxt;
        struct zebra_evpn_access_bd *acc_bd = bucket->data;
+       json_object *json = NULL;
 
+       if (wctx->json)
+               json = json_object_new_object();
        if (wctx->detail)
-               zebra_evpn_acc_vl_show_entry_detail(wctx->vty,
-                               acc_bd, wctx->json);
+               zebra_evpn_acc_vl_show_entry_detail(wctx->vty, acc_bd, json);
        else
-               zebra_evpn_acc_vl_show_entry(wctx->vty,
-                               acc_bd, wctx->json);
+               zebra_evpn_acc_vl_show_entry(wctx->vty, acc_bd, json);
+       if (json)
+               json_object_array_add(wctx->json, json);
 }
 
 void zebra_evpn_acc_vl_show(struct vty *vty, bool uj)
 {
-       json_object *json = NULL;
        struct evpn_mh_show_ctx wctx;
+       json_object *json_array = NULL;
+
+       if (uj)
+               json_array = json_object_new_array();
 
        memset(&wctx, 0, sizeof(wctx));
        wctx.vty = vty;
-       wctx.json = json;
+       wctx.json = json_array;
        wctx.detail = false;
 
-       if (!json)
+       if (!uj)
                vty_out(vty, "%-5s %21s %-8s %s\n",
                                "VLAN", "VxLAN-IF", "L2-VNI", "# Members");
 
        hash_iterate(zmh_info->evpn_vlan_table, zebra_evpn_acc_vl_show_hash,
                        &wctx);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
+       }
 }
 
 void zebra_evpn_acc_vl_show_detail(struct vty *vty, bool uj)
 {
-       json_object *json = NULL;
        struct evpn_mh_show_ctx wctx;
+       json_object *json_array = NULL;
 
+       if (uj)
+               json_array = json_object_new_array();
        memset(&wctx, 0, sizeof(wctx));
        wctx.vty = vty;
-       wctx.json = json;
+       wctx.json = json_array;
        wctx.detail = true;
 
        hash_iterate(zmh_info->evpn_vlan_table, zebra_evpn_acc_vl_show_hash,
                        &wctx);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
+       }
 }
 
 void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid)
@@ -773,14 +899,23 @@ void zebra_evpn_acc_vl_show_vid(struct vty *vty, bool uj, vlanid_t vid)
        json_object *json = NULL;
        struct zebra_evpn_access_bd *acc_bd;
 
+       if (uj)
+               json = json_object_new_object();
+
        acc_bd = zebra_evpn_acc_vl_find(vid);
-       if (!acc_bd) {
-               if (!json) {
+       if (acc_bd) {
+               zebra_evpn_acc_vl_show_entry_detail(vty, acc_bd, json);
+       } else {
+               if (!json)
                        vty_out(vty, "VLAN %u not present\n", vid);
-                       return;
-               }
        }
-       zebra_evpn_acc_vl_show_entry_detail(vty, acc_bd, json);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 /* Initialize VLAN member bitmap on an interface. Although VLAN membership
@@ -808,6 +943,7 @@ void zebra_evpn_if_init(struct zebra_if *zif)
 void zebra_evpn_if_cleanup(struct zebra_if *zif)
 {
        vlanid_t vid;
+       struct zebra_evpn_es *es;
 
        if (!bf_is_inited(zif->vlan_bitmap))
                return;
@@ -819,8 +955,9 @@ void zebra_evpn_if_cleanup(struct zebra_if *zif)
        bf_free(zif->vlan_bitmap);
 
        /* Delete associated Ethernet Segment */
-       if (zif->es_info.es)
-               zebra_evpn_local_es_del(&zif->es_info.es);
+       es = zif->es_info.es;
+       if (es)
+               zebra_evpn_local_es_del(&es);
 }
 
 /*****************************************************************************
@@ -893,12 +1030,23 @@ static void zebra_evpn_nhg_update(struct zebra_evpn_es *es)
 
                es->flags |= ZEBRA_EVPNES_NHG_ACTIVE;
                kernel_upd_mac_nhg(es->nhg_id, nh_cnt, nh_ids);
+               if (!(es->flags & ZEBRA_EVPNES_NHG_ACTIVE)) {
+                       es->flags |= ZEBRA_EVPNES_NHG_ACTIVE;
+                       /* add backup NHG to the br-port */
+                       if ((es->flags & ZEBRA_EVPNES_LOCAL))
+                               zebra_evpn_es_br_port_dplane_update(es,
+                                                                   __func__);
+               }
        } else {
                if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) {
                        if (IS_ZEBRA_DEBUG_EVPN_MH_NH)
                                zlog_debug("es %s nhg 0x%x del",
                                                es->esi_str, es->nhg_id);
                        es->flags &= ~ZEBRA_EVPNES_NHG_ACTIVE;
+                       /* remove backup NHG from the br-port */
+                       if ((es->flags & ZEBRA_EVPNES_LOCAL))
+                               zebra_evpn_es_br_port_dplane_update(es,
+                                                                   __func__);
                        kernel_del_mac_nhg(es->nhg_id);
                }
        }
@@ -917,9 +1065,9 @@ static void zebra_evpn_nh_add(struct zebra_evpn_es_vtep *es_vtep)
                return;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_NH)
-               zlog_debug("es %s vtep %s nh 0x%x add",
+               zlog_debug("es %s vtep %pI4 nh 0x%x add",
                                es_vtep->es->esi_str,
-                               inet_ntoa(es_vtep->vtep_ip), es_vtep->nh_id);
+                               &es_vtep->vtep_ip, es_vtep->nh_id);
        /* install the NH */
        kernel_upd_mac_nh(es_vtep->nh_id, es_vtep->vtep_ip);
        /* add the NH to the parent NHG */
@@ -934,9 +1082,9 @@ static void zebra_evpn_nh_del(struct zebra_evpn_es_vtep *es_vtep)
                return;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_NH)
-               zlog_debug("es %s vtep %s nh 0x%x del",
+               zlog_debug("es %s vtep %pI4 nh 0x%x del",
                                es_vtep->es->esi_str,
-                               inet_ntoa(es_vtep->vtep_ip), es_vtep->nh_id);
+                               &es_vtep->vtep_ip, es_vtep->nh_id);
 
        nh_id = es_vtep->nh_id;
        es_vtep->nh_id = 0;
@@ -1013,34 +1161,215 @@ static struct zebra_evpn_es_vtep *zebra_evpn_es_vtep_find(
        return NULL;
 }
 
+/* flush all the dataplane br-port info associated with the ES */
+static bool zebra_evpn_es_br_port_dplane_clear(struct zebra_evpn_es *es)
+{
+       struct in_addr sph_filters[ES_VTEP_MAX_CNT];
+
+       if (!(es->flags & ZEBRA_EVPNES_BR_PORT))
+               return false;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("es %s br-port dplane clear", es->esi_str);
+
+       memset(&sph_filters, 0, sizeof(sph_filters));
+       dplane_br_port_update(es->zif->ifp, false /* non_df */, 0, sph_filters,
+                             0 /* backup_nhg_id */);
+       return true;
+}
+
+static inline bool
+zebra_evpn_es_br_port_dplane_update_needed(struct zebra_evpn_es *es)
+{
+       return (es->flags & ZEBRA_EVPNES_NON_DF)
+              || (es->flags & ZEBRA_EVPNES_NHG_ACTIVE)
+              || listcount(es->es_vtep_list);
+}
+
+/* returns TRUE if dplane entry was updated */
+static bool zebra_evpn_es_br_port_dplane_update(struct zebra_evpn_es *es,
+                                               const char *caller)
+{
+       uint32_t backup_nhg_id;
+       struct in_addr sph_filters[ES_VTEP_MAX_CNT];
+       struct listnode *node = NULL;
+       struct zebra_evpn_es_vtep *es_vtep;
+       uint32_t sph_filter_cnt = 0;
+
+       if (!(es->flags & ZEBRA_EVPNES_LOCAL))
+               return zebra_evpn_es_br_port_dplane_clear(es);
+
+       /* If the ES is not a bridge port there is nothing
+        * in the dataplane
+        */
+       if (!(es->flags & ZEBRA_EVPNES_BR_PORT))
+               return false;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("es %s br-port dplane update by %s", es->esi_str, caller);
+       backup_nhg_id = (es->flags & ZEBRA_EVPNES_NHG_ACTIVE) ? es->nhg_id : 0;
+
+       memset(&sph_filters, 0, sizeof(sph_filters));
+       if (listcount(es->es_vtep_list) > ES_VTEP_MAX_CNT) {
+               zlog_warn("es %s vtep count %d exceeds filter cnt %d",
+                         es->esi_str, listcount(es->es_vtep_list),
+                         ES_VTEP_MAX_CNT);
+       } else {
+               for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) {
+                       if (es_vtep->flags & ZEBRA_EVPNES_VTEP_DEL_IN_PROG)
+                               continue;
+                       sph_filters[sph_filter_cnt] = es_vtep->vtep_ip;
+                       ++sph_filter_cnt;
+               }
+       }
+
+       dplane_br_port_update(es->zif->ifp, !!(es->flags & ZEBRA_EVPNES_NON_DF),
+                             sph_filter_cnt, sph_filters, backup_nhg_id);
+
+       return true;
+}
+
+/* returns TRUE if dplane entry was updated */
+static bool zebra_evpn_es_df_change(struct zebra_evpn_es *es, bool new_non_df,
+                                   const char *caller)
+{
+       bool old_non_df;
+
+       old_non_df = !!(es->flags & ZEBRA_EVPNES_NON_DF);
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("df-change(%s) es %s old %s new %s", caller,
+                          es->esi_str, old_non_df ? "non-df" : "df",
+                          new_non_df ? "non-df" : "df");
+
+       if (old_non_df == new_non_df)
+               return false;
+
+       if (new_non_df)
+               es->flags |= ZEBRA_EVPNES_NON_DF;
+       else
+               es->flags &= ~ZEBRA_EVPNES_NON_DF;
+
+       /* update non-DF block filter in the dataplane */
+       return zebra_evpn_es_br_port_dplane_update(es, __func__);
+}
+
+
+/* returns TRUE if dplane entry was updated */
+static bool zebra_evpn_es_run_df_election(struct zebra_evpn_es *es,
+                                         const char *caller)
+{
+       struct listnode *node = NULL;
+       struct zebra_evpn_es_vtep *es_vtep;
+       bool new_non_df = false;
+
+       /* If the ES is not ready (i.e. not completely configured) there
+        * is no need to setup the BUM block filter
+        */
+       if (!(es->flags & ZEBRA_EVPNES_LOCAL)
+           || !zmh_info->es_originator_ip.s_addr)
+               return zebra_evpn_es_df_change(es, new_non_df, caller);
+
+       /* if oper-state is down DF filtering must be on. when the link comes
+        * up again dataplane should block BUM till FRR has had the chance
+        * to run DF election again
+        */
+       if (!(es->flags & ZEBRA_EVPNES_OPER_UP)) {
+               new_non_df = true;
+               return zebra_evpn_es_df_change(es, new_non_df, caller);
+       }
+
+       for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) {
+               /* Only VTEPs that have advertised the ESR can participate
+                * in DF election
+                */
+               if (!(es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR))
+                       continue;
+
+               /* If the DF alg is not the same we should fall back to
+                * service-carving. But as service-carving is not supported
+                * we will stop forwarding BUM
+                */
+               if (es_vtep->df_alg != EVPN_MH_DF_ALG_PREF) {
+                       new_non_df = true;
+                       break;
+               }
+
+               /* Peer VTEP wins DF election if -
+                * the peer-VTEP has higher preference (or)
+                * the pref is the same but peer's IP address is lower
+                */
+               if ((es_vtep->df_pref > es->df_pref)
+                   || ((es_vtep->df_pref == es->df_pref)
+                       && (es_vtep->vtep_ip.s_addr
+                           < zmh_info->es_originator_ip.s_addr))) {
+                       new_non_df = true;
+                       break;
+               }
+       }
+
+       return zebra_evpn_es_df_change(es, new_non_df, caller);
+}
+
 static void zebra_evpn_es_vtep_add(struct zebra_evpn_es *es,
-               struct in_addr vtep_ip)
+                                  struct in_addr vtep_ip, bool esr_rxed,
+                                  uint8_t df_alg, uint16_t df_pref)
 {
        struct zebra_evpn_es_vtep *es_vtep;
+       bool old_esr_rxed;
+       bool dplane_updated = false;
 
        es_vtep = zebra_evpn_es_vtep_find(es, vtep_ip);
 
        if (!es_vtep) {
                if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-                       zlog_debug("es %s vtep %s add",
-                                       es->esi_str, inet_ntoa(vtep_ip));
+                       zlog_debug("es %s vtep %pI4 add",
+                                       es->esi_str, &vtep_ip);
                es_vtep = zebra_evpn_es_vtep_new(es, vtep_ip);
                /* update the L2-NHG associated with the ES */
                zebra_evpn_nh_add(es_vtep);
        }
+
+       old_esr_rxed = !!(es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR);
+       if ((old_esr_rxed != esr_rxed) || (es_vtep->df_alg != df_alg)
+           || (es_vtep->df_pref != df_pref)) {
+               /* If any of the DF election params changed we need to re-run
+                * DF election
+                */
+               if (esr_rxed)
+                       es_vtep->flags |= ZEBRA_EVPNES_VTEP_RXED_ESR;
+               else
+                       es_vtep->flags &= ~ZEBRA_EVPNES_VTEP_RXED_ESR;
+               es_vtep->df_alg = df_alg;
+               es_vtep->df_pref = df_pref;
+               dplane_updated = zebra_evpn_es_run_df_election(es, __func__);
+       }
+       /* add the vtep to the SPH list */
+       if (!dplane_updated && (es->flags & ZEBRA_EVPNES_LOCAL))
+               zebra_evpn_es_br_port_dplane_update(es, __func__);
 }
 
 static void zebra_evpn_es_vtep_del(struct zebra_evpn_es *es,
                struct in_addr vtep_ip)
 {
        struct zebra_evpn_es_vtep *es_vtep;
+       bool dplane_updated = false;
 
        es_vtep = zebra_evpn_es_vtep_find(es, vtep_ip);
 
        if (es_vtep) {
                if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-                       zlog_debug("es %s vtep %s del",
-                                       es->esi_str, inet_ntoa(vtep_ip));
+                       zlog_debug("es %s vtep %pI4 del",
+                                       es->esi_str, &vtep_ip);
+               es_vtep->flags |= ZEBRA_EVPNES_VTEP_DEL_IN_PROG;
+               if (es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR) {
+                       es_vtep->flags &= ~ZEBRA_EVPNES_VTEP_RXED_ESR;
+                       dplane_updated =
+                               zebra_evpn_es_run_df_election(es, __func__);
+               }
+               /* remove the vtep from the SPH list */
+               if (!dplane_updated && (es->flags & ZEBRA_EVPNES_LOCAL))
+                       zebra_evpn_es_br_port_dplane_update(es, __func__);
                zebra_evpn_es_vtep_free(es_vtep);
        }
 }
@@ -1161,15 +1490,16 @@ static int zebra_evpn_es_send_add_to_client(struct zebra_evpn_es *es)
        stream_put_ipv4(s, zmh_info->es_originator_ip.s_addr);
        oper_up = !!(es->flags & ZEBRA_EVPNES_OPER_UP);
        stream_putc(s, oper_up);
+       stream_putw(s, es->df_pref);
 
        /* Write packet size. */
        stream_putw_at(s, 0, stream_get_endp(s));
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("send add local es %s %s to %s",
-                               es->esi_str,
-                               inet_ntoa(zmh_info->es_originator_ip),
-                               zebra_route_string(client->proto));
+               zlog_debug("send add local es %s %pI4 active %u df_pref %u to %s",
+                          es->esi_str, &zmh_info->es_originator_ip,
+                          oper_up, es->df_pref,
+                          zebra_route_string(client->proto));
 
        client->local_es_add_cnt++;
        return zserv_send_message(client, s);
@@ -1306,6 +1636,30 @@ static void zebra_evpn_es_local_mac_update(struct zebra_evpn_es *es,
        }
 }
 
+void zebra_evpn_es_local_br_port_update(struct zebra_if *zif)
+{
+       struct zebra_evpn_es *es = zif->es_info.es;
+       bool old_br_port = !!(es->flags & ZEBRA_EVPNES_BR_PORT);
+       bool new_br_port;
+
+       if (zif->brslave_info.bridge_ifindex != IFINDEX_INTERNAL)
+               es->flags |= ZEBRA_EVPNES_BR_PORT;
+       else
+               es->flags &= ~ZEBRA_EVPNES_BR_PORT;
+
+       new_br_port = !!(es->flags & ZEBRA_EVPNES_BR_PORT);
+       if (old_br_port == new_br_port)
+               return;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("es %s br_port change old %u new %u", es->esi_str,
+                          old_br_port, new_br_port);
+
+       /* update the dataplane br_port attrs */
+       if (new_br_port && zebra_evpn_es_br_port_dplane_update_needed(es))
+               zebra_evpn_es_br_port_dplane_update(es, __func__);
+}
+
 static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es,
                struct zebra_if *zif)
 {
@@ -1322,12 +1676,17 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es,
 
        /* attach es to interface */
        zif->es_info.es = es;
+       es->df_pref = zif->es_info.df_pref ? zif->es_info.df_pref
+                                          : EVPN_MH_DF_PREF_DEFAULT;
 
        /* attach interface to es */
        es->zif = zif;
        if (if_is_operative(zif->ifp))
                es->flags |= ZEBRA_EVPNES_OPER_UP;
 
+       if (zif->brslave_info.bridge_ifindex != IFINDEX_INTERNAL)
+               es->flags |= ZEBRA_EVPNES_BR_PORT;
+
        /* setup base-vni if one doesn't already exist; the ES will get sent
         * to BGP as a part of that process
         */
@@ -1338,6 +1697,16 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es,
                zebra_evpn_es_re_eval_send_to_client(es,
                        false /* es_evi_re_reval */);
 
+       /* See if the local VTEP can function as DF on the ES */
+       if (!zebra_evpn_es_run_df_election(es, __func__)) {
+               /* check if the dplane entry needs to be re-programmed as a
+                * result of some thing other than DF status change
+                */
+               if (zebra_evpn_es_br_port_dplane_update_needed(es))
+                       zebra_evpn_es_br_port_dplane_update(es, __func__);
+       }
+
+
        /* Setup ES-EVIs for all VxLAN stretched VLANs associated with
         * the zif
         */
@@ -1348,29 +1717,46 @@ static void zebra_evpn_es_local_info_set(struct zebra_evpn_es *es,
         */
        zebra_evpn_es_local_mac_update(es,
                        false /* force_clear_static */);
+
+       /* inherit EVPN protodown flags on the access port */
+       zebra_evpn_mh_update_protodown_es(es);
 }
 
 static void zebra_evpn_es_local_info_clear(struct zebra_evpn_es **esp)
 {
        struct zebra_if *zif;
        struct zebra_evpn_es *es = *esp;
+       bool dplane_updated = false;
 
        if (!(es->flags & ZEBRA_EVPNES_LOCAL))
                return;
 
        es->flags &= ~(ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_READY_FOR_BGP);
 
+       /* remove the DF filter */
+       dplane_updated = zebra_evpn_es_run_df_election(es, __func__);
+
+       /* clear EVPN protodown flags on the access port */
+       zebra_evpn_mh_clear_protodown_es(es);
+
        /* if there any local macs referring to the ES as dest we
         * need to clear the static reference on them
         */
        zebra_evpn_es_local_mac_update(es,
                        true /* force_clear_static */);
 
+       /* flush the BUM filters and backup NHG */
+       if (!dplane_updated)
+               zebra_evpn_es_br_port_dplane_clear(es);
+
        /* clear the es from the parent interface */
        zif = es->zif;
        zif->es_info.es = NULL;
        es->zif = NULL;
 
+       /* clear all local flags associated with the ES */
+       es->flags &= ~(ZEBRA_EVPNES_OPER_UP | ZEBRA_EVPNES_BR_PORT);
+
        /* remove from the ES list */
        list_delete_node(zmh_info->local_es_list, &es->local_es_listnode);
 
@@ -1448,7 +1834,7 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid,
        if (!lid || is_zero_mac(sysmac)) {
                /* if in ES is attached to zif delete it */
                if (old_es)
-                       zebra_evpn_local_es_del(&zif->es_info.es);
+                       zebra_evpn_local_es_del(&old_es);
                return 0;
        }
 
@@ -1473,7 +1859,7 @@ static int zebra_evpn_local_es_update(struct zebra_if *zif, uint32_t lid,
 
        /* release the old_es against the zif */
        if (old_es)
-               zebra_evpn_local_es_del(&zif->es_info.es);
+               zebra_evpn_local_es_del(&old_es);
 
        es = zebra_evpn_es_find(&esi);
        if (es) {
@@ -1496,9 +1882,8 @@ static int zebra_evpn_remote_es_del(esi_t *esi, struct in_addr vtep_ip)
        struct zebra_evpn_es *es;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("remote es %s vtep %s del",
-                               esi_to_str(esi, buf, sizeof(buf)),
-                               inet_ntoa(vtep_ip));
+               zlog_debug("remote es %s vtep %pI4 del",
+                          esi_to_str(esi, buf, sizeof(buf)), &vtep_ip);
 
        es = zebra_evpn_es_find(esi);
        if (!es) {
@@ -1523,23 +1908,26 @@ static void zebra_evpn_remote_es_flush(struct zebra_evpn_es **esp)
 
        for (ALL_LIST_ELEMENTS(es->es_vtep_list, node, nnode, es_vtep)) {
                if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-                       zlog_debug("es %s vtep %s flush",
+                       zlog_debug("es %s vtep %pI4 flush",
                                        es->esi_str,
-                                       inet_ntoa(es_vtep->vtep_ip));
+                                       &es_vtep->vtep_ip);
                zebra_evpn_es_vtep_free(es_vtep);
        }
        zebra_evpn_es_remote_info_re_eval(esp);
 }
 
-static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip)
+static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip,
+                                   bool esr_rxed, uint8_t df_alg,
+                                   uint16_t df_pref)
 {
        char buf[ESI_STR_LEN];
        struct zebra_evpn_es *es;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("remote es %s vtep %s add",
-                               esi_to_str(esi, buf, sizeof(buf)),
-                               inet_ntoa(vtep_ip));
+               zlog_debug("remote es %s vtep %pI4 add %s df_alg %d df_pref %d",
+                          esi_to_str(esi, buf, sizeof(buf)),
+                          &vtep_ip, esr_rxed ? "esr" : "", df_alg,
+                          df_pref);
 
        es = zebra_evpn_es_find(esi);
        if (!es) {
@@ -1552,7 +1940,13 @@ static int zebra_evpn_remote_es_add(esi_t *esi, struct in_addr vtep_ip)
                }
        }
 
-       zebra_evpn_es_vtep_add(es, vtep_ip);
+       if (df_alg != EVPN_MH_DF_ALG_PREF)
+               zlog_warn(
+                       "remote es %s vtep %pI4 add %s with unsupported df_alg %d",
+                       esi_to_str(esi, buf, sizeof(buf)), &vtep_ip,
+                       esr_rxed ? "esr" : "", df_alg);
+
+       zebra_evpn_es_vtep_add(es, vtep_ip, esr_rxed, df_alg, df_pref);
        zebra_evpn_es_remote_info_re_eval(&es);
 
        return 0;
@@ -1577,10 +1971,22 @@ void zebra_evpn_proc_remote_es(ZAPI_HANDLER_ARGS)
        stream_get(&esi, s, sizeof(esi_t));
        vtep_ip.s_addr = stream_get_ipv4(s);
 
-       if (hdr->command == ZEBRA_REMOTE_ES_VTEP_ADD)
-               zebra_evpn_remote_es_add(&esi, vtep_ip);
-       else
+       if (hdr->command == ZEBRA_REMOTE_ES_VTEP_ADD) {
+               uint32_t zapi_flags;
+               uint8_t df_alg;
+               uint16_t df_pref;
+               bool esr_rxed;
+
+               zapi_flags = stream_getl(s);
+               esr_rxed = (zapi_flags & ZAPI_ES_VTEP_FLAG_ESR_RXED) ? true
+                                                                    : false;
+               df_alg = stream_getc(s);
+               df_pref = stream_getw(s);
+               zebra_evpn_remote_es_add(&esi, vtep_ip, esr_rxed, df_alg,
+                                        df_pref);
+       } else {
                zebra_evpn_remote_es_del(&esi, vtep_ip);
+       }
 }
 
 void zebra_evpn_es_mac_deref_entry(zebra_mac_t *mac)
@@ -1706,6 +2112,35 @@ void zebra_evpn_es_cleanup(void)
        }
 }
 
+static void zebra_evpn_es_df_pref_update(struct zebra_if *zif, uint16_t df_pref)
+{
+       struct zebra_evpn_es *es;
+       uint16_t tmp_pref;
+
+       if (zif->es_info.df_pref == df_pref)
+               return;
+
+       zif->es_info.df_pref = df_pref;
+       es = zif->es_info.es;
+
+       if (!es)
+               return;
+
+       tmp_pref = zif->es_info.df_pref ? zif->es_info.df_pref
+                                       : EVPN_MH_DF_PREF_DEFAULT;
+
+       if (es->df_pref == tmp_pref)
+               return;
+
+       es->df_pref = tmp_pref;
+       /* run df election */
+       zebra_evpn_es_run_df_election(es, __func__);
+       /* notify bgp */
+       if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)
+               zebra_evpn_es_send_add_to_client(es);
+}
+
+
 /* Only certain types of access ports can be setup as an Ethernet Segment */
 bool zebra_evpn_is_if_es_capable(struct zebra_if *zif)
 {
@@ -1719,12 +2154,34 @@ bool zebra_evpn_is_if_es_capable(struct zebra_if *zif)
 void zebra_evpn_if_es_print(struct vty *vty, struct zebra_if *zif)
 {
        char buf[ETHER_ADDR_STRLEN];
+       char mh_buf[80];
+       bool vty_print = false;
+
+       mh_buf[0] = '\0';
+       snprintf(mh_buf + strlen(mh_buf), sizeof(mh_buf) - strlen(mh_buf),
+                "  EVPN-MH:");
+       if (zif->es_info.lid || !is_zero_mac(&zif->es_info.sysmac)) {
+               vty_print = true;
+               snprintf(
+                       mh_buf + strlen(mh_buf),
+                       sizeof(mh_buf) - strlen(mh_buf),
+                       " ES id %u ES sysmac %s", zif->es_info.lid,
+                       prefix_mac2str(&zif->es_info.sysmac, buf, sizeof(buf)));
+       }
 
-       if (zif->es_info.lid || !is_zero_mac(&zif->es_info.sysmac))
-               vty_out(vty, "  EVPN MH: ES id %u ES sysmac %s\n",
-                               zif->es_info.lid,
-                               prefix_mac2str(&zif->es_info.sysmac,
-                                       buf, sizeof(buf)));
+       if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK) {
+               vty_print = true;
+               if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)
+                       snprintf(mh_buf + strlen(mh_buf),
+                                sizeof(mh_buf) - strlen(mh_buf), " uplink-up");
+               else
+                       snprintf(mh_buf + strlen(mh_buf),
+                                sizeof(mh_buf) - strlen(mh_buf),
+                                " uplink-down");
+       }
+
+       if (vty_print)
+               vty_out(vty, "%s\n", mh_buf);
 }
 
 void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up)
@@ -1744,6 +2201,8 @@ void zebra_evpn_es_if_oper_state_change(struct zebra_if *zif, bool up)
        else
                es->flags &= ~ZEBRA_EVPNES_OPER_UP;
 
+       zebra_evpn_es_run_df_election(es, __func__);
+
        /* inform BGP of the ES oper state change */
        if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)
                zebra_evpn_es_send_add_to_client(es);
@@ -1755,36 +2214,100 @@ static char *zebra_evpn_es_vtep_str(char *vtep_str, struct zebra_evpn_es *es,
        struct zebra_evpn_es_vtep *zvtep;
        struct listnode *node;
        bool first = true;
+       char ip_buf[INET6_ADDRSTRLEN];
 
        vtep_str[0] = '\0';
        for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, zvtep)) {
                if (first) {
                        first = false;
-                       strlcat(vtep_str, inet_ntoa(zvtep->vtep_ip),
+                       strlcat(vtep_str,
+                               inet_ntop(AF_INET, &zvtep->vtep_ip, ip_buf,
+                                         sizeof(ip_buf)),
                                vtep_str_size);
                } else {
                        strlcat(vtep_str, ",", vtep_str_size);
-                       strlcat(vtep_str, inet_ntoa(zvtep->vtep_ip),
+                       strlcat(vtep_str,
+                               inet_ntop(AF_INET, &zvtep->vtep_ip, ip_buf,
+                                         sizeof(ip_buf)),
                                vtep_str_size);
                }
        }
        return vtep_str;
 }
 
-static void zebra_evpn_es_show_entry(struct vty *vty,
-               struct zebra_evpn_es *es, json_object *json)
+static void zebra_evpn_es_json_vtep_fill(struct zebra_evpn_es *es,
+                                        json_object *json_vteps)
+{
+       struct zebra_evpn_es_vtep *es_vtep;
+       struct listnode *node;
+       json_object *json_vtep_entry;
+       char alg_buf[EVPN_DF_ALG_STR_LEN];
+       char ip_buf[INET6_ADDRSTRLEN];
+
+       for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) {
+               json_vtep_entry = json_object_new_object();
+               json_object_string_add(json_vtep_entry, "vtep",
+                                      inet_ntop(AF_INET, &es_vtep->vtep_ip,
+                                                ip_buf, sizeof(ip_buf)));
+               if (es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR) {
+                       json_object_string_add(
+                               json_vtep_entry, "dfAlgorithm",
+                               evpn_es_df_alg2str(es_vtep->df_alg, alg_buf,
+                                                  sizeof(alg_buf)));
+                       json_object_int_add(json_vtep_entry, "dfPreference",
+                                           es_vtep->df_pref);
+               }
+               json_object_int_add(json_vtep_entry, "nexthopId",
+                                   es_vtep->nh_id);
+               json_object_array_add(json_vteps, json_vtep_entry);
+       }
+}
+
+static void zebra_evpn_es_show_entry(struct vty *vty, struct zebra_evpn_es *es,
+                                    json_object *json_array)
 {
        char type_str[4];
        char vtep_str[ES_VTEP_LIST_STR_SZ];
 
-       if (json) {
-               /* XXX */
+       if (json_array) {
+               json_object *json = NULL;
+               json_object *json_vteps;
+               json_object *json_flags;
+
+               json = json_object_new_object();
+               json_object_string_add(json, "esi", es->esi_str);
+
+               if (es->flags
+                   & (ZEBRA_EVPNES_LOCAL | ZEBRA_EVPNES_REMOTE
+                      | ZEBRA_EVPNES_NON_DF)) {
+                       json_flags = json_object_new_array();
+                       if (es->flags & ZEBRA_EVPNES_LOCAL)
+                               json_array_string_add(json_flags, "local");
+                       if (es->flags & ZEBRA_EVPNES_REMOTE)
+                               json_array_string_add(json_flags, "remote");
+                       if (es->flags & ZEBRA_EVPNES_NON_DF)
+                               json_array_string_add(json_flags, "nonDF");
+                       json_object_object_add(json, "flags", json_flags);
+               }
+
+               if (es->zif)
+                       json_object_string_add(json, "accessPort",
+                                              es->zif->ifp->name);
+
+               if (listcount(es->es_vtep_list)) {
+                       json_vteps = json_object_new_array();
+                       zebra_evpn_es_json_vtep_fill(es, json_vteps);
+                       json_object_object_add(json, "vteps", json_vteps);
+               }
+               json_object_array_add(json_array, json);
        } else {
                type_str[0] = '\0';
                if (es->flags & ZEBRA_EVPNES_LOCAL)
                        strlcat(type_str, "L", sizeof(type_str));
                if (es->flags & ZEBRA_EVPNES_REMOTE)
                        strlcat(type_str, "R", sizeof(type_str));
+               if (es->flags & ZEBRA_EVPNES_NON_DF)
+                       strlcat(type_str, "N", sizeof(type_str));
 
                zebra_evpn_es_vtep_str(vtep_str, es, sizeof(vtep_str));
 
@@ -1799,11 +2322,51 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty,
                struct zebra_evpn_es *es, json_object *json)
 {
        char type_str[80];
-       struct zebra_evpn_es_vtep *zvtep;
+       char alg_buf[EVPN_DF_ALG_STR_LEN];
+       struct zebra_evpn_es_vtep *es_vtep;
        struct listnode *node;
 
        if (json) {
-               /* XXX */
+               json_object *json_vteps;
+               json_object *json_flags;
+
+               json_object_string_add(json, "esi", es->esi_str);
+               if (es->zif)
+                       json_object_string_add(json, "accessPort",
+                                              es->zif->ifp->name);
+
+
+               if (es->flags) {
+                       json_flags = json_object_new_array();
+                       if (es->flags & ZEBRA_EVPNES_LOCAL)
+                               json_array_string_add(json_flags, "local");
+                       if (es->flags & ZEBRA_EVPNES_REMOTE)
+                               json_array_string_add(json_flags, "remote");
+                       if (es->flags & ZEBRA_EVPNES_NON_DF)
+                               json_array_string_add(json_flags, "nonDF");
+                       if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)
+                               json_array_string_add(json_flags,
+                                                     "readyForBgp");
+                       if (es->flags & ZEBRA_EVPNES_BR_PORT)
+                               json_array_string_add(json_flags, "bridgePort");
+                       if (es->flags & ZEBRA_EVPNES_OPER_UP)
+                               json_array_string_add(json_flags, "operUp");
+                       if (es->flags & ZEBRA_EVPNES_NHG_ACTIVE)
+                               json_array_string_add(json_flags,
+                                                     "nexthopGroupActive");
+                       json_object_object_add(json, "flags", json_flags);
+               }
+
+               json_object_int_add(json, "vniCount",
+                                   listcount(es->es_evi_list));
+               json_object_int_add(json, "macCount", listcount(es->mac_list));
+               json_object_int_add(json, "dfPreference", es->df_pref);
+               json_object_int_add(json, "nexthopGroup", es->nhg_id);
+               if (listcount(es->es_vtep_list)) {
+                       json_vteps = json_object_new_array();
+                       zebra_evpn_es_json_vtep_fill(es, json_vteps);
+                       json_object_object_add(json, "vteps", json_vteps);
+               }
        } else {
                type_str[0] = '\0';
                if (es->flags & ZEBRA_EVPNES_LOCAL)
@@ -1819,20 +2382,35 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty,
                vty_out(vty, " Interface: %s\n",
                                (es->zif) ?
                                es->zif->ifp->name : "-");
-               vty_out(vty, " State: %s\n",
-                               (es->flags & ZEBRA_EVPNES_OPER_UP) ?
-                               "up" : "down");
+               if (es->flags & ZEBRA_EVPNES_LOCAL) {
+                       vty_out(vty, " State: %s\n",
+                               (es->flags & ZEBRA_EVPNES_OPER_UP) ? "up"
+                                                                  : "down");
+                       vty_out(vty, " Bridge port: %s\n",
+                               (es->flags & ZEBRA_EVPNES_BR_PORT) ? "yes"
+                                                                  : "no");
+               }
                vty_out(vty, " Ready for BGP: %s\n",
                                (es->flags & ZEBRA_EVPNES_READY_FOR_BGP) ?
                                "yes" : "no");
                vty_out(vty, " VNI Count: %d\n", listcount(es->es_evi_list));
                vty_out(vty, " MAC Count: %d\n", listcount(es->mac_list));
+               vty_out(vty, " DF: status: %s preference: %u\n",
+                       (es->flags & ZEBRA_EVPNES_NON_DF) ? "non-df" : "df",
+                       es->df_pref);
                vty_out(vty, " Nexthop group: 0x%x\n", es->nhg_id);
                vty_out(vty, " VTEPs:\n");
-               for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, zvtep))
-                       vty_out(vty, "     %s nh: 0x%x\n",
-                                       inet_ntoa(zvtep->vtep_ip),
-                                       zvtep->nh_id);
+               for (ALL_LIST_ELEMENTS_RO(es->es_vtep_list, node, es_vtep)) {
+                       vty_out(vty, "     %pI4",
+                                       &es_vtep->vtep_ip);
+                       if (es_vtep->flags & ZEBRA_EVPNES_VTEP_RXED_ESR)
+                               vty_out(vty, " df_alg: %s df_pref: %d",
+                                       evpn_es_df_alg2str(es_vtep->df_alg,
+                                                          alg_buf,
+                                                          sizeof(alg_buf)),
+                                       es_vtep->df_pref);
+                       vty_out(vty, " nh: 0x%x\n", es_vtep->nh_id);
+               }
 
                vty_out(vty, "\n");
        }
@@ -1841,27 +2419,51 @@ static void zebra_evpn_es_show_entry_detail(struct vty *vty,
 void zebra_evpn_es_show(struct vty *vty, bool uj)
 {
        struct zebra_evpn_es *es;
-       json_object *json = NULL;
+       json_object *json_array = NULL;
 
        if (uj) {
-               /* XXX */
+               json_array = json_object_new_array();
        } else {
-               vty_out(vty, "Type: L local, R remote\n");
+               vty_out(vty, "Type: L local, R remote, N non-DF\n");
                vty_out(vty, "%-30s %-4s %-21s %s\n",
                                "ESI", "Type", "ES-IF", "VTEPs");
        }
 
        RB_FOREACH(es, zebra_es_rb_head, &zmh_info->es_rb_tree)
-               zebra_evpn_es_show_entry(vty, es, json);
+               zebra_evpn_es_show_entry(vty, es, json_array);
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
+       }
 }
 
 void zebra_evpn_es_show_detail(struct vty *vty, bool uj)
 {
        struct zebra_evpn_es *es;
-       json_object *json = NULL;
+       json_object *json_array = NULL;
 
-       RB_FOREACH(es, zebra_es_rb_head, &zmh_info->es_rb_tree)
+       if (uj)
+               json_array = json_object_new_array();
+
+       RB_FOREACH (es, zebra_es_rb_head, &zmh_info->es_rb_tree) {
+               json_object *json = NULL;
+
+               if (uj)
+                       json = json_object_new_object();
                zebra_evpn_es_show_entry_detail(vty, es, json);
+               if (uj)
+                       json_object_array_add(json_array, json);
+       }
+
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json_array, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json_array);
+       }
 }
 
 void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi)
@@ -1870,15 +2472,26 @@ void zebra_evpn_es_show_esi(struct vty *vty, bool uj, esi_t *esi)
        char esi_str[ESI_STR_LEN];
        json_object *json = NULL;
 
+       if (uj)
+               json = json_object_new_object();
+
        es = zebra_evpn_es_find(esi);
 
-       if (!es) {
-               esi_to_str(esi, esi_str, sizeof(esi_str));
-               vty_out(vty, "ESI %s does not exist\n", esi_str);
-               return;
+       if (es) {
+               zebra_evpn_es_show_entry_detail(vty, es, json);
+       } else {
+               if (!uj) {
+                       esi_to_str(esi, esi_str, sizeof(esi_str));
+                       vty_out(vty, "ESI %s does not exist\n", esi_str);
+               }
        }
 
-       zebra_evpn_es_show_entry_detail(vty, es, json);
+       if (uj) {
+               vty_out(vty, "%s\n",
+                       json_object_to_json_string_ext(
+                               json, JSON_C_TO_STRING_PRETTY));
+               json_object_free(json);
+       }
 }
 
 int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp)
@@ -1893,12 +2506,44 @@ int zebra_evpn_mh_if_write(struct vty *vty, struct interface *ifp)
                vty_out(vty, " evpn mh es-sys-mac %s\n",
                                prefix_mac2str(&zif->es_info.sysmac,
                                        buf, sizeof(buf)));
+
+       if (zif->es_info.df_pref)
+               vty_out(vty, " evpn mh es-df-pref %u\n", zif->es_info.df_pref);
+
+       if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
+               vty_out(vty, " evpn mh uplink\n");
+
        return 0;
 }
 
 #ifndef VTYSH_EXTRACT_PL
 #include "zebra/zebra_evpn_mh_clippy.c"
 #endif
+/* CLI for configuring DF preference part for an ES */
+DEFPY(zebra_evpn_es_pref, zebra_evpn_es_pref_cmd,
+      "[no$no] evpn mh es-df-pref [(1-65535)$df_pref]",
+      NO_STR "EVPN\n" EVPN_MH_VTY_STR
+            "preference value used for DF election\n"
+            "ID\n")
+{
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct zebra_if *zif;
+
+       zif = ifp->info;
+
+       if (no) {
+               zebra_evpn_es_df_pref_update(zif, 0);
+       } else {
+               if (!zebra_evpn_is_if_es_capable(zif)) {
+                       vty_out(vty,
+                               "%%DF preference cannot be associated with this interface type\n");
+                       return CMD_WARNING;
+               }
+               zebra_evpn_es_df_pref_update(zif, df_pref);
+       }
+       return CMD_SUCCESS;
+}
+
 /* CLI for setting up sysmac part of ESI on an access port */
 DEFPY(zebra_evpn_es_sys_mac,
       zebra_evpn_es_sys_mac_cmd,
@@ -1990,6 +2635,70 @@ DEFPY(zebra_evpn_es_id,
        return CMD_SUCCESS;
 }
 
+/* CLI for tagging an interface as an uplink */
+DEFPY(zebra_evpn_mh_uplink, zebra_evpn_mh_uplink_cmd, "[no] evpn mh uplink",
+      NO_STR "EVPN\n" EVPN_MH_VTY_STR "uplink to the VxLAN core\n")
+{
+       VTY_DECLVAR_CONTEXT(interface, ifp);
+       struct zebra_if *zif;
+
+       zif = ifp->info;
+       zebra_evpn_mh_uplink_cfg_update(zif, no ? false : true);
+
+       return CMD_SUCCESS;
+}
+
+void zebra_evpn_mh_json(json_object *json)
+{
+       json_object *json_array;
+       char thread_buf[THREAD_TIMER_STRLEN];
+
+       json_object_int_add(json, "macHoldtime", zmh_info->mac_hold_time);
+       json_object_int_add(json, "neighHoldtime", zmh_info->neigh_hold_time);
+       json_object_int_add(json, "startupDelay", zmh_info->startup_delay_time);
+       json_object_string_add(
+               json, "startupDelayTimer",
+               thread_timer_to_hhmmss(thread_buf, sizeof(thread_buf),
+                                      zmh_info->startup_delay_timer));
+       json_object_int_add(json, "uplinkConfigCount",
+                           zmh_info->uplink_cfg_cnt);
+       json_object_int_add(json, "uplinkActiveCount",
+                           zmh_info->uplink_oper_up_cnt);
+
+       if (zmh_info->protodown_rc) {
+               json_array = json_object_new_array();
+               if (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY)
+                       json_object_array_add(
+                               json_array,
+                               json_object_new_string("startupDelay"));
+               if (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN)
+                       json_object_array_add(
+                               json_array,
+                               json_object_new_string("uplinkDown"));
+               json_object_object_add(json, "protodownReasons", json_array);
+       }
+}
+
+void zebra_evpn_mh_print(struct vty *vty)
+{
+       char pd_buf[ZEBRA_PROTODOWN_RC_STR_LEN];
+       char thread_buf[THREAD_TIMER_STRLEN];
+
+       vty_out(vty, "EVPN MH:\n");
+       vty_out(vty, "  mac-holdtime: %ds, neigh-holdtime: %ds\n",
+               zmh_info->mac_hold_time, zmh_info->neigh_hold_time);
+       vty_out(vty, "  startup-delay: %ds, start-delay-timer: %s\n",
+               zmh_info->startup_delay_time,
+               thread_timer_to_hhmmss(thread_buf, sizeof(thread_buf),
+                                      zmh_info->startup_delay_timer));
+       vty_out(vty, "  uplink-cfg-cnt: %u, uplink-active-cnt: %u\n",
+               zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt);
+       if (zmh_info->protodown_rc)
+               vty_out(vty, "  protodown: %s\n",
+                       zebra_protodown_rc_str(zmh_info->protodown_rc, pd_buf,
+                                              sizeof(pd_buf)));
+}
+
 /*****************************************************************************/
 /* A base L2-VNI is maintained to derive parameters such as ES originator-IP.
  * XXX: once single vxlan device model becomes available this will not be
@@ -2027,11 +2736,13 @@ void zebra_evpn_es_set_base_evpn(zebra_evpn_t *zevpn)
                zmh_info->es_base_evpn->local_vtep_ip.s_addr;
 
        if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
-               zlog_debug("es originator ip set to %s",
-                       inet_ntoa(zmh_info->es_base_evpn->local_vtep_ip));
+               zlog_debug("es originator ip set to %pI4",
+                       &zmh_info->es_base_evpn->local_vtep_ip);
 
        /* if originator ip changes we need to update bgp */
        for (ALL_LIST_ELEMENTS_RO(zmh_info->local_es_list, node, es)) {
+               zebra_evpn_es_run_df_election(es, __func__);
+
                if (es->flags & ZEBRA_EVPNES_READY_FOR_BGP)
                        zebra_evpn_es_send_add_to_client(es);
                else
@@ -2093,23 +2804,316 @@ static void zebra_evpn_es_get_one_base_evpn(void)
        hash_walk(zvrf->evpn_table, zebra_evpn_es_get_one_base_evpn_cb, NULL);
 }
 
+/*****************************************************************************
+ * local ethernet segments can be error-disabled if the switch is not
+ * ready to start transmitting traffic via the VxLAN overlay
+ */
+bool zebra_evpn_is_es_bond(struct interface *ifp)
+{
+       struct zebra_if *zif = ifp->info;
+
+       return !!(struct zebra_if *)zif->es_info.es;
+}
+
+bool zebra_evpn_is_es_bond_member(struct interface *ifp)
+{
+       struct zebra_if *zif = ifp->info;
+
+       return IS_ZEBRA_IF_BOND_SLAVE(zif->ifp) && zif->bondslave_info.bond_if
+              && ((struct zebra_if *)zif->bondslave_info.bond_if->info)
+                         ->es_info.es;
+}
+
+void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif, bool clear,
+                                            const char *caller)
+{
+       bool old_protodown;
+       bool new_protodown;
+       enum protodown_reasons old_protodown_rc = 0;
+       enum protodown_reasons protodown_rc = 0;
+
+       if (!clear) {
+               struct zebra_if *bond_zif;
+
+               bond_zif = zif->bondslave_info.bond_if->info;
+               protodown_rc = bond_zif->protodown_rc;
+       }
+
+       if (zif->protodown_rc == protodown_rc)
+               return;
+
+       old_protodown = !!(zif->flags & ZIF_FLAG_PROTODOWN);
+       old_protodown_rc = zif->protodown_rc;
+       zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL;
+       zif->protodown_rc |= (protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL);
+       new_protodown = !!zif->protodown_rc;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug(
+                       "%s bond mbr %s protodown_rc changed; old 0x%x new 0x%x",
+                       caller, zif->ifp->name, old_protodown_rc,
+                       zif->protodown_rc);
+
+       if (old_protodown == new_protodown)
+               return;
+
+       if (new_protodown)
+               zif->flags |= ZIF_FLAG_PROTODOWN;
+       else
+               zif->flags &= ~ZIF_FLAG_PROTODOWN;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("%s protodown %s", zif->ifp->name,
+                          new_protodown ? "on" : "off");
+
+       zebra_if_set_protodown(zif->ifp, new_protodown);
+}
+
+/* The bond members inherit the protodown reason code from the bond */
+static void zebra_evpn_mh_update_protodown_bond(struct zebra_if *bond_zif)
+{
+       struct zebra_if *zif;
+       struct listnode *node;
+
+       if (!bond_zif->bond_info.mbr_zifs)
+               return;
+
+       for (ALL_LIST_ELEMENTS_RO(bond_zif->bond_info.mbr_zifs, node, zif)) {
+               zebra_evpn_mh_update_protodown_bond_mbr(zif, false /*clear*/,
+                                                       __func__);
+       }
+}
+
+/* The global EVPN MH protodown rc is applied to all local ESs */
+static void zebra_evpn_mh_update_protodown_es(struct zebra_evpn_es *es)
+{
+       struct zebra_if *zif;
+       enum protodown_reasons old_protodown_rc;
+
+       zif = es->zif;
+       if ((zif->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL)
+           == (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL))
+               return;
+
+       old_protodown_rc = zif->protodown_rc;
+       zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL;
+       zif->protodown_rc |=
+               (zmh_info->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL);
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug(
+                       "es %s ifp %s protodown_rc changed; old 0x%x new 0x%x",
+                       es->esi_str, zif->ifp->name, old_protodown_rc,
+                       zif->protodown_rc);
+
+       /* update dataplane with the new protodown setting */
+       zebra_evpn_mh_update_protodown_bond(zif);
+}
+
+static void zebra_evpn_mh_clear_protodown_es(struct zebra_evpn_es *es)
+{
+       struct zebra_if *zif;
+       enum protodown_reasons old_protodown_rc;
+
+       zif = es->zif;
+       if (!(zif->protodown_rc & ZEBRA_PROTODOWN_EVPN_ALL))
+               return;
+
+       old_protodown_rc = zif->protodown_rc;
+       zif->protodown_rc &= ~ZEBRA_PROTODOWN_EVPN_ALL;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug(
+                       "clear: es %s ifp %s protodown_rc cleared; old 0x%x new 0x%x",
+                       es->esi_str, zif->ifp->name, old_protodown_rc,
+                       zif->protodown_rc);
+
+       /* update dataplane with the new protodown setting */
+       zebra_evpn_mh_update_protodown_bond(zif);
+}
+
+static void zebra_evpn_mh_update_protodown_es_all(void)
+{
+       struct listnode *node;
+       struct zebra_evpn_es *es;
+
+       for (ALL_LIST_ELEMENTS_RO(zmh_info->local_es_list, node, es))
+               zebra_evpn_mh_update_protodown_es(es);
+}
+
+static void zebra_evpn_mh_update_protodown(enum protodown_reasons protodown_rc,
+                                          bool set)
+{
+       enum protodown_reasons old_protodown_rc = zmh_info->protodown_rc;
+
+       if (set) {
+               if ((protodown_rc & zmh_info->protodown_rc) == protodown_rc)
+                       return;
+
+               zmh_info->protodown_rc |= protodown_rc;
+       } else {
+               if (!(protodown_rc & zmh_info->protodown_rc))
+                       return;
+               zmh_info->protodown_rc &= ~protodown_rc;
+       }
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("mh protodown_rc changed; old 0x%x new 0x%x",
+                          old_protodown_rc, zmh_info->protodown_rc);
+       zebra_evpn_mh_update_protodown_es_all();
+}
+
+static inline bool zebra_evpn_mh_is_all_uplinks_down(void)
+{
+       return zmh_info->uplink_cfg_cnt && !zmh_info->uplink_oper_up_cnt;
+}
+
+static void zebra_evpn_mh_uplink_oper_flags_update(struct zebra_if *zif,
+                                                  bool set)
+{
+       if (set) {
+               if (if_is_operative(zif->ifp)) {
+                       if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP)) {
+                               zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP;
+                               ++zmh_info->uplink_oper_up_cnt;
+                       }
+               } else {
+                       if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) {
+                               zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP;
+                               if (zmh_info->uplink_oper_up_cnt)
+                                       --zmh_info->uplink_oper_up_cnt;
+                       }
+               }
+       } else {
+               if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP) {
+                       zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK_OPER_UP;
+                       if (zmh_info->uplink_oper_up_cnt)
+                               --zmh_info->uplink_oper_up_cnt;
+               }
+       }
+}
+
+static void zebra_evpn_mh_uplink_cfg_update(struct zebra_if *zif, bool set)
+{
+       bool old_protodown = zebra_evpn_mh_is_all_uplinks_down();
+       bool new_protodown;
+
+       if (set) {
+               if (zif->flags & ZIF_FLAG_EVPN_MH_UPLINK)
+                       return;
+
+               zif->flags |= ZIF_FLAG_EVPN_MH_UPLINK;
+               ++zmh_info->uplink_cfg_cnt;
+       } else {
+               if (!(zif->flags & ZIF_FLAG_EVPN_MH_UPLINK))
+                       return;
+
+               zif->flags &= ~ZIF_FLAG_EVPN_MH_UPLINK;
+               if (zmh_info->uplink_cfg_cnt)
+                       --zmh_info->uplink_cfg_cnt;
+       }
+
+       zebra_evpn_mh_uplink_oper_flags_update(zif, set);
+       new_protodown = zebra_evpn_mh_is_all_uplinks_down();
+       if (old_protodown == new_protodown)
+               return;
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug(
+                       "mh-uplink-cfg-chg on if %s/%d %s uplinks cfg %u up %u",
+                       zif->ifp->name, zif->ifp->ifindex, set ? "set" : "down",
+                       zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt);
+
+       zebra_evpn_mh_update_protodown(ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN,
+                                      new_protodown);
+}
+
+void zebra_evpn_mh_uplink_oper_update(struct zebra_if *zif)
+{
+       bool old_protodown = zebra_evpn_mh_is_all_uplinks_down();
+       bool new_protodown;
+
+       zebra_evpn_mh_uplink_oper_flags_update(zif, true /*set*/);
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug(
+                       "mh-uplink-oper-chg on if %s/%d %s; uplinks cfg %u up %u",
+                       zif->ifp->name, zif->ifp->ifindex,
+                       if_is_operative(zif->ifp) ? "up" : "down",
+                       zmh_info->uplink_cfg_cnt, zmh_info->uplink_oper_up_cnt);
+
+       new_protodown = zebra_evpn_mh_is_all_uplinks_down();
+       if (old_protodown == new_protodown)
+               return;
+
+       zebra_evpn_mh_update_protodown(ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN,
+                                      new_protodown);
+}
+
+static int zebra_evpn_mh_startup_delay_exp_cb(struct thread *t)
+{
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+               zlog_debug("startup-delay expired");
+
+       zebra_evpn_mh_update_protodown(ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY,
+                                      false /* set */);
+
+       return 0;
+}
+
+static void zebra_evpn_mh_startup_delay_timer_start(bool init)
+{
+       /* 1. This timer can be started during init.
+        * 2. It can also be restarted if it is alreay running and the
+        * admin wants to increase or decrease its value
+        */
+       if (!init && !zmh_info->startup_delay_timer)
+               return;
+
+       if (zmh_info->startup_delay_timer) {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+                       zlog_debug("startup-delay timer cancelled");
+               thread_cancel(&zmh_info->startup_delay_timer);
+               zmh_info->startup_delay_timer = NULL;
+       }
+
+       if (zmh_info->startup_delay_time) {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES)
+                       zlog_debug("startup-delay timer started for %d sec",
+                                  zmh_info->startup_delay_time);
+               thread_add_timer(zrouter.master,
+                                zebra_evpn_mh_startup_delay_exp_cb, NULL,
+                                zmh_info->startup_delay_time,
+                                &zmh_info->startup_delay_timer);
+               zebra_evpn_mh_update_protodown(
+                       ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY, true /* set */);
+       } else {
+               zebra_evpn_mh_update_protodown(
+                       ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY, false /* set */);
+       }
+}
+
 /*****************************************************************************/
 void zebra_evpn_mh_config_write(struct vty *vty)
 {
-       if (zmh_info->mac_hold_time != EVPN_MH_MAC_HOLD_TIME_DEF)
-               vty_out(vty, "evpn mh mac-holdtime %ld\n",
+       if (zmh_info->mac_hold_time != ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF)
+               vty_out(vty, "evpn mh mac-holdtime %d\n",
                        zmh_info->mac_hold_time);
 
-       if (zmh_info->neigh_hold_time != EVPN_MH_NEIGH_HOLD_TIME_DEF)
-               vty_out(vty, "evpn mh neigh-holdtime %ld\n",
+       if (zmh_info->neigh_hold_time != ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF)
+               vty_out(vty, "evpn mh neigh-holdtime %d\n",
                        zmh_info->neigh_hold_time);
+
+       if (zmh_info->startup_delay_time != ZEBRA_EVPN_MH_STARTUP_DELAY_DEF)
+               vty_out(vty, "evpn mh startup-delay %d\n",
+                       zmh_info->startup_delay_time);
 }
 
 int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty,
                uint32_t duration, bool set_default)
 {
        if (set_default)
-               duration = EVPN_MH_NEIGH_HOLD_TIME_DEF;
+               duration = ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF;
 
        zmh_info->neigh_hold_time = duration;
 
@@ -2120,25 +3124,39 @@ int zebra_evpn_mh_mac_holdtime_update(struct vty *vty,
                uint32_t duration, bool set_default)
 {
        if (set_default)
-               duration = EVPN_MH_MAC_HOLD_TIME_DEF;
+               duration = ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF;
 
        zmh_info->mac_hold_time = duration;
 
        return 0;
 }
 
+int zebra_evpn_mh_startup_delay_update(struct vty *vty, uint32_t duration,
+                                      bool set_default)
+{
+       if (set_default)
+               duration = ZEBRA_EVPN_MH_STARTUP_DELAY_DEF;
+
+       zmh_info->startup_delay_time = duration;
+       zebra_evpn_mh_startup_delay_timer_start(false /* init */);
+
+       return 0;
+}
+
 void zebra_evpn_interface_init(void)
 {
        install_element(INTERFACE_NODE, &zebra_evpn_es_id_cmd);
        install_element(INTERFACE_NODE, &zebra_evpn_es_sys_mac_cmd);
+       install_element(INTERFACE_NODE, &zebra_evpn_es_pref_cmd);
+       install_element(INTERFACE_NODE, &zebra_evpn_mh_uplink_cmd);
 }
 
 void zebra_evpn_mh_init(void)
 {
        zrouter.mh_info = XCALLOC(MTYPE_ZMH_INFO, sizeof(*zrouter.mh_info));
 
-       zmh_info->mac_hold_time = EVPN_MH_MAC_HOLD_TIME_DEF;
-       zmh_info->neigh_hold_time = EVPN_MH_NEIGH_HOLD_TIME_DEF;
+       zmh_info->mac_hold_time = ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF;
+       zmh_info->neigh_hold_time = ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF;
        /* setup ES tables */
        RB_INIT(zebra_es_rb_head, &zmh_info->es_rb_tree);
        zmh_info->local_es_list = list_new();
@@ -2150,6 +3168,9 @@ void zebra_evpn_mh_init(void)
        /* setup broadcast domain tables */
        zmh_info->evpn_vlan_table = hash_create(zebra_evpn_acc_vl_hash_keymake,
                        zebra_evpn_acc_vl_cmp, "access VLAN hash table");
+
+       zmh_info->startup_delay_time = ZEBRA_EVPN_MH_STARTUP_DELAY_DEF;
+       zebra_evpn_mh_startup_delay_timer_start(true /*init*/);
 }
 
 void zebra_evpn_mh_terminate(void)
index 72b7f9b67507f813286b5f7deb239fed027aaa75..09af26a3a3d437f82420f238c52172c08db074a8 100644 (file)
@@ -51,6 +51,14 @@ struct zebra_evpn_es {
 #define ZEBRA_EVPNES_OPER_UP       (1 << 2) /* es->ifp is oper-up */
 #define ZEBRA_EVPNES_READY_FOR_BGP (1 << 3) /* ready to be sent to BGP */
 #define ZEBRA_EVPNES_NHG_ACTIVE    (1 << 4) /* NHG has been installed */
+/* This flag is only applicable to local ESs and signifies that this
+ * VTEP is not the DF
+ */
+#define ZEBRA_EVPNES_NON_DF (1 << 5)
+/* When the ES becomes a bridge port we need to activate the BUM non-DF
+ * filter, SPH filter and backup NHG for fast-failover
+ */
+#define ZEBRA_EVPNES_BR_PORT (1 << 6)
 
        /* memory used for adding the es to zmh_info->es_rb_tree */
        RB_ENTRY(zebra_evpn_es) rb_node;
@@ -74,6 +82,11 @@ struct zebra_evpn_es {
 
        /* Nexthop group id */
        uint32_t nhg_id;
+
+       /* Preference config for BUM-DF election. Sent to BGP and
+        * advertised via the ESR
+        */
+       uint16_t df_pref;
 };
 RB_HEAD(zebra_es_rb_head, zebra_evpn_es);
 RB_PROTOTYPE(zebra_es_rb_head, zebra_evpn_es, rb_node, zebra_es_rb_cmp);
@@ -115,12 +128,21 @@ struct zebra_evpn_es_vtep {
        struct zebra_evpn_es *es; /* parent ES */
        struct in_addr vtep_ip;
 
+       uint32_t flags;
+       /* Rxed Type-4 route from this VTEP */
+#define ZEBRA_EVPNES_VTEP_RXED_ESR (1 << 0)
+#define ZEBRA_EVPNES_VTEP_DEL_IN_PROG (1 << 1)
+
        /* memory used for adding the entry to es->es_vtep_list */
        struct listnode es_listnode;
 
        /* MAC nexthop */
        uint32_t nh_id;
 
+       /* Parameters for DF election */
+       uint8_t df_alg;
+       uint32_t df_pref;
+
        /* XXX - maintain a backpointer to zebra_vtep_t */
 };
 
@@ -173,10 +195,25 @@ struct zebra_evpn_mh_info {
 #define EVPN_NHG_ID_TYPE_BIT (2 << EVPN_NH_ID_TYPE_POS)
 
        /* XXX - re-visit the default hold timer value */
-#define EVPN_MH_MAC_HOLD_TIME_DEF (18 * 60)
-       long mac_hold_time;
-#define EVPN_MH_NEIGH_HOLD_TIME_DEF (18 * 60)
-       long neigh_hold_time;
+       int mac_hold_time;
+#define ZEBRA_EVPN_MH_MAC_HOLD_TIME_DEF (18 * 60)
+       int neigh_hold_time;
+#define ZEBRA_EVPN_MH_NEIGH_HOLD_TIME_DEF (18 * 60)
+
+       /* During this period access ports will be held in a protodown
+        * state
+        */
+       int startup_delay_time; /* seconds */
+#define ZEBRA_EVPN_MH_STARTUP_DELAY_DEF (3 * 60)
+       struct thread *startup_delay_timer;
+
+       /* Number of configured uplinks */
+       uint32_t uplink_cfg_cnt;
+       /* Number of operationally-up uplinks */
+       uint32_t uplink_oper_up_cnt;
+
+       /* These protodown bits are inherited by all ES bonds */
+       enum protodown_reasons protodown_rc;
 };
 
 static inline bool zebra_evpn_mac_is_es_local(zebra_mac_t *mac)
@@ -235,5 +272,17 @@ extern int zebra_evpn_mh_mac_holdtime_update(struct vty *vty,
 void zebra_evpn_mh_config_write(struct vty *vty);
 int zebra_evpn_mh_neigh_holdtime_update(struct vty *vty,
                uint32_t duration, bool set_default);
+void zebra_evpn_es_local_br_port_update(struct zebra_if *zif);
+extern int zebra_evpn_mh_startup_delay_update(struct vty *vty,
+                                             uint32_t duration,
+                                             bool set_default);
+extern void zebra_evpn_mh_uplink_oper_update(struct zebra_if *zif);
+extern void zebra_evpn_mh_update_protodown_bond_mbr(struct zebra_if *zif,
+                                                   bool clear,
+                                                   const char *caller);
+extern bool zebra_evpn_is_es_bond(struct interface *ifp);
+extern bool zebra_evpn_is_es_bond_member(struct interface *ifp);
+extern void zebra_evpn_mh_print(struct vty *vty);
+extern void zebra_evpn_mh_json(json_object *json);
 
 #endif /* _ZEBRA_EVPN_MH_H */
index 6a76a475e6f07dc56a28401410dbb32738b60c9d..e4f38008ac8e135411a22bea5491a0389c687abb 100644 (file)
@@ -592,6 +592,7 @@ static zebra_neigh_t *zebra_evpn_neigh_add(zebra_evpn_t *zevpn,
        n->zevpn = zevpn;
        n->dad_ip_auto_recovery_timer = NULL;
        n->flags = n_flags;
+       n->uptime = monotime(NULL);
 
        if (!zmac)
                zmac = zebra_evpn_mac_lookup(zevpn, mac);
@@ -722,9 +723,8 @@ zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n,
                                        n->state, false /*force*/);
                                old_bgp_ready = false;
                        }
-                       if (n->mac)
-                               zebra_evpn_local_neigh_deref_mac(
-                                       n, false /*send_mac_update*/);
+                       zebra_evpn_local_neigh_deref_mac(n,
+                                                        false /*send_mac_update*/);
                }
                /* clear old fwd info */
                n->rem_seq = 0;
@@ -803,6 +803,8 @@ zebra_evpn_proc_sync_neigh_update(zebra_evpn_t *zevpn, zebra_neigh_t *n,
                        n->ifindex = ifindex;
                        inform_dataplane = true;
                }
+
+               n->uptime = monotime(NULL);
        }
 
        /* update the neigh seq. we don't bother with the mac seq as
@@ -1284,12 +1286,12 @@ zebra_evpn_dup_addr_detect_for_neigh(struct zebra_vrf *zvrf, zebra_neigh_t *nbr,
        if (nbr->dad_count >= zvrf->dad_max_moves) {
                flog_warn(
                        EC_ZEBRA_DUP_IP_DETECTED,
-                       "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %s",
+                       "VNI %u: MAC %s IP %s detected as duplicate during %s VTEP %pI4",
                        nbr->zevpn->vni,
                        prefix_mac2str(&nbr->emac, buf, sizeof(buf)),
                        ipaddr2str(&nbr->ip, buf1, sizeof(buf1)),
                        is_local ? "local update, last" : "remote update, from",
-                       inet_ntoa(vtep_ip));
+                       &vtep_ip);
 
                SET_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE);
 
@@ -1791,6 +1793,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
        struct vty *vty;
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
+       char addr_buf[PREFIX_STRLEN];
        const char *type_str;
        const char *state_str;
        bool flags_present = false;
@@ -1798,11 +1801,18 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
        struct timeval detect_start_time = {0, 0};
        char timebuf[MONOTIME_STRLEN];
        char thread_buf[THREAD_TIMER_STRLEN];
+       time_t uptime;
+       char up_str[MONOTIME_STRLEN];
 
        zvrf = zebra_vrf_get_evpn();
        if (!zvrf)
                return;
 
+       uptime = monotime(NULL);
+       uptime -= n->uptime;
+
+       frrtime_to_interval(uptime, up_str, sizeof(up_str));
+
        ipaddr2str(&n->ip, buf2, sizeof(buf2));
        prefix_mac2str(&n->emac, buf1, sizeof(buf1));
        type_str = CHECK_FLAG(n->flags, ZEBRA_NEIGH_LOCAL) ? "local" : "remote";
@@ -1815,6 +1825,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
                        ipaddr2str(&n->ip, buf2, sizeof(buf2)));
                vty_out(vty, " Type: %s\n", type_str);
                vty_out(vty, " State: %s\n", state_str);
+               vty_out(vty, " Uptime: %s\n", up_str);
                vty_out(vty, " MAC: %s\n",
                        prefix_mac2str(&n->emac, buf1, sizeof(buf1)));
                vty_out(vty, " Sync-info:");
@@ -1841,6 +1852,7 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
                        vty_out(vty, " -");
                vty_out(vty, "\n");
        } else {
+               json_object_string_add(json, "uptime", up_str);
                json_object_string_add(json, "ip", buf2);
                json_object_string_add(json, "type", type_str);
                json_object_string_add(json, "state", state_str);
@@ -1868,11 +1880,13 @@ void zebra_evpn_print_neigh(zebra_neigh_t *n, void *ctxt, json_object *json)
                                        n->mac->es->esi_str);
                } else {
                        if (json)
-                               json_object_string_add(json, "remoteVtep",
-                                                      inet_ntoa(n->r_vtep_ip));
+                               json_object_string_add(
+                                       json, "remoteVtep",
+                                       inet_ntop(AF_INET, &n->r_vtep_ip,
+                                                 addr_buf, sizeof(addr_buf)));
                        else
-                               vty_out(vty, " Remote VTEP: %s\n",
-                                       inet_ntoa(n->r_vtep_ip));
+                               vty_out(vty, " Remote VTEP: %pI4\n",
+                                       &n->r_vtep_ip);
                }
        }
        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW)) {
@@ -1953,6 +1967,7 @@ void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
        zebra_neigh_t *n;
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
+       char addr_buf[PREFIX_STRLEN];
        struct neigh_walk_ctx *wctx = ctxt;
        const char *state_str;
        char flags_buf[6];
@@ -2007,12 +2022,16 @@ void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
                        if ((wctx->flags & SHOW_REMOTE_NEIGH_FROM_VTEP)
                            && (wctx->count == 0))
                                zebra_evpn_print_neigh_hdr(vty, wctx);
+
+                       if (n->mac->es == NULL)
+                               inet_ntop(AF_INET, &n->r_vtep_ip,
+                                         addr_buf, sizeof(addr_buf));
+
                        vty_out(vty, "%*s %-6s %-5s %-8s %-17s %-30s %u/%u\n",
                                -wctx->addr_width, buf2, "remote",
                                zebra_evpn_print_neigh_flags(n, flags_buf,
                                sizeof(flags_buf)), state_str, buf1,
-                               n->mac->es ? n->mac->es->esi_str
-                                          : inet_ntoa(n->r_vtep_ip),
+                               n->mac->es ? n->mac->es->esi_str : addr_buf,
                                n->loc_seq, n->rem_seq);
                } else {
                        json_object_string_add(json_row, "type", "remote");
@@ -2022,8 +2041,10 @@ void zebra_evpn_print_neigh_hash(struct hash_bucket *bucket, void *ctxt)
                                json_object_string_add(json_row, "remoteEs",
                                                       n->mac->es->esi_str);
                        else
-                               json_object_string_add(json_row, "remoteVtep",
-                                                      inet_ntoa(n->r_vtep_ip));
+                               json_object_string_add(
+                                       json_row, "remoteVtep",
+                                       inet_ntop(AF_INET, &n->r_vtep_ip,
+                                                 addr_buf, sizeof(addr_buf)));
                        if (CHECK_FLAG(n->flags, ZEBRA_NEIGH_DEF_GW))
                                json_object_boolean_true_add(json_row,
                                                             "defaultGateway");
@@ -2134,11 +2155,11 @@ void process_neigh_remote_macip_add(zebra_evpn_t *zevpn, struct zebra_vrf *zvrf,
                                                 mac, 0);
                        if (!n) {
                                zlog_warn(
-                                       "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %s",
+                                       "Failed to add Neigh %s MAC %s VNI %u Remote VTEP %pI4",
                                        ipaddr2str(ipaddr, buf1, sizeof(buf1)),
                                        prefix_mac2str(&mac->macaddr, buf,
                                                       sizeof(buf)),
-                                       zevpn->vni, inet_ntoa(vtep_ip));
+                                       zevpn->vni, &vtep_ip);
                                return;
                        }
 
index 4b98266c86fc5899d2d6bdf7695da30665a4bd34..50efdc0e0d41b66871eef67e0065035c35808334 100644 (file)
@@ -113,6 +113,8 @@ struct zebra_neigh_t_ {
 
        time_t dad_dup_detect_time;
 
+       time_t uptime;
+
        /* used for ageing out the PEER_ACTIVE flag */
        struct thread *hold_timer;
 };
index f84c8c1fcc364a20a52be0bfc48bd34c35123fc1..2bf48c6277591ed1f9e0bd3cda6aabd1252af001 100644 (file)
@@ -489,7 +489,7 @@ static inline void zfpm_write_on(void)
  */
 static inline void zfpm_read_off(void)
 {
-       THREAD_READ_OFF(zfpm_g->t_read);
+       thread_cancel(&zfpm_g->t_read);
 }
 
 /*
@@ -497,12 +497,12 @@ static inline void zfpm_read_off(void)
  */
 static inline void zfpm_write_off(void)
 {
-       THREAD_WRITE_OFF(zfpm_g->t_write);
+       thread_cancel(&zfpm_g->t_write);
 }
 
 static inline void zfpm_connect_off(void)
 {
-       THREAD_TIMER_OFF(zfpm_g->t_connect);
+       thread_cancel(&zfpm_g->t_connect);
 }
 
 /*
@@ -1437,7 +1437,6 @@ static inline int zfpm_conn_is_up(void)
 static int zfpm_trigger_update(struct route_node *rn, const char *reason)
 {
        rib_dest_t *dest;
-       char buf[PREFIX_STRLEN];
 
        /*
         * Ignore if the connection is down. We will update the FPM about
@@ -1454,8 +1453,8 @@ static int zfpm_trigger_update(struct route_node *rn, const char *reason)
        }
 
        if (reason) {
-               zfpm_debug("%s triggering update to FPM - Reason: %s",
-                          prefix2str(&rn->p, buf, sizeof(buf)), reason);
+               zfpm_debug("%pFX triggering update to FPM - Reason: %s", &rn->p,
+                          reason);
        }
 
        SET_FLAG(dest->flags, RIB_DEST_UPDATE_FPM);
@@ -1688,7 +1687,7 @@ static void zfpm_stop_stats_timer(void)
                return;
 
        zfpm_debug("Stopping existing stats timer");
-       THREAD_TIMER_OFF(zfpm_g->t_stats);
+       thread_cancel(&zfpm_g->t_stats);
 }
 
 /*
@@ -1934,7 +1933,7 @@ static int fpm_remote_srv_write(struct vty *vty)
        if ((zfpm_g->fpm_server != FPM_DEFAULT_IP
             && zfpm_g->fpm_server != INADDR_ANY)
            || (zfpm_g->fpm_port != FPM_DEFAULT_PORT && zfpm_g->fpm_port != 0))
-               vty_out(vty, "fpm connection ip %s port %d\n", inet_ntoa(in),
+               vty_out(vty, "fpm connection ip %pI4 port %d\n", &in,
                        zfpm_g->fpm_port);
 
        return 0;
index 81437e72f511ebd5d0fbc1d039f3f2e9d9d2054b..e39272203032dfd77ec3735c8e414aa2ea060990 100644 (file)
@@ -181,6 +181,7 @@ static void zfpm_dt_log_fpm_message(Fpm__Message *msg)
        char *if_name;
        size_t i;
        char buf[INET6_ADDRSTRLEN];
+       char addr_buf[PREFIX_STRLEN];
        union g_addr nh_addr;
 
        if (msg->type != FPM__MESSAGE__TYPE__ADD_ROUTE)
@@ -213,7 +214,9 @@ static void zfpm_dt_log_fpm_message(Fpm__Message *msg)
 
                zfpm_debug("Nexthop - if_index: %d (%s), gateway: %s, ",
                           if_index, if_name ? if_name : "name not specified",
-                          nexthop->address ? inet_ntoa(nh_addr.ipv4) : "None");
+                          nexthop->address ?
+                          inet_ntop(AF_INET, &nh_addr.ipv4,
+                                    addr_buf, sizeof(addr_buf)) : "None");
        }
 }
 
index 2c07413638667467e09e572bfe47619bd869eaab..44f574073cb26c2598305d97118bc47ff84529a5 100644 (file)
 #include "zebra/zebra_fpm_private.h"
 #include "zebra/zebra_vxlan_private.h"
 
-/*
- * addr_to_a
- *
- * Returns string representation of an address of the given AF.
- */
-static inline const char *addr_to_a(uint8_t af, void *addr)
-{
-       if (!addr)
-               return "<No address>";
-
-       switch (af) {
-
-       case AF_INET:
-               return inet_ntoa(*((struct in_addr *)addr));
-       case AF_INET6:
-               return inet6_ntoa(*((struct in6_addr *)addr));
-       default:
-               return "<Addr in unknown AF>";
-       }
-}
-
-/*
- * prefix_addr_to_a
- *
- * Convience wrapper that returns a human-readable string for the
- * address in a prefix.
- */
-static const char *prefix_addr_to_a(struct prefix *prefix)
-{
-       if (!prefix)
-               return "<No address>";
-
-       return addr_to_a(prefix->family, &prefix->u.prefix);
-}
-
 /*
  * af_addr_size
  *
@@ -525,18 +490,24 @@ static void zfpm_log_route_info(struct netlink_route_info *ri,
 {
        struct netlink_nh_info *nhi;
        unsigned int i;
+       char buf[PREFIX_STRLEN];
 
-       zfpm_debug("%s : %s %s/%d, Proto: %s, Metric: %u", label,
+       zfpm_debug("%s : %s %s, Proto: %s, Metric: %u", label,
                   nl_msg_type_to_str(ri->nlmsg_type),
-                  prefix_addr_to_a(ri->prefix), ri->prefix->prefixlen,
+                  prefix2str(ri->prefix, buf, sizeof(buf)),
                   nl_rtproto_to_str(ri->rtm_protocol),
                   ri->metric ? *ri->metric : 0);
 
        for (i = 0; i < ri->num_nhs; i++) {
                nhi = &ri->nhs[i];
+
+               if (ri->af == AF_INET)
+                       inet_ntop(AF_INET, &nhi->gateway, buf, sizeof(buf));
+               else
+                       inet_ntop(AF_INET6, &nhi->gateway, buf, sizeof(buf));
+
                zfpm_debug("  Intf: %u, Gateway: %s, Recursive: %s, Type: %s, Encap type: %s",
-                          nhi->if_index, addr_to_a(ri->af, nhi->gateway),
-                          nhi->recursive ? "yes" : "no",
+                          nhi->if_index, buf, nhi->recursive ? "yes" : "no",
                           nexthop_type_to_str(nhi->type),
                           fpm_nh_encap_type_to_str(nhi->encap_info.encap_type)
                           );
@@ -621,11 +592,11 @@ int zfpm_netlink_encode_mac(struct fpm_mac_info_t *mac, char *in_buf,
 
        assert(req->hdr.nlmsg_len < in_buf_len);
 
-       zfpm_debug("Tx %s family %s ifindex %u MAC %s DEST %s",
+       zfpm_debug("Tx %s family %s ifindex %u MAC %s DEST %pI4",
                   nl_msg_type_to_str(req->hdr.nlmsg_type),
                   nl_family_to_str(req->ndm.ndm_family), req->ndm.ndm_ifindex,
                   prefix_mac2str(&mac->macaddr, buf1, sizeof(buf1)),
-                  inet_ntoa(mac->r_vtep_ip));
+                  &mac->r_vtep_ip);
 
        return req->hdr.nlmsg_len;
 }
index a4f32dbf39f64a0c421ca04b4d575a2e7d38f1ad..ca6a33cd52ec8425301c93048c75e1ca7d3b45b7 100644 (file)
@@ -490,19 +490,15 @@ static void zebra_gr_process_route_entry(struct zserv *client,
                                         struct route_node *rn,
                                         struct route_entry *re)
 {
-       char buf[PREFIX2STR_BUFFER];
-
        if ((client == NULL) || (rn == NULL) || (re == NULL))
                return;
 
        /* If the route is not refreshed after restart, delete the entry */
        if (re->uptime < client->restart_time) {
-               if (IS_ZEBRA_DEBUG_RIB) {
-                       prefix2str(&rn->p, buf, sizeof(buf));
-                       zlog_debug("%s: Client %s stale route %s is deleted",
+               if (IS_ZEBRA_DEBUG_RIB)
+                       zlog_debug("%s: Client %s stale route %pFX is deleted",
                                   __func__, zebra_route_string(client->proto),
-                                  buf);
-               }
+                                  &rn->p);
                rib_delnode(rn, re);
        }
 }
index 417056ecb0ee7e3e6237ff914b8dd43057ecf6f3..c1ad91c8ca86e2b557e5255e6b721f30605990cd 100644 (file)
@@ -41,6 +41,7 @@
 #include "zebra/zebra_memory.h"
 #include "zebra/zebra_vrf.h"
 #include "zebra/rt_netlink.h"
+#include "zebra/interface.h"
 #include "zebra/zebra_l2.h"
 #include "zebra/zebra_vxlan.h"
 #include "zebra/zebra_evpn_mh.h"
@@ -109,24 +110,99 @@ void zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave)
        br_slave->br_if = NULL;
 }
 
-void zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave,
-                               vrf_id_t vrf_id)
+void zebra_l2_map_slave_to_bond(struct zebra_if *zif, vrf_id_t vrf_id)
 {
        struct interface *bond_if;
+       struct zebra_if *bond_zif;
+       struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info;
 
-       /* TODO: Handle change of master */
        bond_if = if_lookup_by_index_all_vrf(bond_slave->bond_ifindex);
-       if (bond_if)
-               bond_slave->bond_if = bond_if;
-       else
-               bond_slave->bond_if = if_create_ifindex(bond_slave->bond_ifindex,
-                                                       vrf_id);
+       if (bond_if == bond_slave->bond_if)
+               return;
+
+       /* unlink the slave from the old master */
+       zebra_l2_unmap_slave_from_bond(zif);
+
+       /* If the bond is present and ready link the bond-member
+        * to it
+        */
+       if (bond_if && (bond_zif = bond_if->info)) {
+               if (bond_zif->bond_info.mbr_zifs) {
+                       if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
+                               zlog_debug("bond mbr %s linked to %s",
+                                          zif->ifp->name, bond_if->name);
+                       bond_slave->bond_if = bond_if;
+                       /* link the slave to the new bond master */
+                       listnode_add(bond_zif->bond_info.mbr_zifs, zif);
+                       /* inherit protodown flags from the es-bond */
+                       if (zebra_evpn_is_es_bond(bond_if))
+                               zebra_evpn_mh_update_protodown_bond_mbr(
+                                       zif, false /*clear*/, __func__);
+               }
+       } else {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
+                       zlog_debug("bond mbr %s link to bond skipped",
+                                  zif->ifp->name);
+       }
+}
+
+void zebra_l2_unmap_slave_from_bond(struct zebra_if *zif)
+{
+       struct zebra_l2info_bondslave *bond_slave = &zif->bondslave_info;
+       struct zebra_if *bond_zif;
+
+       if (!bond_slave->bond_if) {
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
+                       zlog_debug("bond mbr %s unlink from bond skipped",
+                                  zif->ifp->name);
+               return;
+       }
+
+       if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
+               zlog_debug("bond mbr %s un-linked from %s", zif->ifp->name,
+                          bond_slave->bond_if->name);
+
+       /* unlink the slave from the bond master */
+       bond_zif = bond_slave->bond_if->info;
+       /* clear protodown flags */
+       if (zebra_evpn_is_es_bond(bond_zif->ifp))
+               zebra_evpn_mh_update_protodown_bond_mbr(zif, true /*clear*/,
+                                                       __func__);
+       listnode_delete(bond_zif->bond_info.mbr_zifs, zif);
+       bond_slave->bond_if = NULL;
 }
 
-void zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave)
+void zebra_l2if_update_bond(struct interface *ifp, bool add)
 {
-       if (bond_slave != NULL)
-               bond_slave->bond_if = NULL;
+       struct zebra_if *zif;
+       struct zebra_l2info_bond *bond;
+
+       zif = ifp->info;
+       assert(zif);
+       bond = &zif->bond_info;
+
+       if (add) {
+               if (!bond->mbr_zifs) {
+                       if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
+                               zlog_debug("bond %s mbr list create",
+                                          ifp->name);
+                       bond->mbr_zifs = list_new();
+               }
+       } else {
+               struct listnode *node;
+               struct listnode *nnode;
+               struct zebra_if *bond_mbr;
+
+               if (!bond->mbr_zifs)
+                       return;
+
+               if (IS_ZEBRA_DEBUG_EVPN_MH_ES || IS_ZEBRA_DEBUG_EVENT)
+                       zlog_debug("bond %s mbr list delete", ifp->name);
+               for (ALL_LIST_ELEMENTS(bond->mbr_zifs, node, nnode, bond_mbr))
+                       zebra_l2_unmap_slave_from_bond(bond_mbr);
+
+               list_delete(&bond->mbr_zifs);
+       }
 }
 
 /*
@@ -286,6 +362,8 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
                /* In the case of VxLAN, invoke the handler for EVPN. */
                if (zif->zif_type == ZEBRA_IF_VXLAN)
                        zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+               if (zif->es_info.es)
+                       zebra_evpn_es_local_br_port_update(zif);
        } else if (old_bridge_ifindex != IFINDEX_INTERNAL) {
                /*
                 * In the case of VxLAN, invoke the handler for EVPN.
@@ -294,6 +372,8 @@ void zebra_l2if_update_bridge_slave(struct interface *ifp,
                 */
                if (zif->zif_type == ZEBRA_IF_VXLAN)
                        zebra_vxlan_if_update(ifp, ZEBRA_VXLIF_MASTER_CHANGE);
+               if (zif->es_info.es)
+                       zebra_evpn_es_local_br_port_update(zif);
                zebra_l2_unmap_slave_from_bridge(&zif->brslave_info);
        }
 }
@@ -314,9 +394,9 @@ void zebra_l2if_update_bond_slave(struct interface *ifp, ifindex_t bond_ifindex)
 
        /* Set up or remove link with master */
        if (bond_ifindex != IFINDEX_INTERNAL)
-               zebra_l2_map_slave_to_bond(&zif->bondslave_info, ifp->vrf_id);
+               zebra_l2_map_slave_to_bond(zif, ifp->vrf_id);
        else if (old_bond_ifindex != IFINDEX_INTERNAL)
-               zebra_l2_unmap_slave_from_bond(&zif->bondslave_info);
+               zebra_l2_unmap_slave_from_bond(zif);
 }
 
 void zebra_vlan_bitmap_compute(struct interface *ifp,
index f3b15c777057eb7768b09d3be77d36e97921b88b..4b84eb071efcf75a56847506d68aa64ca8a02a3b 100644 (file)
@@ -40,6 +40,10 @@ struct zebra_l2info_brslave {
        ns_id_t ns_id; /* network namespace where bridge is */
 };
 
+struct zebra_l2info_bond {
+       struct list *mbr_zifs; /* slaves using this bond as a master */
+};
+
 /* zebra L2 interface information - bridge interface */
 struct zebra_l2info_bridge {
        uint8_t vlan_aware; /* VLAN-aware bridge? */
@@ -86,10 +90,6 @@ extern void zebra_l2_map_slave_to_bridge(struct zebra_l2info_brslave *br_slave,
                                         struct zebra_ns *zns);
 extern void
 zebra_l2_unmap_slave_from_bridge(struct zebra_l2info_brslave *br_slave);
-extern void
-zebra_l2_map_slave_to_bond(struct zebra_l2info_bondslave *bond_slave, vrf_id_t);
-extern void
-zebra_l2_unmap_slave_from_bond(struct zebra_l2info_bondslave *bond_slave);
 extern void zebra_l2_bridge_add_update(struct interface *ifp,
                                       struct zebra_l2info_bridge *bridge_info,
                                       int add);
@@ -112,6 +112,7 @@ extern void zebra_vlan_bitmap_compute(struct interface *ifp,
                uint32_t vid_start, uint16_t vid_end);
 extern void zebra_vlan_mbr_re_eval(struct interface *ifp,
                bitfield_t vlan_bitmap);
+extern void zebra_l2if_update_bond(struct interface *ifp, bool add);
 
 #ifdef __cplusplus
 }
index 343e7801db5a42f2472a3f99a784f4cb8d11e5a8..8a66d6de726a99e90f810a56598c2b0f5d0ce358 100644 (file)
@@ -74,9 +74,10 @@ static void zebra_mlag_sched_read(void)
 
 static int zebra_mlag_read(struct thread *thread)
 {
+       static uint32_t mlag_rd_buf_offset;
        uint32_t *msglen;
        uint32_t h_msglen;
-       uint32_t tot_len, curr_len = 0;
+       uint32_t tot_len, curr_len = mlag_rd_buf_offset;
 
        /*
         * Received message in sock_stream looks like below
@@ -99,6 +100,7 @@ static int zebra_mlag_read(struct thread *thread)
                        zebra_mlag_handle_process_state(MLAG_DOWN);
                        return -1;
                }
+               mlag_rd_buf_offset += data_len;
                if (data_len != (ssize_t)(ZEBRA_MLAG_LEN_SIZE - curr_len)) {
                        /* Try again later */
                        zebra_mlag_sched_read();
@@ -136,6 +138,7 @@ static int zebra_mlag_read(struct thread *thread)
                        zebra_mlag_handle_process_state(MLAG_DOWN);
                        return -1;
                }
+               mlag_rd_buf_offset += data_len;
                if (data_len != (ssize_t)(tot_len - curr_len)) {
                        /* Try again later */
                        zebra_mlag_sched_read();
@@ -157,6 +160,7 @@ static int zebra_mlag_read(struct thread *thread)
 
        /* Register read thread. */
        zebra_mlag_reset_read_buffer();
+       mlag_rd_buf_offset = 0;
        zebra_mlag_sched_read();
        return 0;
 }
index 03b8c8de1fca64f8555d02e6748f1286babbcb07..dc4969501991de638fa4fb7ee498435e95592e35 100644 (file)
 
 DEFINE_MTYPE_STATIC(ZEBRA, LSP, "MPLS LSP object")
 DEFINE_MTYPE_STATIC(ZEBRA, FEC, "MPLS FEC object")
-DEFINE_MTYPE_STATIC(ZEBRA, SLSP, "MPLS static LSP config")
 DEFINE_MTYPE_STATIC(ZEBRA, NHLFE, "MPLS nexthop object")
-DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE, "MPLS static nexthop object")
-DEFINE_MTYPE_STATIC(ZEBRA, SNHLFE_IFNAME, "MPLS static nexthop ifname")
 
 int mpls_enabled;
 
@@ -101,7 +98,8 @@ static void lsp_check_free(struct hash *lsp_table, zebra_lsp_t **plsp);
 /* Free lsp; sets caller's pointer to NULL */
 static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp);
 
-static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size);
+static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size);
+static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size);
 static int nhlfe_nhop_match(zebra_nhlfe_t *nhlfe, enum nexthop_types_t gtype,
                            const union g_addr *gate, ifindex_t ifindex);
 static zebra_nhlfe_t *nhlfe_find(struct nhlfe_list_head *list,
@@ -124,19 +122,6 @@ static int mpls_static_lsp_uninstall_all(struct zebra_vrf *zvrf,
 static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty,
                        const char *indent);
 static void lsp_print(struct vty *vty, zebra_lsp_t *lsp);
-static void *slsp_alloc(void *p);
-static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
-                       const union g_addr *gate, ifindex_t ifindex);
-static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
-                                  enum nexthop_types_t gtype,
-                                  const union g_addr *gate, ifindex_t ifindex);
-static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
-                                 enum nexthop_types_t gtype,
-                                 const union g_addr *gate, ifindex_t ifindex,
-                                 mpls_label_t out_label);
-static int snhlfe_del(zebra_snhlfe_t *snhlfe);
-static int snhlfe_del_all(zebra_slsp_t *slsp);
-static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size);
 static void mpls_lsp_uninstall_all_type(struct hash_bucket *bucket, void *ctxt);
 static void mpls_ftn_uninstall_all(struct zebra_vrf *zvrf,
                                   int afi, enum lsp_types_t lsp_type);
@@ -145,9 +130,6 @@ static int lsp_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type,
 static int lsp_backup_znh_install(zebra_lsp_t *lsp, enum lsp_types_t type,
                                  const struct zapi_nexthop *znh);
 
-/* List implementations - declare internal linkage */
-DECLARE_DLIST(snhlfe_list, struct zebra_snhlfe_t_, list);
-
 /* Static functions */
 
 /*
@@ -349,7 +331,6 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
        zebra_fec_t *fec;
        uint32_t old_label, new_label;
        int af;
-       char buf[BUFSIZ];
 
        for (af = AFI_IP; af < AFI_MAX; af++) {
                if (zvrf->fec_table[af] == NULL)
@@ -366,9 +347,6 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
                            || fec->label_index == MPLS_INVALID_LABEL_INDEX)
                                continue;
 
-                       if (IS_ZEBRA_DEBUG_MPLS)
-                               prefix2str(&rn->p, buf, BUFSIZ);
-
                        /* Save old label, determine new label. */
                        old_label = fec->label;
                        new_label =
@@ -382,8 +360,8 @@ static void fec_evaluate(struct zebra_vrf *zvrf)
 
                        if (IS_ZEBRA_DEBUG_MPLS)
                                zlog_debug(
-                                       "Update fec %s new label %u upon label block",
-                                       buf, new_label);
+                                       "Update fec %pRN new label %u upon label block",
+                                       rn, new_label);
 
                        fec->label = new_label;
                        fec_update_clients(fec);
@@ -512,8 +490,7 @@ static void fec_print(zebra_fec_t *fec, struct vty *vty)
        char buf[BUFSIZ];
 
        rn = fec->rn;
-       prefix2str(&rn->p, buf, BUFSIZ);
-       vty_out(vty, "%s\n", buf);
+       vty_out(vty, "%pRN\n", rn);
        vty_out(vty, "  Label: %s", label2str(fec->label, buf, BUFSIZ));
        if (fec->label_index != MPLS_INVALID_LABEL_INDEX)
                vty_out(vty, ", Label Index: %u", fec->label_index);
@@ -1173,9 +1150,9 @@ static void lsp_free(struct hash *lsp_table, zebra_lsp_t **plsp)
 /*
  * Create printable string for NHLFE entry.
  */
-static char *nhlfe2str(zebra_nhlfe_t *nhlfe, char *buf, int size)
+static char *nhlfe2str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
 {
-       struct nexthop *nexthop;
+       const struct nexthop *nexthop;
 
        buf[0] = '\0';
        nexthop = nhlfe->nexthop;
@@ -1414,7 +1391,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
                        continue;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
-                       nhlfe2str(nhlfe, buf, BUFSIZ);
+                       nhlfe2str(nhlfe, buf, sizeof(buf));
                        zlog_debug(
                                "Del LSP in-label %u type %d nexthop %s flags 0x%x",
                                lsp->ile.in_label, type, buf, nhlfe->flags);
@@ -1435,7 +1412,7 @@ static int mpls_lsp_uninstall_all(struct hash *lsp_table, zebra_lsp_t *lsp,
                        continue;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
-                       nhlfe2str(nhlfe, buf, BUFSIZ);
+                       nhlfe2str(nhlfe, buf, sizeof(buf));
                        zlog_debug(
                                "Del backup LSP in-label %u type %d nexthop %s flags 0x%x",
                                lsp->ile.in_label, type, buf, nhlfe->flags);
@@ -1520,7 +1497,8 @@ static json_object *nhlfe_json(zebra_nhlfe_t *nhlfe)
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
                json_object_string_add(json_nhlfe, "nexthop",
-                                      inet_ntoa(nexthop->gate.ipv4));
+                                      inet_ntop(AF_INET, &nexthop->gate.ipv4,
+                                                buf, sizeof(buf)));
                break;
        case NEXTHOP_TYPE_IPV6:
        case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -1578,7 +1556,7 @@ static void nhlfe_print(zebra_nhlfe_t *nhlfe, struct vty *vty,
        switch (nexthop->type) {
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               vty_out(vty, "  via %s", inet_ntoa(nexthop->gate.ipv4));
+               vty_out(vty, "  via %pI4", &nexthop->gate.ipv4);
                if (nexthop->ifindex)
                        vty_out(vty, " dev %s",
                                ifindex2ifname(nexthop->ifindex,
@@ -1710,188 +1688,6 @@ static int lsp_cmp(const zebra_lsp_t *lsp1, const zebra_lsp_t *lsp2)
        return 0;
 }
 
-/*
- * Callback to allocate static LSP.
- */
-static void *slsp_alloc(void *p)
-{
-       const zebra_ile_t *ile = p;
-       zebra_slsp_t *slsp;
-
-       slsp = XCALLOC(MTYPE_SLSP, sizeof(zebra_slsp_t));
-       slsp->ile = *ile;
-       snhlfe_list_init(&slsp->snhlfe_list);
-
-       return ((void *)slsp);
-}
-
-/*
- * Compare two static LSPs based on their label values.
- */
-static int slsp_cmp(const zebra_slsp_t *slsp1, const zebra_slsp_t *slsp2)
-{
-       if (slsp1->ile.in_label < slsp2->ile.in_label)
-               return -1;
-
-       if (slsp1->ile.in_label > slsp2->ile.in_label)
-               return 1;
-
-       return 0;
-}
-
-/*
- * Check if static NHLFE matches with search info passed.
- */
-static int snhlfe_match(zebra_snhlfe_t *snhlfe, enum nexthop_types_t gtype,
-                       const union g_addr *gate, ifindex_t ifindex)
-{
-       int cmp = 1;
-
-       if (snhlfe->gtype != gtype)
-               return 1;
-
-       switch (snhlfe->gtype) {
-       case NEXTHOP_TYPE_IPV4:
-               cmp = memcmp(&(snhlfe->gate.ipv4), &(gate->ipv4),
-                            sizeof(struct in_addr));
-               break;
-       case NEXTHOP_TYPE_IPV6:
-       case NEXTHOP_TYPE_IPV6_IFINDEX:
-               cmp = memcmp(&(snhlfe->gate.ipv6), &(gate->ipv6),
-                            sizeof(struct in6_addr));
-               if (!cmp && snhlfe->gtype == NEXTHOP_TYPE_IPV6_IFINDEX)
-                       cmp = !(snhlfe->ifindex == ifindex);
-               break;
-       default:
-               break;
-       }
-
-       return cmp;
-}
-
-/*
- * Locate static NHLFE that matches with passed info.
- */
-static zebra_snhlfe_t *snhlfe_find(zebra_slsp_t *slsp,
-                                  enum nexthop_types_t gtype,
-                                  const union g_addr *gate, ifindex_t ifindex)
-{
-       zebra_snhlfe_t *snhlfe;
-
-       if (!slsp)
-               return NULL;
-
-       frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
-               if (!snhlfe_match(snhlfe, gtype, gate, ifindex))
-                       break;
-       }
-
-       return snhlfe;
-}
-
-
-/*
- * Add static NHLFE. Base LSP config entry must have been created
- * and duplicate check done.
- */
-static zebra_snhlfe_t *snhlfe_add(zebra_slsp_t *slsp,
-                                 enum nexthop_types_t gtype,
-                                 const union g_addr *gate, ifindex_t ifindex,
-                                 mpls_label_t out_label)
-{
-       zebra_snhlfe_t *snhlfe;
-
-       if (!slsp)
-               return NULL;
-
-       snhlfe = XCALLOC(MTYPE_SNHLFE, sizeof(zebra_snhlfe_t));
-       snhlfe->slsp = slsp;
-       snhlfe->out_label = out_label;
-       snhlfe->gtype = gtype;
-       switch (gtype) {
-       case NEXTHOP_TYPE_IPV4:
-               snhlfe->gate.ipv4 = gate->ipv4;
-               break;
-       case NEXTHOP_TYPE_IPV6:
-       case NEXTHOP_TYPE_IPV6_IFINDEX:
-               snhlfe->gate.ipv6 = gate->ipv6;
-               if (ifindex)
-                       snhlfe->ifindex = ifindex;
-               break;
-       default:
-               XFREE(MTYPE_SNHLFE, snhlfe);
-               return NULL;
-       }
-
-       snhlfe_list_add_head(&slsp->snhlfe_list, snhlfe);
-
-       return snhlfe;
-}
-
-/*
- * Delete static NHLFE. Entry must be present on list.
- */
-static int snhlfe_del(zebra_snhlfe_t *snhlfe)
-{
-       zebra_slsp_t *slsp;
-
-       if (!snhlfe)
-               return -1;
-
-       slsp = snhlfe->slsp;
-       if (!slsp)
-               return -1;
-
-       snhlfe_list_del(&slsp->snhlfe_list, snhlfe);
-
-       XFREE(MTYPE_SNHLFE_IFNAME, snhlfe->ifname);
-       XFREE(MTYPE_SNHLFE, snhlfe);
-
-       return 0;
-}
-
-/*
- * Delete all static NHLFE entries for this LSP (in label).
- */
-static int snhlfe_del_all(zebra_slsp_t *slsp)
-{
-       zebra_snhlfe_t *snhlfe;
-
-       if (!slsp)
-               return -1;
-
-       frr_each_safe(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
-               snhlfe_del(snhlfe);
-       }
-
-       return 0;
-}
-
-/*
- * Create printable string for NHLFE configuration.
- */
-static char *snhlfe2str(zebra_snhlfe_t *snhlfe, char *buf, int size)
-{
-       buf[0] = '\0';
-       switch (snhlfe->gtype) {
-       case NEXTHOP_TYPE_IPV4:
-               inet_ntop(AF_INET, &snhlfe->gate.ipv4, buf, size);
-               break;
-       case NEXTHOP_TYPE_IPV6:
-       case NEXTHOP_TYPE_IPV6_IFINDEX:
-               inet_ntop(AF_INET6, &snhlfe->gate.ipv6, buf, size);
-               if (snhlfe->ifindex)
-                       strlcat(buf,
-                               ifindex2ifname(snhlfe->ifindex, VRF_DEFAULT),
-                               size);
-               break;
-       default:
-               break;
-       }
-
-       return buf;
-}
-
 /*
  * Initialize work queue for processing changed LSPs.
  */
@@ -2443,7 +2239,6 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
 {
        struct route_table *table;
        zebra_fec_t *fec;
-       char buf[BUFSIZ];
        bool new_client;
        bool label_change = false;
        uint32_t old_label;
@@ -2454,14 +2249,11 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
        if (!table)
                return -1;
 
-       if (IS_ZEBRA_DEBUG_MPLS)
-               prefix2str(p, buf, BUFSIZ);
-
        if (label != MPLS_INVALID_LABEL && have_label_index) {
                flog_err(
                        EC_ZEBRA_FEC_LABEL_INDEX_LABEL_CONFLICT,
-                       "Rejecting FEC register for %s with both label %u and Label Index %u specified, client %s",
-                       buf, label, label_index,
+                       "Rejecting FEC register for %pFX with both label %u and Label Index %u specified, client %s",
+                       p, label, label_index,
                        zebra_route_string(client->proto));
                return -1;
        }
@@ -2473,8 +2265,8 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
                if (!fec) {
                        flog_err(
                                EC_ZEBRA_FEC_ADD_FAILED,
-                               "Failed to add FEC %s upon register, client %s",
-                               buf, zebra_route_string(client->proto));
+                               "Failed to add FEC %pFX upon register, client %s",
+                               p, zebra_route_string(client->proto));
                        return -1;
                }
 
@@ -2500,7 +2292,7 @@ int zebra_mpls_fec_register(struct zebra_vrf *zvrf, struct prefix *p,
                listnode_add(fec->client_list, client);
 
        if (IS_ZEBRA_DEBUG_MPLS)
-               zlog_debug("FEC %s label%s %u %s by client %s%s", buf,
+               zlog_debug("FEC %pFX label%s %u %s by client %s%s", p,
                           have_label_index ? " index" : "",
                           have_label_index ? label_index : label,
                           new_client ? "registered" : "updated",
@@ -2551,28 +2343,23 @@ int zebra_mpls_fec_unregister(struct zebra_vrf *zvrf, struct prefix *p,
 {
        struct route_table *table;
        zebra_fec_t *fec;
-       char buf[BUFSIZ];
 
        table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
        if (!table)
                return -1;
 
-       if (IS_ZEBRA_DEBUG_MPLS)
-               prefix2str(p, buf, BUFSIZ);
-
        fec = fec_find(table, p);
        if (!fec) {
-               prefix2str(p, buf, BUFSIZ);
                flog_err(EC_ZEBRA_FEC_RM_FAILED,
-                        "Failed to find FEC %s upon unregister, client %s",
-                        buf, zebra_route_string(client->proto));
+                        "Failed to find FEC %pFX upon unregister, client %s",
+                        p, zebra_route_string(client->proto));
                return -1;
        }
 
        listnode_delete(fec->client_list, client);
 
        if (IS_ZEBRA_DEBUG_MPLS)
-               zlog_debug("FEC %s unregistered by client %s", buf,
+               zlog_debug("FEC %pFX unregistered by client %s", p,
                           zebra_route_string(client->proto));
 
        /* If not a configured entry, delete the FEC if no other clients. Before
@@ -2713,7 +2500,6 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
 {
        struct route_table *table;
        zebra_fec_t *fec;
-       char buf[BUFSIZ];
        mpls_label_t old_label;
        int ret = 0;
 
@@ -2721,23 +2507,19 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
        if (!table)
                return -1;
 
-       if (IS_ZEBRA_DEBUG_MPLS)
-               prefix2str(p, buf, BUFSIZ);
-
        /* Update existing FEC or create a new one. */
        fec = fec_find(table, p);
        if (!fec) {
                fec = fec_add(table, p, in_label, FEC_FLAG_CONFIGURED,
                              MPLS_INVALID_LABEL_INDEX);
                if (!fec) {
-                       prefix2str(p, buf, BUFSIZ);
                        flog_err(EC_ZEBRA_FEC_ADD_FAILED,
-                                "Failed to add FEC %s upon config", buf);
+                                "Failed to add FEC %pFX upon config", p);
                        return -1;
                }
 
                if (IS_ZEBRA_DEBUG_MPLS)
-                       zlog_debug("Add fec %s label %u", buf, in_label);
+                       zlog_debug("Add fec %pFX label %u", p, in_label);
        } else {
                fec->flags |= FEC_FLAG_CONFIGURED;
                if (fec->label == in_label)
@@ -2747,7 +2529,7 @@ int zebra_mpls_static_fec_add(struct zebra_vrf *zvrf, struct prefix *p,
                /* Label change, update clients. */
                old_label = fec->label;
                if (IS_ZEBRA_DEBUG_MPLS)
-                       zlog_debug("Update fec %s new label %u", buf, in_label);
+                       zlog_debug("Update fec %pFX new label %u", p, in_label);
 
                fec->label = in_label;
                fec_update_clients(fec);
@@ -2770,7 +2552,6 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
        struct route_table *table;
        zebra_fec_t *fec;
        mpls_label_t old_label;
-       char buf[BUFSIZ];
 
        table = zvrf->fec_table[family2afi(PREFIX_FAMILY(p))];
        if (!table)
@@ -2778,15 +2559,13 @@ int zebra_mpls_static_fec_del(struct zebra_vrf *zvrf, struct prefix *p)
 
        fec = fec_find(table, p);
        if (!fec) {
-               prefix2str(p, buf, BUFSIZ);
                flog_err(EC_ZEBRA_FEC_RM_FAILED,
-                        "Failed to find FEC %s upon delete", buf);
+                        "Failed to find FEC %pFX upon delete", p);
                return -1;
        }
 
        if (IS_ZEBRA_DEBUG_MPLS) {
-               prefix2str(p, buf, BUFSIZ);
-               zlog_debug("Delete fec %s label %u label index %u", buf,
+               zlog_debug("Delete fec %pFX label %u label index %u", p,
                           fec->label, fec->label_index);
        }
 
@@ -2820,7 +2599,6 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
        struct route_node *rn;
        int af;
        zebra_fec_t *fec;
-       char buf[BUFSIZ];
        int write = 0;
 
        for (af = AFI_IP; af < AFI_MAX; af++) {
@@ -2839,8 +2617,7 @@ int zebra_mpls_write_fec_config(struct vty *vty, struct zebra_vrf *zvrf)
                                continue;
 
                        write = 1;
-                       prefix2str(&rn->p, buf, BUFSIZ);
-                       vty_out(vty, "mpls label bind %s %s\n", buf,
+                       vty_out(vty, "mpls label bind %pFX %s\n", &rn->p,
                                label2str(fec->label, lstr, BUFSIZ));
                }
        }
@@ -3046,7 +2823,7 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
                             const struct zapi_labels *zl)
 {
        int i, counter, ret = 0;
-       char buf[NEXTHOP_STRLEN], prefix_buf[PREFIX_STRLEN];
+       char buf[NEXTHOP_STRLEN];
        const struct zapi_nexthop *znh;
        struct route_table *table;
        struct route_node *rn = NULL;
@@ -3110,12 +2887,10 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
                         * attempted to manage LSPs before trying to
                         * find a route/FEC, so we'll continue that way.
                         */
-                       if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_MPLS) {
-                               prefix2str(prefix, prefix_buf,
-                                          sizeof(prefix_buf));
-                               zlog_debug("%s: FTN update requested: no route for prefix %s",
-                                          __func__, prefix_buf);
-                       }
+                       if (IS_ZEBRA_DEBUG_RECV || IS_ZEBRA_DEBUG_MPLS)
+                               zlog_debug(
+                                       "%s: FTN update requested: no route for prefix %pFX",
+                                       __func__, prefix);
                }
        }
 
@@ -3157,9 +2932,9 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
                        counter++;
                } else if (IS_ZEBRA_DEBUG_RECV | IS_ZEBRA_DEBUG_MPLS) {
                        zapi_nexthop2str(znh, buf, sizeof(buf));
-                       prefix2str(prefix, prefix_buf, sizeof(prefix_buf));
-                       zlog_debug("%s: Unable to update FEC: prefix %s, label %u, znh %s",
-                                  __func__, prefix_buf, zl->local_label, buf);
+                       zlog_debug(
+                               "%s: Unable to update FEC: prefix %pFX, label %u, znh %s",
+                               __func__, prefix, zl->local_label, buf);
                }
        }
 
@@ -3207,9 +2982,9 @@ int mpls_zapi_labels_process(bool add_p, struct zebra_vrf *zvrf,
                        counter++;
                } else if (IS_ZEBRA_DEBUG_RECV | IS_ZEBRA_DEBUG_MPLS) {
                        zapi_nexthop2str(znh, buf, sizeof(buf));
-                       prefix2str(prefix, prefix_buf, sizeof(prefix_buf));
-                       zlog_debug("%s: Unable to update backup FEC: prefix %s, label %u, znh %s",
-                                  __func__, prefix_buf, zl->local_label, buf);
+                       zlog_debug(
+                               "%s: Unable to update backup FEC: prefix %pFX, label %u, znh %s",
+                               __func__, prefix, zl->local_label, buf);
                }
        }
 
@@ -3633,8 +3408,9 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
 {
        struct hash *slsp_table;
        zebra_ile_t tmp_ile;
-       zebra_slsp_t *slsp;
-       zebra_snhlfe_t *snhlfe;
+       zebra_lsp_t *lsp;
+       zebra_nhlfe_t *nhlfe;
+       const struct nexthop *nh;
 
        /* Lookup table. */
        slsp_table = zvrf->slsp_table;
@@ -3643,26 +3419,37 @@ int zebra_mpls_lsp_label_consistent(struct zebra_vrf *zvrf,
 
        /* If entry is not present, exit. */
        tmp_ile.in_label = in_label;
-       slsp = hash_lookup(slsp_table, &tmp_ile);
-       if (!slsp)
+       lsp = hash_lookup(slsp_table, &tmp_ile);
+       if (!lsp)
                return 1;
 
-       snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
-       if (snhlfe) {
-               if (snhlfe->out_label == out_label)
+       nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC,
+                          gtype, gate, ifindex);
+       if (nhlfe) {
+               nh = nhlfe->nexthop;
+
+               if (nh == NULL || nh->nh_label == NULL)
+                       return 0;
+
+               if (nh->nh_label->label[0] == out_label)
                        return 1;
 
                /* If not only NHLFE, cannot allow label change. */
-               if (snhlfe != snhlfe_list_first(&slsp->snhlfe_list) ||
-                   snhlfe_list_next(&slsp->snhlfe_list, snhlfe) != NULL)
+               if (nhlfe != nhlfe_list_first(&lsp->nhlfe_list) ||
+                   nhlfe_list_next(&lsp->nhlfe_list, nhlfe) != NULL)
                        return 0;
        } else {
                /* If other NHLFEs exist, label operation must match. */
-               snhlfe = snhlfe_list_first(&slsp->snhlfe_list);
-               if (snhlfe != NULL) {
+               nhlfe = nhlfe_list_first(&lsp->nhlfe_list);
+               if (nhlfe != NULL) {
                        int cur_op, new_op;
 
-                       cur_op = (snhlfe->out_label ==
+                       nh = nhlfe->nexthop;
+
+                       if (nh == NULL || nh->nh_label == NULL)
+                               return 0;
+
+                       cur_op = (nh->nh_label->label[0] ==
                                  MPLS_LABEL_IMPLICIT_NULL);
                        new_op = (out_label == MPLS_LABEL_IMPLICIT_NULL);
                        if (cur_op != new_op)
@@ -3689,8 +3476,8 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
 {
        struct hash *slsp_table;
        zebra_ile_t tmp_ile;
-       zebra_slsp_t *slsp;
-       zebra_snhlfe_t *snhlfe;
+       zebra_lsp_t *lsp;
+       zebra_nhlfe_t *nhlfe;
        char buf[BUFSIZ];
 
        /* Lookup table. */
@@ -3700,31 +3487,47 @@ int zebra_mpls_static_lsp_add(struct zebra_vrf *zvrf, mpls_label_t in_label,
 
        /* Find or create LSP. */
        tmp_ile.in_label = in_label;
-       slsp = hash_get(slsp_table, &tmp_ile, slsp_alloc);
-       if (!slsp)
+       lsp = hash_get(slsp_table, &tmp_ile, lsp_alloc);
+       if (!lsp)
                return -1;
 
-       snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
-       if (snhlfe) {
-               if (snhlfe->out_label == out_label)
+       nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC, gtype, gate,
+                          ifindex);
+       if (nhlfe) {
+               struct nexthop *nh = nhlfe->nexthop;
+
+               assert(nh);
+               assert(nh->nh_label);
+
+               /* Compare existing nexthop */
+               if (nh->nh_label->num_labels == 1 &&
+                   nh->nh_label->label[0] == out_label)
                        /* No change */
                        return 0;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
-                       snhlfe2str(snhlfe, buf, sizeof(buf));
+                       nhlfe2str(nhlfe, buf, sizeof(buf));
                        zlog_debug(
                                "Upd static LSP in-label %u nexthop %s out-label %u (old %u)",
-                               in_label, buf, out_label, snhlfe->out_label);
+                               in_label, buf, out_label,
+                               nh->nh_label->label[0]);
+               }
+               if (nh->nh_label->num_labels == 1)
+                       nh->nh_label->label[0] = out_label;
+               else {
+                       nexthop_del_labels(nh);
+                       nexthop_add_labels(nh, ZEBRA_LSP_STATIC, 1, &out_label);
                }
-               snhlfe->out_label = out_label;
+
        } else {
                /* Add static LSP entry to this nexthop */
-               snhlfe = snhlfe_add(slsp, gtype, gate, ifindex, out_label);
-               if (!snhlfe)
+               nhlfe = nhlfe_add(lsp, ZEBRA_LSP_STATIC, gtype, gate,
+                                 ifindex, 1, &out_label, false /*backup*/);
+               if (!nhlfe)
                        return -1;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
-                       snhlfe2str(snhlfe, buf, sizeof(buf));
+                       nhlfe2str(nhlfe, buf, sizeof(buf));
                        zlog_debug(
                                "Add static LSP in-label %u nexthop %s out-label %u",
                                in_label, buf, out_label);
@@ -3752,8 +3555,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
 {
        struct hash *slsp_table;
        zebra_ile_t tmp_ile;
-       zebra_slsp_t *slsp;
-       zebra_snhlfe_t *snhlfe;
+       zebra_lsp_t *lsp;
+       zebra_nhlfe_t *nhlfe;
 
        /* Lookup table. */
        slsp_table = zvrf->slsp_table;
@@ -3762,8 +3565,8 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
 
        /* If entry is not present, exit. */
        tmp_ile.in_label = in_label;
-       slsp = hash_lookup(slsp_table, &tmp_ile);
-       if (!slsp)
+       lsp = hash_lookup(slsp_table, &tmp_ile);
+       if (!lsp)
                return 0;
 
        /* Is it delete of entire LSP or a specific NHLFE? */
@@ -3775,16 +3578,19 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
                mpls_static_lsp_uninstall_all(zvrf, in_label);
 
                /* Delete all static NHLFEs */
-               snhlfe_del_all(slsp);
+               frr_each_safe(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
+                       nhlfe_del(nhlfe);
+               }
        } else {
                /* Find specific NHLFE, exit if not found. */
-               snhlfe = snhlfe_find(slsp, gtype, gate, ifindex);
-               if (!snhlfe)
+               nhlfe = nhlfe_find(&lsp->nhlfe_list, ZEBRA_LSP_STATIC,
+                                  gtype, gate, ifindex);
+               if (!nhlfe)
                        return 0;
 
                if (IS_ZEBRA_DEBUG_MPLS) {
                        char buf[BUFSIZ];
-                       snhlfe2str(snhlfe, buf, BUFSIZ);
+                       nhlfe2str(nhlfe, buf, sizeof(buf));
                        zlog_debug("Del static LSP in-label %u nexthop %s",
                                   in_label, buf);
                }
@@ -3794,14 +3600,15 @@ int zebra_mpls_static_lsp_del(struct zebra_vrf *zvrf, mpls_label_t in_label,
                                   gate, ifindex, false);
 
                /* Delete static LSP NHLFE */
-               snhlfe_del(snhlfe);
+               nhlfe_del(nhlfe);
        }
 
        /* Remove entire static LSP entry if no NHLFE - valid in either case
-        * above. */
-       if (snhlfe_list_first(&slsp->snhlfe_list) == NULL) {
-               slsp = hash_release(slsp_table, &tmp_ile);
-               XFREE(MTYPE_SLSP, slsp);
+        * above.
+        */
+       if (nhlfe_list_first(&lsp->nhlfe_list) == NULL) {
+               lsp = hash_release(slsp_table, &tmp_ile);
+               XFREE(MTYPE_LSP, lsp);
        }
 
        return 0;
@@ -3948,24 +3755,59 @@ void zebra_mpls_print_lsp_table(struct vty *vty, struct zebra_vrf *zvrf,
        list_delete(&lsp_list);
 }
 
+/*
+ * Create printable string for static LSP configuration.
+ */
+static char *nhlfe_config_str(const zebra_nhlfe_t *nhlfe, char *buf, int size)
+{
+       const struct nexthop *nh;
+
+       nh = nhlfe->nexthop;
+
+       buf[0] = '\0';
+       switch (nh->type) {
+       case NEXTHOP_TYPE_IPV4:
+               inet_ntop(AF_INET, &nh->gate.ipv4, buf, size);
+               break;
+       case NEXTHOP_TYPE_IPV6:
+       case NEXTHOP_TYPE_IPV6_IFINDEX:
+               inet_ntop(AF_INET6, &nh->gate.ipv6, buf, size);
+               if (nh->ifindex)
+                       strlcat(buf,
+                               ifindex2ifname(nh->ifindex, VRF_DEFAULT),
+                               size);
+               break;
+       default:
+               break;
+       }
+
+       return buf;
+}
+
 /*
  * Display MPLS LSP configuration of all static LSPs (VTY command handler).
  */
 int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
 {
-       zebra_slsp_t *slsp;
-       zebra_snhlfe_t *snhlfe;
+       zebra_lsp_t *lsp;
+       zebra_nhlfe_t *nhlfe;
+       struct nexthop *nh;
        struct listnode *node;
        struct list *slsp_list =
-               hash_get_sorted_list(zvrf->slsp_table, slsp_cmp);
+               hash_get_sorted_list(zvrf->slsp_table, lsp_cmp);
 
-       for (ALL_LIST_ELEMENTS_RO(slsp_list, node, slsp)) {
-               frr_each(snhlfe_list, &slsp->snhlfe_list, snhlfe) {
+       for (ALL_LIST_ELEMENTS_RO(slsp_list, node, lsp)) {
+               frr_each(nhlfe_list, &lsp->nhlfe_list, nhlfe) {
                        char buf[BUFSIZ];
                        char lstr[30];
 
-                       snhlfe2str(snhlfe, buf, sizeof(buf));
-                       switch (snhlfe->out_label) {
+                       nh = nhlfe->nexthop;
+                       if (nh == NULL || nh->nh_label == NULL)
+                               continue;
+
+                       nhlfe_config_str(nhlfe, buf, sizeof(buf));
+
+                       switch (nh->nh_label->label[0]) {
                        case MPLS_LABEL_IPV4_EXPLICIT_NULL:
                        case MPLS_LABEL_IPV6_EXPLICIT_NULL:
                                strlcpy(lstr, "explicit-null", sizeof(lstr));
@@ -3975,11 +3817,11 @@ int zebra_mpls_write_lsp_config(struct vty *vty, struct zebra_vrf *zvrf)
                                break;
                        default:
                                snprintf(lstr, sizeof(lstr), "%u",
-                                        snhlfe->out_label);
+                                        nh->nh_label->label[0]);
                                break;
                        }
 
-                       vty_out(vty, "mpls lsp %u %s %s\n", slsp->ile.in_label,
+                       vty_out(vty, "mpls lsp %u %s %s\n", lsp->ile.in_label,
                                buf, lstr);
                }
        }
index c0e58c44e3f7a7679263c1778f2570b59168d48c..51672330409d02c7407ae1ec5e495b75d1685952 100644 (file)
@@ -50,36 +50,13 @@ extern "C" {
 /* Typedefs */
 
 typedef struct zebra_ile_t_ zebra_ile_t;
-typedef struct zebra_snhlfe_t_ zebra_snhlfe_t;
-typedef struct zebra_slsp_t_ zebra_slsp_t;
 typedef struct zebra_nhlfe_t_ zebra_nhlfe_t;
 typedef struct zebra_lsp_t_ zebra_lsp_t;
 typedef struct zebra_fec_t_ zebra_fec_t;
 
 /* Declare LSP nexthop list types */
-PREDECL_DLIST(snhlfe_list);
 PREDECL_DLIST(nhlfe_list);
 
-/*
- * (Outgoing) nexthop label forwarding entry configuration
- */
-struct zebra_snhlfe_t_ {
-       /* Nexthop information */
-       enum nexthop_types_t gtype;
-       union g_addr gate;
-       char *ifname;
-       ifindex_t ifindex;
-
-       /* Out label. */
-       mpls_label_t out_label;
-
-       /* Backpointer to base entry. */
-       zebra_slsp_t *slsp;
-
-       /* Linkage for LSPs' lists */
-       struct snhlfe_list_item list;
-};
-
 /*
  * (Outgoing) nexthop label forwarding entry
  */
@@ -115,17 +92,6 @@ struct zebra_ile_t_ {
        mpls_label_t in_label;
 };
 
-/*
- * Label swap entry static configuration.
- */
-struct zebra_slsp_t_ {
-       /* Incoming label */
-       zebra_ile_t ile;
-
-       /* List of outgoing nexthop static configuration */
-       struct snhlfe_list_head snhlfe_list;
-};
-
 /*
  * Label swap entry (ile -> list of nhlfes)
  */
index 583b666e66acc71350251ced00b0a2f405d106a8..3af805558dd8c1474c2afa18061c9f58466cc282 100644 (file)
@@ -47,8 +47,8 @@ void zebra_ipmr_route_stats(ZAPI_HANDLER_ARGS)
                char sbuf[40];
                char gbuf[40];
 
-               strlcpy(sbuf, inet_ntoa(mroute.sg.src), sizeof(sbuf));
-               strlcpy(gbuf, inet_ntoa(mroute.sg.grp), sizeof(gbuf));
+               inet_ntop(AF_INET, &mroute.sg.src, sbuf, sizeof(sbuf));
+               inet_ntop(AF_INET, &mroute.sg.grp, gbuf, sizeof(gbuf));
 
                zlog_debug("Asking for (%s,%s)[%s(%u)] mroute information",
                           sbuf, gbuf, zvrf->vrf->name, zvrf->vrf->vrf_id);
index b4ed910b4d8b235ce0a745134c9518baf28ed14b..df957703070ed2b8ee1a926cc5c5d4a507a7682f 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "lib/log.h"
 #include "lib/northbound.h"
+#include "lib/printfrr.h"
 #include "libfrr.h"
 #include "lib/command.h"
 #include "lib/routemap.h"
@@ -839,7 +840,6 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args)
 {
        struct interface *ifp;
        struct prefix prefix;
-       char buf[PREFIX_STRLEN] = {0};
 
        ifp = nb_running_get_entry(args->dnode, NULL, true);
        // addr_family = yang_dnode_get_enum(dnode, "./address-family");
@@ -850,15 +850,13 @@ int lib_interface_zebra_ip_addrs_create(struct nb_cb_create_args *args)
        case NB_EV_VALIDATE:
                if (prefix.family == AF_INET
                    && ipv4_martian(&prefix.u.prefix4)) {
-                       snprintf(args->errmsg, args->errmsg_len,
-                                "invalid address %s",
-                                prefix2str(&prefix, buf, sizeof(buf)));
+                       snprintfrr(args->errmsg, args->errmsg_len,
+                                  "invalid address %pFX", &prefix);
                        return NB_ERR_VALIDATION;
                } else if (prefix.family == AF_INET6
                           && ipv6_martian(&prefix.u.prefix6)) {
-                       snprintf(args->errmsg, args->errmsg_len,
-                                "invalid address %s",
-                                prefix2str(&prefix, buf, sizeof(buf)));
+                       snprintfrr(args->errmsg, args->errmsg_len,
+                                  "invalid address %pFX", &prefix);
                        return NB_ERR_VALIDATION;
                }
                break;
@@ -1554,7 +1552,7 @@ int lib_route_map_entry_set_action_source_v4_modify(
                }
                if (pif == NULL) {
                        snprintf(args->errmsg, args->errmsg_len,
-                                "is not a local adddress: %s",
+                                "is not a local address: %s",
                                 yang_dnode_get_string(args->dnode, NULL));
                        return NB_ERR_VALIDATION;
                }
index 204cc5da6d44c6f7fdc0a0232131580651c1b87e..e7d438b1af8836c72c9dc9aad8462d6df507e8a0 100644 (file)
@@ -65,19 +65,22 @@ int clear_evpn_dup_addr_rpc(struct nb_cb_rpc_args *args)
                        if (yang_dup_mac) {
                                yang_str2mac(yang_dup_mac->value, &mac);
                                ret = zebra_vxlan_clear_dup_detect_vni_mac(
-                                       zvrf, vni, &mac);
+                                       zvrf, vni, &mac, args->errmsg,
+                                       args->errmsg_len);
                        } else if (yang_dup_ip) {
                                yang_str2ip(yang_dup_ip->value, &host_ip);
                                ret = zebra_vxlan_clear_dup_detect_vni_ip(
-                                       zvrf, vni, &host_ip);
+                                       zvrf, vni, &host_ip, args->errmsg,
+                                       args->errmsg_len);
                        } else
                                ret = zebra_vxlan_clear_dup_detect_vni(zvrf,
                                                                       vni);
                }
        }
-       ret = (ret != CMD_SUCCESS) ? NB_ERR : NB_OK;
+       if (ret < 0)
+               return NB_ERR;
 
-       return ret;
+       return NB_OK;
 }
 
 /*
index 995fa6fb5af6cbc5410d342713e205aa26a2c180..ee2dc7a0edc11505e9486316cc298f74fdb8b676 100644 (file)
@@ -378,7 +378,7 @@ void zebra_ns_notify_close(void)
                fd = zebra_netns_notify_current->u.fd;
 
        if (zebra_netns_notify_current->master != NULL)
-               thread_cancel(zebra_netns_notify_current);
+               thread_cancel(&zebra_netns_notify_current);
 
        /* auto-removal of notify items */
        if (fd > 0)
index de79c59caaaaa60a511b8b0edbfe152780e23659..196e3c83d0a4ae18398f1a0a1dff3d6f9adce0b1 100644 (file)
@@ -56,12 +56,12 @@ static bool g_nexthops_enabled = true;
 static bool proto_nexthops_only;
 
 static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi,
-                                          int type);
+                                          int type, bool from_dplane);
 static void depends_add(struct nhg_connected_tree_head *head,
                        struct nhg_hash_entry *depend);
 static struct nhg_hash_entry *
 depends_find_add(struct nhg_connected_tree_head *head, struct nexthop *nh,
-                afi_t afi, int type);
+                afi_t afi, int type, bool from_dplane);
 static struct nhg_hash_entry *
 depends_find_id_add(struct nhg_connected_tree_head *head, uint32_t id);
 static void depends_decrement_free(struct nhg_connected_tree_head *head);
@@ -442,11 +442,8 @@ static void *zebra_nhg_hash_alloc(void *arg)
        /* Mark duplicate nexthops in a group at creation time. */
        nexthop_group_mark_duplicates(&(nhe->nhg));
 
-       zebra_nhg_connect_depends(nhe, &(copy->nhg_depends));
-
        /* Add the ifp now if it's not a group or recursive and has ifindex */
-       if (zebra_nhg_depends_is_empty(nhe) && nhe->nhg.nexthop
-           && nhe->nhg.nexthop->ifindex) {
+       if (nhe->nhg.nexthop && nhe->nhg.nexthop->ifindex) {
                struct interface *ifp = NULL;
 
                ifp = if_lookup_by_index(nhe->nhg.nexthop->ifindex,
@@ -461,7 +458,6 @@ static void *zebra_nhg_hash_alloc(void *arg)
                                nhe->nhg.nexthop->vrf_id, nhe->id);
        }
 
-
        return nhe;
 }
 
@@ -672,7 +668,7 @@ static void handle_recursive_depend(struct nhg_connected_tree_head *nhg_depends,
 static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
                           struct nhg_hash_entry *lookup,
                           struct nhg_connected_tree_head *nhg_depends,
-                          afi_t afi)
+                          afi_t afi, bool from_dplane)
 {
        bool created = false;
        bool recursive = false;
@@ -680,10 +676,11 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
        struct nexthop *nh = NULL;
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
-               zlog_debug("%s: id %u, lookup %p, vrf %d, type %d, depends %p",
-                          __func__, lookup->id, lookup,
-                          lookup->vrf_id, lookup->type,
-                          nhg_depends);
+               zlog_debug(
+                       "%s: id %u, lookup %p, vrf %d, type %d, depends %p%s",
+                       __func__, lookup->id, lookup, lookup->vrf_id,
+                       lookup->type, nhg_depends,
+                       (from_dplane ? " (from dplane)" : ""));
 
        if (lookup->id)
                (*nhe) = zebra_nhg_lookup_id(lookup->id);
@@ -705,7 +702,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
        if (lookup->id == 0)
                lookup->id = nhg_get_next_id();
 
-       if (lookup->id < ZEBRA_NHG_PROTO_LOWER) {
+       if (!from_dplane && lookup->id < ZEBRA_NHG_PROTO_LOWER) {
                /*
                 * This is a zebra hashed/owned NHG.
                 *
@@ -715,7 +712,8 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
                zebra_nhg_insert_id(newnhe);
        } else {
                /*
-                * This is upperproto owned NHG and should not be hashed to.
+                * This is upperproto owned NHG or one we read in from dataplane
+                * and should not be hashed to.
                 *
                 * It goes in ID table.
                 */
@@ -752,7 +750,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
         * resolving nexthop; or a group of nexthops, where we need
         * relationships with the corresponding singletons.
         */
-       zebra_nhg_depends_init(lookup);
+       zebra_nhg_depends_init(newnhe);
 
        nh = newnhe->nhg.nexthop;
 
@@ -779,12 +777,19 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
                                           "(R)" : "");
 
                        depends_find_add(&newnhe->nhg_depends, nh, afi,
-                                        newnhe->type);
+                                        newnhe->type, from_dplane);
                }
        }
 
        if (recursive)
-               SET_FLAG((*nhe)->flags, NEXTHOP_GROUP_RECURSIVE);
+               SET_FLAG(newnhe->flags, NEXTHOP_GROUP_RECURSIVE);
+
+       /* Attach dependent backpointers to singletons */
+       zebra_nhg_connect_depends(newnhe, &newnhe->nhg_depends);
+
+       /**
+        * Backup Nexthops
+        */
 
        if (zebra_nhg_get_backup_nhg(newnhe) == NULL ||
            zebra_nhg_get_backup_nhg(newnhe)->nexthop == NULL)
@@ -820,7 +825,7 @@ static bool zebra_nhe_find(struct nhg_hash_entry **nhe, /* return value */
                                           "(R)" : "");
 
                        depends_find_add(&backup_nhe->nhg_depends, nh, afi,
-                                        backup_nhe->type);
+                                        backup_nhe->type, from_dplane);
                }
        }
 
@@ -838,7 +843,8 @@ done:
 static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id,
                           struct nexthop_group *nhg,
                           struct nhg_connected_tree_head *nhg_depends,
-                          vrf_id_t vrf_id, afi_t afi, int type)
+                          vrf_id_t vrf_id, afi_t afi, int type,
+                          bool from_dplane)
 {
        struct nhg_hash_entry lookup = {};
        bool created = false;
@@ -854,7 +860,7 @@ static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id,
        lookup.nhg = *nhg;
 
        lookup.vrf_id = vrf_id;
-       if (lookup.nhg.nexthop->next) {
+       if (nhg_depends || lookup.nhg.nexthop->next) {
                /* Groups can have all vrfs and AF's in them */
                lookup.afi = AFI_UNSPEC;
        } else {
@@ -882,14 +888,16 @@ static bool zebra_nhg_find(struct nhg_hash_entry **nhe, uint32_t id,
                }
        }
 
-       created = zebra_nhe_find(nhe, &lookup, nhg_depends, afi);
+       created = zebra_nhe_find(nhe, &lookup, nhg_depends, afi, from_dplane);
 
        return created;
 }
 
 /* Find/create a single nexthop */
-static struct nhg_hash_entry *
-zebra_nhg_find_nexthop(uint32_t id, struct nexthop *nh, afi_t afi, int type)
+static struct nhg_hash_entry *zebra_nhg_find_nexthop(uint32_t id,
+                                                    struct nexthop *nh,
+                                                    afi_t afi, int type,
+                                                    bool from_dplane)
 {
        struct nhg_hash_entry *nhe = NULL;
        struct nexthop_group nhg = {};
@@ -897,7 +905,7 @@ zebra_nhg_find_nexthop(uint32_t id, struct nexthop *nh, afi_t afi, int type)
 
        nexthop_group_add_sorted(&nhg, nh);
 
-       zebra_nhg_find(&nhe, id, &nhg, NULL, vrf_id, afi, type);
+       zebra_nhg_find(&nhe, id, &nhg, NULL, vrf_id, afi, type, from_dplane);
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
                zlog_debug("%s: nh %pNHv => %p (%u)",
@@ -1151,14 +1159,14 @@ static int nhg_ctx_process_new(struct nhg_ctx *ctx)
                }
 
                if (!zebra_nhg_find(&nhe, id, nhg, &nhg_depends, vrf_id, afi,
-                                   type))
+                                   type, true))
                        depends_decrement_free(&nhg_depends);
 
                /* These got copied over in zebra_nhg_alloc() */
                nexthop_group_delete(&nhg);
        } else
-               nhe = zebra_nhg_find_nexthop(id, nhg_ctx_get_nh(ctx), afi,
-                                            type);
+               nhe = zebra_nhg_find_nexthop(id, nhg_ctx_get_nh(ctx), afi, type,
+                                            true);
 
        if (!nhe) {
                flog_err(
@@ -1325,7 +1333,7 @@ static struct nhg_hash_entry *depends_find_recursive(const struct nexthop *nh,
 
        lookup = nexthop_dup(nh, NULL);
 
-       nhe = zebra_nhg_find_nexthop(0, lookup, afi, type);
+       nhe = zebra_nhg_find_nexthop(0, lookup, afi, type, false);
 
        nexthops_free(lookup);
 
@@ -1333,7 +1341,8 @@ static struct nhg_hash_entry *depends_find_recursive(const struct nexthop *nh,
 }
 
 static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh,
-                                                    afi_t afi, int type)
+                                                    afi_t afi, int type,
+                                                    bool from_dplane)
 {
        struct nhg_hash_entry *nhe;
        struct nexthop lookup = {};
@@ -1343,7 +1352,7 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh,
         */
        nexthop_copy_no_recurse(&lookup, nh, NULL);
 
-       nhe = zebra_nhg_find_nexthop(0, &lookup, afi, type);
+       nhe = zebra_nhg_find_nexthop(0, &lookup, afi, type, from_dplane);
 
        /* The copy may have allocated labels; free them if necessary. */
        nexthop_del_labels(&lookup);
@@ -1356,7 +1365,7 @@ static struct nhg_hash_entry *depends_find_singleton(const struct nexthop *nh,
 }
 
 static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi,
-                                          int type)
+                                          int type, bool from_dplane)
 {
        struct nhg_hash_entry *nhe = NULL;
 
@@ -1369,7 +1378,7 @@ static struct nhg_hash_entry *depends_find(const struct nexthop *nh, afi_t afi,
        if (CHECK_FLAG(nh->flags, NEXTHOP_FLAG_RECURSIVE))
                nhe = depends_find_recursive(nh, afi, type);
        else
-               nhe = depends_find_singleton(nh, afi, type);
+               nhe = depends_find_singleton(nh, afi, type, from_dplane);
 
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL) {
@@ -1402,11 +1411,11 @@ static void depends_add(struct nhg_connected_tree_head *head,
 
 static struct nhg_hash_entry *
 depends_find_add(struct nhg_connected_tree_head *head, struct nexthop *nh,
-                afi_t afi, int type)
+                afi_t afi, int type, bool from_dplane)
 {
        struct nhg_hash_entry *depend = NULL;
 
-       depend = depends_find(nh, afi, type);
+       depend = depends_find(nh, afi, type, from_dplane);
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
                zlog_debug("%s: nh %pNHv => %p",
@@ -1452,7 +1461,7 @@ struct nhg_hash_entry *zebra_nhg_rib_find(uint32_t id,
        assert(nhg->nexthop);
        vrf_id = !vrf_is_backend_netns() ? VRF_DEFAULT : nhg->nexthop->vrf_id;
 
-       zebra_nhg_find(&nhe, id, nhg, NULL, vrf_id, rt_afi, type);
+       zebra_nhg_find(&nhe, id, nhg, NULL, vrf_id, rt_afi, type, false);
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
                zlog_debug("%s: => nhe %p (%u)",
@@ -1476,7 +1485,7 @@ zebra_nhg_rib_find_nhe(struct nhg_hash_entry *rt_nhe, afi_t rt_afi)
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
                zlog_debug("%s: rt_nhe %p (%u)", __func__, rt_nhe, rt_nhe->id);
 
-       zebra_nhe_find(&nhe, rt_nhe, NULL, rt_afi);
+       zebra_nhe_find(&nhe, rt_nhe, NULL, rt_afi, false);
 
        if (IS_ZEBRA_DEBUG_NHG_DETAIL)
                zlog_debug("%s: => nhe %p (%u)",
@@ -1582,6 +1591,7 @@ void zebra_nhg_free(struct nhg_hash_entry *nhe)
 
 void zebra_nhg_hash_free(void *p)
 {
+       zebra_nhg_release_all_deps((struct nhg_hash_entry *)p);
        zebra_nhg_free((struct nhg_hash_entry *)p);
 }
 
@@ -2682,6 +2692,7 @@ void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx)
        case DPLANE_OP_RULE_DELETE:
        case DPLANE_OP_RULE_UPDATE:
        case DPLANE_OP_NEIGH_DISCOVER:
+       case DPLANE_OP_BR_PORT_UPDATE:
        case DPLANE_OP_NONE:
                break;
        }
@@ -2705,6 +2716,30 @@ void zebra_nhg_sweep_table(struct hash *hash)
        hash_iterate(hash, zebra_nhg_sweep_entry, NULL);
 }
 
+static void zebra_nhg_mark_keep_entry(struct hash_bucket *bucket, void *arg)
+{
+       struct nhg_hash_entry *nhe = bucket->data;
+
+       UNSET_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED);
+}
+
+/*
+ * When we are shutting down and we have retain mode enabled
+ * in zebra the process is to mark each vrf that it's
+ * routes should not be deleted.  The problem with that
+ * is that shutdown actually free's up memory which
+ * causes the nexthop group's ref counts to go to zero
+ * we need a way to subtly tell the system to not remove
+ * the nexthop groups from the kernel at the same time.
+ * The easiest just looks like that we should not mark
+ * the nhg's as installed any more and when the ref count
+ * goes to zero we'll attempt to delete and do nothing
+ */
+void zebra_nhg_mark_keep(void)
+{
+       hash_iterate(zrouter.nhgs_id, zebra_nhg_mark_keep_entry, NULL);
+}
+
 /* Global control to disable use of kernel nexthops, if available. We can't
  * force the kernel to support nexthop ids, of course, but we can disable
  * zebra's use of them, for testing e.g. By default, if the kernel supports
@@ -2808,10 +2843,15 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
        if (old) {
                /*
                 * This is a replace, just release NHE from ID for now, The
-                * depends/dependents may still be used in the replacement.
+                * depends/dependents may still be used in the replacement so
+                * we don't touch them other than to remove their refs to their
+                * old parent.
                 */
                replace = true;
                hash_release(zrouter.nhgs_id, old);
+
+               /* Free all the things */
+               zebra_nhg_release_all_deps(old);
        }
 
        new = zebra_nhg_rib_find_nhe(&lookup, afi);
@@ -2848,9 +2888,6 @@ struct nhg_hash_entry *zebra_nhg_proto_add(uint32_t id, int type,
                                zebra_nhg_decrement_ref(rb_node_dep->nhe);
                }
 
-               /* Free all the things */
-               zebra_nhg_release_all_deps(old);
-
                /* Dont call the dec API, we dont want to uninstall the ID */
                old->refcnt = 0;
                zebra_nhg_free(old);
index 052fa65d064014ffb1a3d32a230ae9d5ccb44cea..b2ef88bb61a0d4006adcbd96db26685d2fef720d 100644 (file)
@@ -324,9 +324,16 @@ struct zebra_dplane_ctx;
 extern void zebra_nhg_dplane_result(struct zebra_dplane_ctx *ctx);
 
 
-/* Sweet the nhg hash tables for old entries on restart */
+/* Sweep the nhg hash tables for old entries on restart */
 extern void zebra_nhg_sweep_table(struct hash *hash);
 
+/*
+ * We are shutting down but the nexthops should be kept
+ * as that -r has been specified and we don't want to delete
+ * the routes unintentionally
+ */
+extern void zebra_nhg_mark_keep(void);
+
 /* Nexthop resolution processing */
 struct route_entry; /* Forward ref to avoid circular includes */
 extern int nexthop_active_update(struct route_node *rn, struct route_entry *re);
index 41e278f71b660c3e9a2ba8ba0b0e89e8149e9ba3..1d59e0ab3486b4ff6c5e7e26e91db8fee4d4a75d 100644 (file)
@@ -258,7 +258,7 @@ uint32_t zebra_opaque_enqueue_batch(struct stream_fifo *batch)
 
        /* Schedule module pthread to process the batch */
        if (counter > 0) {
-               if (IS_ZEBRA_DEBUG_RECV)
+               if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL)
                        zlog_debug("%s: received %u messages",
                                   __func__, counter);
                thread_add_event(zo_info.master, process_messages, NULL, 0,
@@ -315,7 +315,7 @@ static int process_messages(struct thread *event)
                goto done;
        }
 
-       if (IS_ZEBRA_DEBUG_RECV)
+       if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL)
                zlog_debug("%s: processing %u messages", __func__, i);
 
        /*
@@ -381,7 +381,7 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
                /* Look up registered ZAPI client(s) */
                reg = opq_reg_lookup(info.type);
                if (reg == NULL) {
-                       if (IS_ZEBRA_DEBUG_RECV)
+                       if (IS_ZEBRA_DEBUG_RECV && IS_ZEBRA_DEBUG_DETAIL)
                                zlog_debug("%s: no registrations for opaque type %u, flags %#x",
                                           __func__, info.type, info.flags);
                        goto drop_it;
@@ -401,7 +401,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
                                    client->session_id != info.session_id)
                                        continue;
 
-                               if (IS_ZEBRA_DEBUG_RECV)
+                               if (IS_ZEBRA_DEBUG_RECV &&
+                                   IS_ZEBRA_DEBUG_DETAIL)
                                        zlog_debug("%s: found matching unicast client %s",
                                                   __func__,
                                                   opq_client2str(buf,
@@ -423,7 +424,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
                                                       client->instance,
                                                       client->session_id);
                        if (zclient) {
-                               if (IS_ZEBRA_DEBUG_RECV)
+                               if (IS_ZEBRA_DEBUG_SEND &&
+                                   IS_ZEBRA_DEBUG_DETAIL)
                                        zlog_debug("%s: sending %s to client %s",
                                                   __func__,
                                                   (dup ? "dup" : "msg"),
@@ -444,7 +446,8 @@ static int dispatch_opq_messages(struct stream_fifo *msg_fifo)
 
                                zserv_release_client(zclient);
                        } else {
-                               if (IS_ZEBRA_DEBUG_RECV)
+                               if (IS_ZEBRA_DEBUG_RECV &&
+                                   IS_ZEBRA_DEBUG_DETAIL)
                                        zlog_debug("%s: type %u: no zclient for %s",
                                                   __func__, info.type,
                                                   opq_client2str(buf,
@@ -615,10 +618,6 @@ static int handle_opq_unregistration(const struct zmsghdr *hdr,
 
        /* Is registration empty now? */
        if (reg->clients == NULL) {
-               if (IS_ZEBRA_DEBUG_RECV)
-                       zlog_debug("%s: free empty reg %u", __func__,
-                                  reg->type);
-
                opq_regh_del(&opq_reg_hash, reg);
                opq_reg_free(&reg);
        }
index 9a3b567b5aa2b3e80495579d39d25125358e982b..1e7b38086b1d03032cb53fe2ebd6c3e9efefd4d9 100644 (file)
@@ -156,13 +156,10 @@ void zebra_ptm_finish(void)
        if (ptm_cb.in_data)
                free(ptm_cb.in_data);
 
-       /* Release threads. */
-       if (ptm_cb.t_read)
-               thread_cancel(ptm_cb.t_read);
-       if (ptm_cb.t_write)
-               thread_cancel(ptm_cb.t_write);
-       if (ptm_cb.t_timer)
-               thread_cancel(ptm_cb.t_timer);
+       /* Cancel events. */
+       thread_cancel(&ptm_cb.t_read);
+       thread_cancel(&ptm_cb.t_write);
+       thread_cancel(&ptm_cb.t_timer);
 
        if (ptm_cb.wb)
                buffer_free(ptm_cb.wb);
@@ -218,7 +215,7 @@ static int zebra_ptm_send_message(char *data, int size)
                                 ptm_cb.reconnect_time, &ptm_cb.t_timer);
                return -1;
        case BUFFER_EMPTY:
-               THREAD_OFF(ptm_cb.t_write);
+               thread_cancel(&ptm_cb.t_write);
                break;
        case BUFFER_PENDING:
                thread_add_write(zrouter.master, zebra_ptm_flush_messages, NULL,
index cdcca1e930dd517e28ccf47b8bb87fded34a58b4..ecae021dba1e38909c72ed0e298ddff486c48141 100644 (file)
@@ -102,7 +102,7 @@ void zebra_pw_del(struct zebra_vrf *zvrf, struct zebra_pw *pw)
                hook_call(pw_uninstall, pw);
                dplane_pw_uninstall(pw);
        } else if (pw->install_retry_timer)
-               THREAD_TIMER_OFF(pw->install_retry_timer);
+               thread_cancel(&pw->install_retry_timer);
 
        /* unlink and release memory */
        RB_REMOVE(zebra_pw_head, &zvrf->pseudowires, pw);
@@ -219,7 +219,7 @@ void zebra_pw_install_failure(struct zebra_pw *pw, int pwstatus)
                        pw->vrf_id, pw->ifname, PW_INSTALL_RETRY_INTERVAL);
 
        /* schedule to retry later */
-       THREAD_TIMER_OFF(pw->install_retry_timer);
+       thread_cancel(&pw->install_retry_timer);
        thread_add_timer(zrouter.master, zebra_pw_install_retry, pw,
                         PW_INSTALL_RETRY_INTERVAL, &pw->install_retry_timer);
 
index aac0e628fe12fe62b65ce7cdd0962f0ff2d413ff..e76ecc85a60cab1c688eed40a22b702146010594 100644 (file)
@@ -79,35 +79,35 @@ static const struct {
        uint8_t meta_q_map;
 } route_info[ZEBRA_ROUTE_MAX] = {
        [ZEBRA_ROUTE_NHG] = {ZEBRA_ROUTE_NHG, 255 /* Uneeded for nhg's */, 0},
-       [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 5},
-       [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 1},
+       [ZEBRA_ROUTE_SYSTEM] = {ZEBRA_ROUTE_SYSTEM, 0, 6},
+       [ZEBRA_ROUTE_KERNEL] = {ZEBRA_ROUTE_KERNEL, 0, 2},
        [ZEBRA_ROUTE_CONNECT] = {ZEBRA_ROUTE_CONNECT, 0, 1},
-       [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 2},
-       [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 3},
-       [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 3},
-       [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 3},
-       [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 3},
-       [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 3},
-       [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 4},
-       [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 5},
-       [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 3},
-       [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 3},
-       [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 5},
-       [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 5},
-       [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 2},
-       [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 5},
-       [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 4},
-       [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 4},
-       [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 4},
-       [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 4},
-       [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 4},
-       [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 3},
-       [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 5},
-       [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 5},
-       [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 5},
-       [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 3},
-       [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 5},
-       [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 5},
+       [ZEBRA_ROUTE_STATIC] = {ZEBRA_ROUTE_STATIC, 1, 3},
+       [ZEBRA_ROUTE_RIP] = {ZEBRA_ROUTE_RIP, 120, 4},
+       [ZEBRA_ROUTE_RIPNG] = {ZEBRA_ROUTE_RIPNG, 120, 4},
+       [ZEBRA_ROUTE_OSPF] = {ZEBRA_ROUTE_OSPF, 110, 4},
+       [ZEBRA_ROUTE_OSPF6] = {ZEBRA_ROUTE_OSPF6, 110, 4},
+       [ZEBRA_ROUTE_ISIS] = {ZEBRA_ROUTE_ISIS, 115, 4},
+       [ZEBRA_ROUTE_BGP] = {ZEBRA_ROUTE_BGP, 20 /* IBGP is 200. */, 5},
+       [ZEBRA_ROUTE_PIM] = {ZEBRA_ROUTE_PIM, 255, 6},
+       [ZEBRA_ROUTE_EIGRP] = {ZEBRA_ROUTE_EIGRP, 90, 4},
+       [ZEBRA_ROUTE_NHRP] = {ZEBRA_ROUTE_NHRP, 10, 4},
+       [ZEBRA_ROUTE_HSLS] = {ZEBRA_ROUTE_HSLS, 255, 6},
+       [ZEBRA_ROUTE_OLSR] = {ZEBRA_ROUTE_OLSR, 255, 6},
+       [ZEBRA_ROUTE_TABLE] = {ZEBRA_ROUTE_TABLE, 150, 3},
+       [ZEBRA_ROUTE_LDP] = {ZEBRA_ROUTE_LDP, 150, 6},
+       [ZEBRA_ROUTE_VNC] = {ZEBRA_ROUTE_VNC, 20, 5},
+       [ZEBRA_ROUTE_VNC_DIRECT] = {ZEBRA_ROUTE_VNC_DIRECT, 20, 5},
+       [ZEBRA_ROUTE_VNC_DIRECT_RH] = {ZEBRA_ROUTE_VNC_DIRECT_RH, 20, 5},
+       [ZEBRA_ROUTE_BGP_DIRECT] = {ZEBRA_ROUTE_BGP_DIRECT, 20, 5},
+       [ZEBRA_ROUTE_BGP_DIRECT_EXT] = {ZEBRA_ROUTE_BGP_DIRECT_EXT, 20, 5},
+       [ZEBRA_ROUTE_BABEL] = {ZEBRA_ROUTE_BABEL, 100, 4},
+       [ZEBRA_ROUTE_SHARP] = {ZEBRA_ROUTE_SHARP, 150, 6},
+       [ZEBRA_ROUTE_PBR] = {ZEBRA_ROUTE_PBR, 200, 6},
+       [ZEBRA_ROUTE_BFD] = {ZEBRA_ROUTE_BFD, 255, 6},
+       [ZEBRA_ROUTE_OPENFABRIC] = {ZEBRA_ROUTE_OPENFABRIC, 115, 4},
+       [ZEBRA_ROUTE_VRRP] = {ZEBRA_ROUTE_VRRP, 255, 6},
+       [ZEBRA_ROUTE_SRTE] = {ZEBRA_ROUTE_SRTE, 255, 6},
        /* Any new route type added to zebra, should be mirrored here */
 
        /* no entry/default: 150 */
@@ -694,15 +694,13 @@ void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq)
 
                        if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
                                char buf1[PREFIX_STRLEN];
-                               char buf2[PREFIX_STRLEN];
 
                                zlog_debug(
-                                       "%s(%u):%s has Nexthop(%s) Type: %s depending on it, evaluating %u:%u",
+                                       "%s(%u):%s has Nexthop(%pFX) Type: %s depending on it, evaluating %u:%u",
                                        zvrf_name(zvrf), zvrf_id(zvrf),
                                        srcdest_rnode2str(rn, buf1,
                                                          sizeof(buf1)),
-                                       prefix2str(p, buf2, sizeof(buf2)),
-                                       rnh_type2str(rnh->type), seq,
+                                       p, rnh_type2str(rnh->type), seq,
                                        rnh->seqno);
                        }
 
@@ -921,11 +919,22 @@ static void rib_process_update_fib(struct zebra_vrf *zvrf,
                                                zebra_route_string(new->type));
                        }
 
-                       /* If labeled-unicast route, uninstall transit LSP. */
-                       if (zebra_rib_labeled_unicast(old))
-                               zebra_mpls_lsp_uninstall(zvrf, rn, old);
+                       /*
+                        * When we have gotten to this point
+                        * the new route entry has no nexthops
+                        * that are usable and as such we need
+                        * to remove the old route, but only
+                        * if we were the one who installed
+                        * the old route
+                        */
+                       if (!RIB_SYSTEM_ROUTE(old)) {
+                               /* If labeled-unicast route, uninstall transit
+                                * LSP. */
+                               if (zebra_rib_labeled_unicast(old))
+                                       zebra_mpls_lsp_uninstall(zvrf, rn, old);
 
-                       rib_uninstall_kernel(rn, old);
+                               rib_uninstall_kernel(rn, old);
+                       }
                }
        } else {
                /*
@@ -1087,46 +1096,56 @@ static void rib_process(struct route_node *rn)
                if (CHECK_FLAG(re->status, ROUTE_ENTRY_REMOVED))
                        continue;
 
-               /* Skip unreachable nexthop. */
-               /* This first call to nexthop_active_update is merely to
-                * determine if there's any change to nexthops associated
-                * with this RIB entry. Now, rib_process() can be invoked due
-                * to an external event such as link down or due to
-                * next-hop-tracking evaluation. In the latter case,
-                * a decision has already been made that the NHs have changed.
-                * So, no need to invoke a potentially expensive call again.
-                * Further, since the change might be in a recursive NH which
-                * is not caught in the nexthop_active_update() code. Thus, we
-                * might miss changes to recursive NHs.
+               /*
+                * If the route entry has changed, verify/resolve
+                * the nexthops associated with the entry.
+                *
+                * In any event if we have nexthops that are not active
+                * then we cannot use this particular route entry so
+                * skip it.
                 */
-               if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)
-                   && !nexthop_active_update(rn, re)) {
-                       if (re->type == ZEBRA_ROUTE_TABLE) {
-                               /* XXX: HERE BE DRAGONS!!!!!
-                                * In all honesty, I have not yet figured out
-                                * what this part does or why the
-                                * ROUTE_ENTRY_CHANGED test above is correct
-                                * or why we need to delete a route here, and
-                                * also not whether this concerns both selected
-                                * and fib route, or only selected
-                                * or only fib
-                                *
-                                * This entry was denied by the 'ip protocol
-                                * table' route-map, we need to delete it */
-                               if (re != old_selected) {
-                                       if (IS_ZEBRA_DEBUG_RIB)
-                                               zlog_debug(
-                                                       "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map",
-                                                       __func__,
-                                                       VRF_LOGNAME(vrf),
-                                                       vrf_id, buf);
-                                       rib_unlink(rn, re);
-                               } else
-                                       SET_FLAG(re->status,
-                                                ROUTE_ENTRY_REMOVED);
-                       }
+               if (CHECK_FLAG(re->status, ROUTE_ENTRY_CHANGED)) {
+                       if (!nexthop_active_update(rn, re)) {
+                               if (re->type == ZEBRA_ROUTE_TABLE) {
+                                       /* XXX: HERE BE DRAGONS!!!!!
+                                        * In all honesty, I have not yet
+                                        * figured out what this part does or
+                                        * why the ROUTE_ENTRY_CHANGED test
+                                        * above is correct or why we need to
+                                        * delete a route here, and also not
+                                        * whether this concerns both selected
+                                        * and fib route, or only selected
+                                        * or only fib
+                                        *
+                                        * This entry was denied by the 'ip
+                                        * protocol
+                                        * table' route-map, we need to delete
+                                        * it */
+                                       if (re != old_selected) {
+                                               if (IS_ZEBRA_DEBUG_RIB)
+                                                       zlog_debug(
+                                                               "%s: %s(%u):%s: imported via import-table but denied by the ip protocol table route-map",
+                                                               __func__,
+                                                               VRF_LOGNAME(
+                                                                       vrf),
+                                                               vrf_id, buf);
+                                               rib_unlink(rn, re);
+                                       } else
+                                               SET_FLAG(re->status,
+                                                        ROUTE_ENTRY_REMOVED);
+                               }
 
-                       continue;
+                               continue;
+                       }
+               } else {
+                       /*
+                        * If the re has not changed and the nhg we have is
+                        * not usable, then we cannot use this route entry
+                        * for consideration, as that the route will just
+                        * not install if it is selected.
+                        */
+                       if (!nexthop_group_active_nexthop_num(&re->nhe->nhg))
+                               continue;
                }
 
                /* Infinite distance. */
@@ -1357,8 +1376,6 @@ static void zebra_rib_fixup_system(struct route_node *rn)
 static bool rib_compare_routes(const struct route_entry *re1,
                               const struct route_entry *re2)
 {
-       bool result = false;
-
        if (re1->type != re2->type)
                return false;
 
@@ -1372,17 +1389,14 @@ static bool rib_compare_routes(const struct route_entry *re1,
            re1->distance != re2->distance)
                return false;
 
-       /* Only connected routes need more checking, nexthop-by-nexthop */
+       /* We support multiple connected routes: this supports multiple
+        * v6 link-locals, and we also support multiple addresses in the same
+        * subnet on a single interface.
+        */
        if (re1->type != ZEBRA_ROUTE_CONNECT)
                return true;
 
-       /* Quick check if shared nhe */
-       if (re1->nhe == re2->nhe)
-               return true;
-
-       result = nexthop_group_equal_no_recurse(&re1->nhe->nhg, &re2->nhe->nhg);
-
-       return result;
+       return false;
 }
 
 /*
@@ -1481,7 +1495,6 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
                                   struct route_node *rn,
                                   struct zebra_dplane_ctx *ctx)
 {
-       char dest_str[PREFIX_STRLEN] = "";
        struct nexthop *nexthop;
        bool matched;
        const struct nexthop_group *ctxnhg;
@@ -1493,19 +1506,13 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
 
        vrf = vrf_lookup_by_id(re->vrf_id);
 
-       /* Note well: only capturing the prefix string if debug is enabled here;
-        * unconditional log messages will have to generate the string.
-        */
-       if (IS_ZEBRA_DEBUG_RIB)
-               prefix2str(&(rn->p), dest_str, sizeof(dest_str));
-
        dest = rib_dest_from_rnode(rn);
        if (dest)
                is_selected = (re == dest->selected_fib);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED)
-               zlog_debug("update_from_ctx: %s(%u:%u):%s: %sSELECTED, re %p",
-                          VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str,
+               zlog_debug("update_from_ctx: %s(%u:%u):%pRN: %sSELECTED, re %p",
+                          VRF_LOGNAME(vrf), re->vrf_id, re->table, rn,
                           (is_selected ? "" : "NOT "), re);
 
        /* Update zebra's nexthop FIB flag for each nexthop that was installed.
@@ -1531,9 +1538,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
        if (matched) {
                if (IS_ZEBRA_DEBUG_RIB)
                        zlog_debug(
-                               "%s(%u:%u):%s update_from_ctx(): existing fib nhg, no change",
-                               VRF_LOGNAME(vrf), re->vrf_id, re->table,
-                               dest_str);
+                               "%s(%u:%u):%pRN update_from_ctx(): existing fib nhg, no change",
+                               VRF_LOGNAME(vrf), re->vrf_id, re->table, rn);
                goto check_backups;
 
        } else if (CHECK_FLAG(re->status, ROUTE_ENTRY_USE_FIB_NHG)) {
@@ -1542,9 +1548,8 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
                 */
                if (IS_ZEBRA_DEBUG_RIB)
                        zlog_debug(
-                               "%s(%u:%u):%s update_from_ctx(): replacing fib nhg",
-                               VRF_LOGNAME(vrf), re->vrf_id, re->table,
-                               dest_str);
+                               "%s(%u:%u):%pRN update_from_ctx(): replacing fib nhg",
+                               VRF_LOGNAME(vrf), re->vrf_id, re->table, rn);
                nexthops_free(re->fib_ng.nexthop);
                re->fib_ng.nexthop = NULL;
 
@@ -1554,9 +1559,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
                changed_p = true;
        } else {
                if (IS_ZEBRA_DEBUG_RIB)
-                       zlog_debug("%s(%u:%u):%s update_from_ctx(): no fib nhg",
-                                  VRF_LOGNAME(vrf), re->vrf_id, re->table,
-                                  dest_str);
+                       zlog_debug(
+                               "%s(%u:%u):%pRN update_from_ctx(): no fib nhg",
+                               VRF_LOGNAME(vrf), re->vrf_id, re->table, rn);
        }
 
        /*
@@ -1583,9 +1588,9 @@ static bool rib_update_re_from_ctx(struct route_entry *re,
        if (matched) {
                if (IS_ZEBRA_DEBUG_RIB)
                        zlog_debug(
-                               "%s(%u:%u):%s update_from_ctx(): rib nhg matched, changed '%s'",
-                               VRF_LOGNAME(vrf), re->vrf_id, re->table,
-                               dest_str, (changed_p ? "true" : "false"));
+                               "%s(%u:%u):%pRN update_from_ctx(): rib nhg matched, changed '%s'",
+                               VRF_LOGNAME(vrf), re->vrf_id, re->table, rn,
+                               (changed_p ? "true" : "false"));
                goto check_backups;
        }
 
@@ -1596,8 +1601,8 @@ no_nexthops:
         */
        if (IS_ZEBRA_DEBUG_RIB)
                zlog_debug(
-                       "%s(%u:%u):%s update_from_ctx(): changed %s, adding new fib nhg%s",
-                       VRF_LOGNAME(vrf), re->vrf_id, re->table, dest_str,
+                       "%s(%u:%u):%pRN update_from_ctx(): changed %s, adding new fib nhg%s",
+                       VRF_LOGNAME(vrf), re->vrf_id, re->table, rn,
                        (changed_p ? "true" : "false"),
                        ctxnhg->nexthop != NULL ? "" : " (empty)");
 
@@ -1631,8 +1636,8 @@ check_backups:
        if (matched) {
                if (IS_ZEBRA_DEBUG_RIB)
                        zlog_debug(
-                               "%s(%u):%s update_from_ctx(): existing fib backup nhg, no change",
-                               VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+                               "%s(%u):%pRN update_from_ctx(): existing fib backup nhg, no change",
+                               VRF_LOGNAME(vrf), re->vrf_id, rn);
                goto done;
 
        } else if (re->fib_backup_ng.nexthop) {
@@ -1642,8 +1647,8 @@ check_backups:
                 */
                if (IS_ZEBRA_DEBUG_RIB)
                        zlog_debug(
-                               "%s(%u):%s update_from_ctx(): replacing fib backup nhg",
-                               VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+                               "%s(%u):%pRN update_from_ctx(): replacing fib backup nhg",
+                               VRF_LOGNAME(vrf), re->vrf_id, rn);
                nexthops_free(re->fib_backup_ng.nexthop);
                re->fib_backup_ng.nexthop = NULL;
 
@@ -1651,8 +1656,9 @@ check_backups:
                changed_p = true;
        } else {
                if (IS_ZEBRA_DEBUG_RIB)
-                       zlog_debug("%s(%u):%s update_from_ctx(): no fib backup nhg",
-                                  VRF_LOGNAME(vrf), re->vrf_id, dest_str);
+                       zlog_debug(
+                               "%s(%u):%pRN update_from_ctx(): no fib backup nhg",
+                               VRF_LOGNAME(vrf), re->vrf_id, rn);
        }
 
        /*
@@ -1671,9 +1677,10 @@ check_backups:
                        goto done;
 
                if (IS_ZEBRA_DEBUG_RIB)
-                       zlog_debug("%s(%u):%s update_from_ctx(): changed %s, adding new backup fib nhg",
-                                  VRF_LOGNAME(vrf), re->vrf_id, dest_str,
-                                  (changed_p ? "true" : "false"));
+                       zlog_debug(
+                               "%s(%u):%pRN update_from_ctx(): changed %s, adding new backup fib nhg",
+                               VRF_LOGNAME(vrf), re->vrf_id, rn,
+                               (changed_p ? "true" : "false"));
 
                copy_nexthops(&(re->fib_backup_ng.nexthop), ctxnhg->nexthop,
                              NULL);
@@ -1735,7 +1742,6 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
        struct route_node *rn = NULL;
        struct route_entry *re = NULL, *old_re = NULL, *rib;
        bool is_update = false;
-       char dest_str[PREFIX_STRLEN] = "";
        enum dplane_op_e op;
        enum zebra_dplane_result status;
        const struct prefix *dest_pfx, *src_pfx;
@@ -1747,20 +1753,14 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
        vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
        dest_pfx = dplane_ctx_get_dest(ctx);
 
-       /* Note well: only capturing the prefix string if debug is enabled here;
-        * unconditional log messages will have to generate the string.
-        */
-       if (IS_ZEBRA_DEBUG_DPLANE)
-               prefix2str(dest_pfx, dest_str, sizeof(dest_str));
-
        /* Locate rn and re(s) from ctx */
        rn = rib_find_rn_from_ctx(ctx);
        if (rn == NULL) {
                if (IS_ZEBRA_DEBUG_DPLANE) {
                        zlog_debug(
-                               "Failed to process dplane results: no route for %s(%u):%s",
+                               "Failed to process dplane results: no route for %s(%u):%pFX",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dest_str);
+                               dest_pfx);
                }
                goto done;
        }
@@ -1773,9 +1773,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
 
        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                zlog_debug(
-                       "%s(%u:%u):%s Processing dplane result ctx %p, op %s result %s",
+                       "%s(%u:%u):%pFX Processing dplane result ctx %p, op %s result %s",
                        VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                       dplane_ctx_get_table(ctx), dest_str, ctx,
+                       dplane_ctx_get_table(ctx), dest_pfx, ctx,
                        dplane_op2str(op), dplane_res2str(status));
 
        /*
@@ -1815,9 +1815,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                if (re->dplane_sequence != seq) {
                        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                                zlog_debug(
-                                       "%s(%u):%s Stale dplane result for re %p",
+                                       "%s(%u):%pFX Stale dplane result for re %p",
                                        VRF_LOGNAME(vrf),
-                                       dplane_ctx_get_vrf(ctx), dest_str, re);
+                                       dplane_ctx_get_vrf(ctx), dest_pfx, re);
                } else
                        UNSET_FLAG(re->status, ROUTE_ENTRY_QUEUED);
        }
@@ -1826,10 +1826,10 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                if (old_re->dplane_sequence != dplane_ctx_get_old_seq(ctx)) {
                        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                                zlog_debug(
-                                       "%s(%u:%u):%s Stale dplane result for old_re %p",
+                                       "%s(%u:%u):%pFX Stale dplane result for old_re %p",
                                        VRF_LOGNAME(vrf),
                                        dplane_ctx_get_vrf(ctx), old_re->table,
-                                       dest_str, old_re);
+                                       dest_pfx, old_re);
                } else
                        UNSET_FLAG(old_re->status, ROUTE_ENTRY_QUEUED);
        }
@@ -1867,12 +1867,12 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                                if (!fib_changed) {
                                        if (IS_ZEBRA_DEBUG_DPLANE_DETAIL)
                                                zlog_debug(
-                                                       "%s(%u:%u):%s no fib change for re",
+                                                       "%s(%u:%u):%pFX no fib change for re",
                                                        VRF_LOGNAME(vrf),
                                                        dplane_ctx_get_vrf(ctx),
                                                        dplane_ctx_get_table(
                                                                ctx),
-                                                       dest_str);
+                                                       dest_pfx);
                                }
 
                                /* Redistribute if this is the selected re */
@@ -1908,11 +1908,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                                zsend_route_notify_owner(re, dest_pfx,
                                                         ZAPI_ROUTE_FAIL_INSTALL);
 
-                       zlog_warn("%s(%u:%u):%s: Route install failed",
+                       zlog_warn("%s(%u:%u):%pFX: Route install failed",
                                  VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                                 dplane_ctx_get_table(ctx),
-                                 prefix2str(dest_pfx, dest_str,
-                                            sizeof(dest_str)));
+                                 dplane_ctx_get_table(ctx), dest_pfx);
                }
                break;
        case DPLANE_OP_ROUTE_DELETE:
@@ -1938,11 +1936,9 @@ static void rib_process_result(struct zebra_dplane_ctx *ctx)
                        zsend_route_notify_owner_ctx(ctx,
                                                     ZAPI_ROUTE_REMOVE_FAIL);
 
-                       zlog_warn("%s(%u:%u):%s: Route Deletion failure",
+                       zlog_warn("%s(%u:%u):%pFX: Route Deletion failure",
                                  VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                                 dplane_ctx_get_table(ctx),
-                                 prefix2str(dest_pfx, dest_str,
-                                            sizeof(dest_str)));
+                                 dplane_ctx_get_table(ctx), dest_pfx);
                }
 
                /*
@@ -2017,7 +2013,6 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        struct route_entry *re = NULL;
        struct vrf *vrf;
        struct nexthop *nexthop;
-       char dest_str[PREFIX_STRLEN] = "";
        const struct prefix *dest_pfx, *src_pfx;
        rib_dest_t *dest;
        bool fib_changed = false;
@@ -2026,20 +2021,14 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        dest_pfx = dplane_ctx_get_dest(ctx);
        vrf = vrf_lookup_by_id(dplane_ctx_get_vrf(ctx));
 
-       /* Note well: only capturing the prefix string if debug is enabled here;
-        * unconditional log messages will have to generate the string.
-        */
-       if (debug_p)
-               prefix2str(dest_pfx, dest_str, sizeof(dest_str));
-
        /* Locate rn and re(s) from ctx */
        rn = rib_find_rn_from_ctx(ctx);
        if (rn == NULL) {
                if (debug_p) {
                        zlog_debug(
-                               "Failed to process dplane notification: no routes for %s(%u:%u):%s",
+                               "Failed to process dplane notification: no routes for %s(%u:%u):%pFX",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dplane_ctx_get_table(ctx), dest_str);
+                               dplane_ctx_get_table(ctx), dest_pfx);
                }
                goto done;
        }
@@ -2048,9 +2037,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        srcdest_rnode_prefixes(rn, &dest_pfx, &src_pfx);
 
        if (debug_p)
-               zlog_debug("%s(%u:%u):%s Processing dplane notif ctx %p",
+               zlog_debug("%s(%u:%u):%pFX Processing dplane notif ctx %p",
                           VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                          dplane_ctx_get_table(ctx), dest_str, ctx);
+                          dplane_ctx_get_table(ctx), dest_pfx, ctx);
 
        /*
         * Take a pass through the routes, look for matches with the context
@@ -2065,9 +2054,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        if (re == NULL) {
                if (debug_p)
                        zlog_debug(
-                               "%s(%u:%u):%s Unable to process dplane notification: no entry for type %s",
+                               "%s(%u:%u):%pFX Unable to process dplane notification: no entry for type %s",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dplane_ctx_get_table(ctx), dest_str,
+                               dplane_ctx_get_table(ctx), dest_pfx,
                                zebra_route_string(dplane_ctx_get_type(ctx)));
 
                goto done;
@@ -2099,20 +2088,20 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
                                UNSET_FLAG(re->status, ROUTE_ENTRY_INSTALLED);
                        if (debug_p)
                                zlog_debug(
-                                       "%s(%u:%u):%s dplane notif, uninstalled type %s route",
+                                       "%s(%u:%u):%pFX dplane notif, uninstalled type %s route",
                                        VRF_LOGNAME(vrf),
                                        dplane_ctx_get_vrf(ctx),
-                                       dplane_ctx_get_table(ctx), dest_str,
+                                       dplane_ctx_get_table(ctx), dest_pfx,
                                        zebra_route_string(
                                                dplane_ctx_get_type(ctx)));
                } else {
                        /* At least report on the event. */
                        if (debug_p)
                                zlog_debug(
-                                       "%s(%u:%u):%s dplane notif, but type %s not selected_fib",
+                                       "%s(%u:%u):%pFX dplane notif, but type %s not selected_fib",
                                        VRF_LOGNAME(vrf),
                                        dplane_ctx_get_vrf(ctx),
-                                       dplane_ctx_get_table(ctx), dest_str,
+                                       dplane_ctx_get_table(ctx), dest_pfx,
                                        zebra_route_string(
                                                dplane_ctx_get_type(ctx)));
                }
@@ -2136,9 +2125,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        if (!fib_changed) {
                if (debug_p)
                        zlog_debug(
-                               "%s(%u:%u):%s dplane notification: rib_update returns FALSE",
+                               "%s(%u:%u):%pFX dplane notification: rib_update returns FALSE",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dplane_ctx_get_table(ctx), dest_str);
+                               dplane_ctx_get_table(ctx), dest_pfx);
        }
 
        /*
@@ -2153,9 +2142,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        if (start_count > 0 && end_count > 0) {
                if (debug_p)
                        zlog_debug(
-                               "%s(%u:%u):%s applied nexthop changes from dplane notification",
+                               "%s(%u:%u):%pFX applied nexthop changes from dplane notification",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dplane_ctx_get_table(ctx), dest_str);
+                               dplane_ctx_get_table(ctx), dest_pfx);
 
                /* Changed nexthops - update kernel/others */
                dplane_route_notif_update(rn, re,
@@ -2164,9 +2153,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        } else if (start_count == 0 && end_count > 0) {
                if (debug_p)
                        zlog_debug(
-                               "%s(%u:%u):%s installed transition from dplane notification",
+                               "%s(%u:%u):%pFX installed transition from dplane notification",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dplane_ctx_get_table(ctx), dest_str);
+                               dplane_ctx_get_table(ctx), dest_pfx);
 
                /* We expect this to be the selected route, so we want
                 * to tell others about this transition.
@@ -2182,9 +2171,9 @@ static void rib_process_dplane_notify(struct zebra_dplane_ctx *ctx)
        } else if (start_count > 0 && end_count == 0) {
                if (debug_p)
                        zlog_debug(
-                               "%s(%u:%u):%s un-installed transition from dplane notification",
+                               "%s(%u:%u):%pFX un-installed transition from dplane notification",
                                VRF_LOGNAME(vrf), dplane_ctx_get_vrf(ctx),
-                               dplane_ctx_get_table(ctx), dest_str);
+                               dplane_ctx_get_table(ctx), dest_pfx);
 
                /* Transition from _something_ installed to _nothing_
                 * installed.
@@ -2247,9 +2236,18 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
        rib_process(rnode);
 
        if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
-               struct route_entry *re = re_list_first(&dest->routes);
+               struct route_entry *re = NULL;
                char buf[SRCDEST2STR_BUFFER];
 
+               /*
+                * rib_process may have freed the dest
+                * as part of the garbage collection.  Let's
+                * prevent stupidity from happening.
+                */
+               dest = rib_dest_from_rnode(rnode);
+               if (dest)
+                       re = re_list_first(&dest->routes);
+
                srcdest_rnode2str(rnode, buf, sizeof(buf));
                zlog_debug("%s(%u:%u):%s: rn %p dequeued from sub-queue %u",
                           zvrf_name(zvrf), zvrf_id(zvrf), re ? re->table : 0, buf,
@@ -2264,7 +2262,7 @@ static void process_subq_route(struct listnode *lnode, uint8_t qindex)
   else
     {
       zlog_debug ("%s: called for route_node (%p, %d) with no ribs",
-                  __func__, rnode, rnode->lock);
+                  __func__, rnode, route_node_get_lock_count(rnode));
       zlog_backtrace(LOG_DEBUG);
     }
 #endif
@@ -2439,8 +2437,8 @@ int rib_queue_add(struct route_node *rn)
        /* Pointless to queue a route_node with no RIB entries to add or remove
         */
        if (!rnode_to_ribs(rn)) {
-               zlog_debug("%s: called for route_node (%p, %d) with no ribs",
-                          __func__, (void *)rn, rn->lock);
+               zlog_debug("%s: called for route_node (%p, %u) with no ribs",
+                          __func__, (void *)rn, route_node_get_lock_count(rn));
                zlog_backtrace(LOG_DEBUG);
                return -1;
        }
@@ -2806,7 +2804,6 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id)
        struct route_node *rn;
        struct route_entry *re;
        struct vrf *vrf;
-       char prefix_buf[INET_ADDRSTRLEN];
 
        vrf = vrf_lookup_by_id(vrf_id);
 
@@ -2824,10 +2821,8 @@ void rib_lookup_and_dump(struct prefix_ipv4 *p, vrf_id_t vrf_id)
 
        /* No route for this prefix. */
        if (!rn) {
-               zlog_debug("%s:%s(%u) lookup failed for %s", __func__,
-                          VRF_LOGNAME(vrf), vrf_id,
-                          prefix2str((struct prefix *)p, prefix_buf,
-                                     sizeof(prefix_buf)));
+               zlog_debug("%s:%s(%u) lookup failed for %pFX", __func__,
+                          VRF_LOGNAME(vrf), vrf_id, (struct prefix *)p);
                return;
        }
 
@@ -2886,14 +2881,13 @@ void rib_lookup_and_pushup(struct prefix_ipv4 *p, vrf_id_t vrf_id)
         */
        if (dest->selected_fib) {
                if (IS_ZEBRA_DEBUG_RIB) {
-                       char buf[PREFIX_STRLEN];
                        struct vrf *vrf =
                                vrf_lookup_by_id(dest->selected_fib->vrf_id);
 
                        zlog_debug(
-                               "%s(%u):%s: freeing way for connected prefix",
+                               "%s(%u):%pFX: freeing way for connected prefix",
                                VRF_LOGNAME(vrf), dest->selected_fib->vrf_id,
-                               prefix2str(&rn->p, buf, sizeof(buf)));
+                               &rn->p);
                        route_entry_dump(&rn->p, NULL, dest->selected_fib);
                }
                rib_uninstall(rn, dest->selected_fib);
@@ -2944,14 +2938,12 @@ int rib_add_multipath_nhe(afi_t afi, safi_t safi, struct prefix *p,
                /* Lookup nhe from route information */
                nhe = zebra_nhg_rib_find_nhe(re_nhe, afi);
                if (!nhe) {
-                       char buf[PREFIX_STRLEN] = "";
                        char buf2[PREFIX_STRLEN] = "";
 
                        flog_err(
                                EC_ZEBRA_TABLE_LOOKUP_FAILED,
-                               "Zebra failed to find or create a nexthop hash entry for %s%s%s",
-                               prefix2str(p, buf, sizeof(buf)),
-                               src_p ? " from " : "",
+                               "Zebra failed to find or create a nexthop hash entry for %pFX%s%s",
+                               p, src_p ? " from " : "",
                                src_p ? prefix2str(src_p, buf2, sizeof(buf2))
                                      : "");
 
@@ -3061,7 +3053,7 @@ int rib_add_multipath(afi_t afi, safi_t safi, struct prefix *p,
 }
 
 void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
-               unsigned short instance, int flags, struct prefix *p,
+               unsigned short instance, uint32_t flags, struct prefix *p,
                struct prefix_ipv6 *src_p, const struct nexthop *nh,
                uint32_t nhe_id, uint32_t table_id, uint32_t metric,
                uint8_t distance, bool fromkernel, bool connected_down)
@@ -3091,19 +3083,17 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
        /* Lookup route node. */
        rn = srcdest_rnode_lookup(table, p, src_p);
        if (!rn) {
-               char dst_buf[PREFIX_STRLEN], src_buf[PREFIX_STRLEN];
-
-               prefix2str(p, dst_buf, sizeof(dst_buf));
-               if (src_p && src_p->prefixlen)
-                       prefix2str(src_p, src_buf, sizeof(src_buf));
-               else
-                       src_buf[0] = '\0';
-
                if (IS_ZEBRA_DEBUG_RIB) {
+                       char src_buf[PREFIX_STRLEN];
                        struct vrf *vrf = vrf_lookup_by_id(vrf_id);
 
-                       zlog_debug("%s[%d]:%s%s%s doesn't exist in rib",
-                                  vrf->name, table_id, dst_buf,
+                       if (src_p && src_p->prefixlen)
+                               prefix2str(src_p, src_buf, sizeof(src_buf));
+                       else
+                               src_buf[0] = '\0';
+
+                       zlog_debug("%s[%d]:%pFX%s%s doesn't exist in rib",
+                                  vrf->name, table_id, p,
                                   (src_buf[0] != '\0') ? " from " : "",
                                   src_buf);
                }
@@ -3291,7 +3281,7 @@ void rib_delete(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
 
 
 int rib_add(afi_t afi, safi_t safi, vrf_id_t vrf_id, int type,
-           unsigned short instance, int flags, struct prefix *p,
+           unsigned short instance, uint32_t flags, struct prefix *p,
            struct prefix_ipv6 *src_p, const struct nexthop *nh,
            uint32_t nhe_id, uint32_t table_id, uint32_t metric, uint32_t mtu,
            uint8_t distance, route_tag_t tag)
@@ -3840,6 +3830,7 @@ static int rib_process_dplane_results(struct thread *thread)
                        case DPLANE_OP_VTEP_ADD:
                        case DPLANE_OP_VTEP_DELETE:
                        case DPLANE_OP_NEIGH_DISCOVER:
+                       case DPLANE_OP_BR_PORT_UPDATE:
                        case DPLANE_OP_NONE:
                                /* Don't expect this: just return the struct? */
                                dplane_ctx_fini(&ctx);
index cdc00f6026504ded3828c23bf7b55a8c4ea228ce..521f969fcc44ac3518900196e65bc5baa407bd5f 100644 (file)
@@ -86,12 +86,6 @@ static inline struct route_table *get_rnh_table(vrf_id_t vrfid, afi_t afi,
        return t;
 }
 
-char *rnh_str(struct rnh *rnh, char *buf, int size)
-{
-       prefix2str(&(rnh->node->p), buf, size);
-       return buf;
-}
-
 static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
 {
        struct zebra_vrf *zvrf = zebra_vrf_lookup_by_id(rnh->vrf_id);
@@ -106,15 +100,10 @@ static void zebra_rnh_remove_from_routing_table(struct rnh *rnh)
        if (!rn)
                return;
 
-       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
-               char buf[PREFIX_STRLEN];
-               char buf1[PREFIX_STRLEN];
-
-               zlog_debug("%s: %u:%s removed from tracking on %s", __func__,
-                          rnh->vrf_id,
-                          prefix2str(&rnh->node->p, buf, sizeof(buf)),
-                          srcdest_rnode2str(rn, buf1, sizeof(buf)));
-       }
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+               zlog_debug("%s: %s(%u):%pRN removed from tracking on %pRN",
+                          __func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id,
+                          rnh->node, rn);
 
        dest = rib_dest_from_rnode(rn);
        rnh_list_del(&dest->nht, rnh);
@@ -132,15 +121,10 @@ static void zebra_rnh_store_in_routing_table(struct rnh *rnh)
        if (!rn)
                return;
 
-       if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
-               char buf[PREFIX_STRLEN];
-               char buf1[PREFIX_STRLEN];
-
-               zlog_debug("%s: %u:%s added for tracking on %s", __func__,
-                          rnh->vrf_id,
-                          prefix2str(&rnh->node->p, buf, sizeof(buf)),
-                          srcdest_rnode2str(rn, buf1, sizeof(buf)));
-       }
+       if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+               zlog_debug("%s: %s(%u):%pRN added for tracking on %pRN",
+                          __func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id,
+                          rnh->node, rn);
 
        dest = rib_dest_from_rnode(rn);
        rnh_list_add_tail(&dest->nht, rnh);
@@ -153,20 +137,21 @@ struct rnh *zebra_add_rnh(struct prefix *p, vrf_id_t vrfid, enum rnh_type type,
        struct route_table *table;
        struct route_node *rn;
        struct rnh *rnh = NULL;
-       char buf[PREFIX2STR_BUFFER];
        afi_t afi = family2afi(p->family);
 
        if (IS_ZEBRA_DEBUG_NHT) {
-               prefix2str(p, buf, sizeof(buf));
-               zlog_debug("%u: Add RNH %s type %s", vrfid, buf,
-                          rnh_type2str(type));
+               struct vrf *vrf = vrf_lookup_by_id(vrfid);
+
+               zlog_debug("%s(%u): Add RNH %pFX type %s", VRF_LOGNAME(vrf),
+                          vrfid, p, rnh_type2str(type));
        }
        table = get_rnh_table(vrfid, afi, type);
        if (!table) {
-               prefix2str(p, buf, sizeof(buf));
+               struct vrf *vrf = vrf_lookup_by_id(vrfid);
+
                flog_warn(EC_ZEBRA_RNH_NO_TABLE,
-                         "%u: Add RNH %s type %s - table not found", vrfid,
-                         buf, rnh_type2str(type));
+                         "%s(%u): Add RNH %pFX type %s - table not found",
+                         VRF_LOGNAME(vrf), vrfid, p, rnh_type2str(type));
                exists = false;
                return NULL;
        }
@@ -270,9 +255,10 @@ static void zebra_delete_rnh(struct rnh *rnh, enum rnh_type type)
                return;
 
        if (IS_ZEBRA_DEBUG_NHT) {
-               char buf[PREFIX2STR_BUFFER];
-               zlog_debug("%u: Del RNH %s type %s", rnh->vrf_id,
-                          rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type));
+               struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id);
+
+               zlog_debug("%s(%u): Del RNH %pRN type %s", VRF_LOGNAME(vrf),
+                          rnh->vrf_id, rnh->node, rnh_type2str(type));
        }
 
        zebra_free_rnh(rnh);
@@ -292,10 +278,12 @@ void zebra_add_rnh_client(struct rnh *rnh, struct zserv *client,
                          enum rnh_type type, vrf_id_t vrf_id)
 {
        if (IS_ZEBRA_DEBUG_NHT) {
-               char buf[PREFIX2STR_BUFFER];
-               zlog_debug("%u: Client %s registers for RNH %s type %s", vrf_id,
-                          zebra_route_string(client->proto),
-                          rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type));
+               struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+               zlog_debug("%s(%u): Client %s registers for RNH %pRN type %s",
+                          VRF_LOGNAME(vrf), vrf_id,
+                          zebra_route_string(client->proto), rnh->node,
+                          rnh_type2str(type));
        }
        if (!listnode_lookup(rnh->client_list, client))
                listnode_add(rnh->client_list, client);
@@ -311,10 +299,11 @@ void zebra_remove_rnh_client(struct rnh *rnh, struct zserv *client,
                             enum rnh_type type)
 {
        if (IS_ZEBRA_DEBUG_NHT) {
-               char buf[PREFIX2STR_BUFFER];
-               zlog_debug("Client %s unregisters for RNH %s type %s",
-                          zebra_route_string(client->proto),
-                          rnh_str(rnh, buf, sizeof(buf)), rnh_type2str(type));
+               struct vrf *vrf = vrf_lookup_by_id(rnh->vrf_id);
+
+               zlog_debug("Client %s unregisters for RNH %s(%u)%pRN type %s",
+                          zebra_route_string(client->proto), VRF_LOGNAME(vrf),
+                          vrf->vrf_id, rnh->node, rnh_type2str(type));
        }
        listnode_delete(rnh->client_list, client);
        zebra_delete_rnh(rnh, type);
@@ -456,13 +445,9 @@ zebra_rnh_resolve_import_entry(struct zebra_vrf *zvrf, afi_t afi,
                return NULL;
 
        if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
-               char buf[PREFIX_STRLEN];
-               char buf1[SRCDEST2STR_BUFFER];
-
-               zlog_debug("%s: %u:%s Resolved Import Entry to %s", __func__,
-                          rnh->vrf_id,
-                          prefix2str(&rnh->node->p, buf, sizeof(buf)),
-                          srcdest_rnode2str(rn, buf1, sizeof(buf1)));
+               zlog_debug("%s: %s(%u):%pRN Resolved Import Entry to %pRN",
+                          __func__, VRF_LOGNAME(zvrf->vrf), rnh->vrf_id,
+                          rnh->node, rn);
        }
 
        /* Identify appropriate route entry. */
@@ -495,7 +480,6 @@ static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi,
 {
        int state_changed = 0;
        struct zserv *client;
-       char bufn[INET6_ADDRSTRLEN];
        struct listnode *node;
 
        zebra_rnh_remove_from_routing_table(rnh);
@@ -521,13 +505,11 @@ static void zebra_rnh_eval_import_check_entry(struct zebra_vrf *zvrf, afi_t afi,
        }
 
        if (state_changed || force) {
-               if (IS_ZEBRA_DEBUG_NHT) {
-                       prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
-                       zlog_debug("%u:%s: Route import check %s %s",
-                                  zvrf->vrf->vrf_id,
-                                  bufn, rnh->state ? "passed" : "failed",
+               if (IS_ZEBRA_DEBUG_NHT)
+                       zlog_debug("%s(%u):%pRN: Route import check %s %s",
+                                  VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id,
+                                  nrn, rnh->state ? "passed" : "failed",
                                   state_changed ? "(state changed)" : "");
-               }
                /* state changed, notify clients */
                for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
                        zebra_send_rnh_update(rnh, client,
@@ -548,19 +530,17 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
 {
        struct listnode *node;
        struct zserv *client;
-       char bufn[INET6_ADDRSTRLEN];
-       char bufp[INET6_ADDRSTRLEN];
        int num_resolving_nh;
 
        if (IS_ZEBRA_DEBUG_NHT) {
-               prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
                if (prn && re) {
-                       srcdest_rnode2str(prn, bufp, INET6_ADDRSTRLEN);
-                       zlog_debug("%u:%s: NH resolved over route %s",
-                                  zvrf->vrf->vrf_id, bufn, bufp);
+                       zlog_debug("%s(%u):%pRN: NH resolved over route %pRN",
+                                  VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id,
+                                  nrn, prn);
                } else
-                       zlog_debug("%u:%s: NH has become unresolved",
-                                  zvrf->vrf->vrf_id, bufn);
+                       zlog_debug("%s(%u):%pRN: NH has become unresolved",
+                                  VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id,
+                                  nrn);
        }
 
        for (ALL_LIST_ELEMENTS_RO(rnh->client_list, node, client)) {
@@ -579,8 +559,9 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
 
                        if (IS_ZEBRA_DEBUG_NHT)
                                zlog_debug(
-                                       "%u:%s: Notifying client %s about NH %s",
-                                       zvrf->vrf->vrf_id, bufn,
+                                       "%s(%u):%pRN: Notifying client %s about NH %s",
+                                       VRF_LOGNAME(zvrf->vrf),
+                                       zvrf->vrf->vrf_id, nrn,
                                        zebra_route_string(client->proto),
                                        num_resolving_nh
                                                ? ""
@@ -589,8 +570,9 @@ static void zebra_rnh_notify_protocol_clients(struct zebra_vrf *zvrf, afi_t afi,
                        rnh->filtered[client->proto] = 0;
                        if (IS_ZEBRA_DEBUG_NHT)
                                zlog_debug(
-                                       "%u:%s: Notifying client %s about NH (unreachable)",
-                                       zvrf->vrf->vrf_id, bufn,
+                                       "%s(%u):%pRN: Notifying client %s about NH (unreachable)",
+                                       VRF_LOGNAME(zvrf->vrf),
+                                       zvrf->vrf->vrf_id, nrn,
                                        zebra_route_string(client->proto));
                }
 
@@ -648,15 +630,10 @@ zebra_rnh_resolve_nexthop_entry(struct zebra_vrf *zvrf, afi_t afi,
         * most-specific match. Do similar logic as in zebra_rib.c
         */
        while (rn) {
-               if (IS_ZEBRA_DEBUG_NHT_DETAILED) {
-                       char buf[PREFIX_STRLEN];
-                       char buf1[PREFIX_STRLEN];
-
-                       zlog_debug("%s: %u:%s Possible Match to %s", __func__,
-                                  rnh->vrf_id,
-                                  prefix2str(&rnh->node->p, buf, sizeof(buf)),
-                                  srcdest_rnode2str(rn, buf1, sizeof(buf)));
-               }
+               if (IS_ZEBRA_DEBUG_NHT_DETAILED)
+                       zlog_debug("%s: %s(%u):%pRN Possible Match to %pRN",
+                                  __func__, VRF_LOGNAME(zvrf->vrf),
+                                  rnh->vrf_id, rnh->node, rn);
 
                /* Do not resolve over default route unless allowed &&
                 * match route to be exact if so specified
@@ -819,12 +796,11 @@ static void zebra_rnh_evaluate_entry(struct zebra_vrf *zvrf, afi_t afi,
        struct rnh *rnh;
        struct route_entry *re;
        struct route_node *prn;
-       char bufn[INET6_ADDRSTRLEN];
 
        if (IS_ZEBRA_DEBUG_NHT) {
-               prefix2str(&nrn->p, bufn, INET6_ADDRSTRLEN);
-               zlog_debug("%u:%s: Evaluate RNH, type %s %s", zvrf->vrf->vrf_id,
-                          bufn, rnh_type2str(type), force ? "(force)" : "");
+               zlog_debug("%s(%u):%pRN: Evaluate RNH, type %s %s",
+                          VRF_LOGNAME(zvrf->vrf), zvrf->vrf->vrf_id, nrn,
+                          rnh_type2str(type), force ? "(force)" : "");
        }
 
        rnh = nrn->info;
@@ -1221,7 +1197,7 @@ static void print_nh(struct nexthop *nexthop, struct vty *vty)
        switch (nexthop->type) {
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
+               vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
                if (nexthop->ifindex)
                        vty_out(vty, ", %s",
                                ifindex2ifname_per_ns(zns, nexthop->ifindex));
@@ -1289,10 +1265,15 @@ static int zebra_cleanup_rnh_client(vrf_id_t vrf_id, afi_t afi,
        struct route_node *nrn;
        struct rnh *rnh;
 
-       if (IS_ZEBRA_DEBUG_NHT)
-               zlog_debug("%u: Client %s RNH cleanup for family %s type %s",
-                          vrf_id, zebra_route_string(client->proto),
-                          afi2str(afi), rnh_type2str(type));
+       if (IS_ZEBRA_DEBUG_NHT) {
+               struct vrf *vrf = vrf_lookup_by_id(vrf_id);
+
+               zlog_debug(
+                       "%s(%u): Client %s RNH cleanup for family %s type %s",
+                       VRF_LOGNAME(vrf), vrf_id,
+                       zebra_route_string(client->proto), afi2str(afi),
+                       rnh_type2str(type));
+       }
 
        ntable = get_rnh_table(vrf_id, afi, type);
        if (!ntable) {
index ba12b1738f26503bf483fda52a4285d1d107cb52..c71a2b9ccefd4fd83d45dca355482cb4402b7438 100644 (file)
@@ -61,7 +61,6 @@ extern void zebra_evaluate_rnh(struct zebra_vrf *zvrf, afi_t afi, int force,
                               enum rnh_type type, struct prefix *p);
 extern void zebra_print_rnh_table(vrf_id_t vrfid, afi_t afi, struct vty *vty,
                                  enum rnh_type type, struct prefix *p);
-extern char *rnh_str(struct rnh *rnh, char *buf, int size);
 
 extern int rnh_resolve_via_default(struct zebra_vrf *zvrf, int family);
 
index 8155f9acfe058d6f079d9efa6aca467edc02e7c6..294f2c17ff270b5519228413fcb1bf777dd23822 100644 (file)
@@ -1695,7 +1695,7 @@ static void zebra_route_map_set_delay_timer(uint32_t value)
        if (!value && zebra_t_rmap_update) {
                /* Event driven route map updates is being disabled */
                /* But there's a pending timer. Fire it off now */
-               thread_cancel(zebra_t_rmap_update);
+               thread_cancel(&zebra_t_rmap_update);
                zebra_route_map_update_timer(zebra_t_rmap_update);
        }
 }
@@ -1705,7 +1705,7 @@ void zebra_routemap_finish(void)
        /* Set zebra_rmap_update_timer to 0 so that it wont schedule again */
        zebra_rmap_update_timer = 0;
        /* Thread off if any scheduled already */
-       THREAD_TIMER_OFF(zebra_t_rmap_update);
+       thread_cancel(&zebra_t_rmap_update);
        route_map_finish();
 }
 
index 67f94bfcfeb5bc7f9e395937b81b607acbd48d5d..8651a01e9fec06320b20ea4c63948bb9f589c8c7 100644 (file)
@@ -61,6 +61,29 @@ enum multicast_mode {
                              /* on equal value, MRIB wins for last 2 */
 };
 
+/* An interface can be error-disabled if a protocol (such as EVPN or
+ * VRRP) detects a problem with keeping it operationally-up.
+ * If any of the protodown bits are set protodown-on is programmed
+ * in the dataplane. This results in a carrier/L1 down on the
+ * physical device.
+ */
+enum protodown_reasons {
+       /* On startup local ESs are held down for some time to
+        * allow the underlay to converge and EVPN routes to
+        * get learnt
+        */
+       ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY = (1 << 0),
+       /* If all the uplinks are down the switch has lost access
+        * to the VxLAN overlay and must shut down the access
+        * ports to allow servers to re-direct their traffic to
+        * other switches on the Ethernet Segment
+        */
+       ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN = (1 << 1),
+       ZEBRA_PROTODOWN_EVPN_ALL = (ZEBRA_PROTODOWN_EVPN_UPLINK_DOWN
+                                   | ZEBRA_PROTODOWN_EVPN_STARTUP_DELAY)
+};
+#define ZEBRA_PROTODOWN_RC_STR_LEN 80
+
 struct zebra_mlag_info {
        /* Role this zebra router is playing */
        enum mlag_role role;
index d102b02a21c8b2e2dd8868278ba0def3a485d0a8..b7cbf5262a832e3e1125a78dfccb1ce0a1b992b3 100644 (file)
@@ -315,6 +315,9 @@ static int zebra_vrf_delete(struct vrf *vrf)
        list_delete_all_node(zvrf->rid_all_sorted_list);
        list_delete_all_node(zvrf->rid_lo_sorted_list);
 
+       list_delete_all_node(zvrf->rid6_all_sorted_list);
+       list_delete_all_node(zvrf->rid6_lo_sorted_list);
+
        otable_fini(&zvrf->other_tables);
        XFREE(MTYPE_ZEBRA_VRF, zvrf);
        vrf->info = NULL;
index 67851517058fb238f3a44543a9c2292f24110e94..ab7d2845e73603c29c50d2bf37c1b62df60c2d2c 100644 (file)
@@ -304,8 +304,8 @@ static void show_nexthop_detail_helper(struct vty *vty,
        switch (nexthop->type) {
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               vty_out(vty, " %s",
-                       inet_ntoa(nexthop->gate.ipv4));
+               vty_out(vty, " %pI4",
+                       &nexthop->gate.ipv4);
                if (nexthop->ifindex)
                        vty_out(vty, ", via %s",
                                ifindex2ifname(
@@ -508,7 +508,7 @@ static void show_route_nexthop_helper(struct vty *vty,
        switch (nexthop->type) {
        case NEXTHOP_TYPE_IPV4:
        case NEXTHOP_TYPE_IPV4_IFINDEX:
-               vty_out(vty, " via %s", inet_ntoa(nexthop->gate.ipv4));
+               vty_out(vty, " via %pI4", &nexthop->gate.ipv4);
                if (nexthop->ifindex)
                        vty_out(vty, ", %s",
                                ifindex2ifname(nexthop->ifindex,
@@ -636,7 +636,8 @@ static void show_nexthop_json_helper(json_object *json_nexthop,
        case NEXTHOP_TYPE_IPV4_IFINDEX:
                json_object_string_add(
                        json_nexthop, "ip",
-                       inet_ntoa(nexthop->gate.ipv4));
+                       inet_ntop(AF_INET, &nexthop->gate.ipv4,
+                                 buf, sizeof(buf)));
                json_object_string_add(json_nexthop, "afi",
                                       "ipv4");
 
@@ -1404,6 +1405,7 @@ struct nhe_show_context {
        struct vty *vty;
        vrf_id_t vrf_id;
        afi_t afi;
+       int type;
 };
 
 static int nhe_show_walker(struct hash_bucket *bucket, void *arg)
@@ -1419,6 +1421,9 @@ static int nhe_show_walker(struct hash_bucket *bucket, void *arg)
        if (ctx->vrf_id && nhe->vrf_id != ctx->vrf_id)
                goto done;
 
+       if (ctx->type && nhe->type != ctx->type)
+               goto done;
+
        show_nexthop_group_out(ctx->vty, nhe);
 
 done:
@@ -1426,14 +1431,15 @@ done:
 }
 
 static void show_nexthop_group_cmd_helper(struct vty *vty,
-                                         struct zebra_vrf *zvrf,
-                                         afi_t afi)
+                                         struct zebra_vrf *zvrf, afi_t afi,
+                                         int type)
 {
        struct nhe_show_context ctx;
 
        ctx.vty = vty;
        ctx.afi = afi;
        ctx.vrf_id = zvrf->vrf->vrf_id;
+       ctx.type = type;
 
        hash_walk(zrouter.nhgs_id, nhe_show_walker, &ctx);
 }
@@ -1492,7 +1498,7 @@ DEFPY (show_interface_nexthop_group,
 
 DEFPY (show_nexthop_group,
        show_nexthop_group_cmd,
-       "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [vrf <NAME$vrf_name|all$vrf_all>]>",
+       "show nexthop-group rib <(0-4294967295)$id|[singleton <ip$v4|ipv6$v6>] [<kernel|zebra|bgp|sharp>$type_str] [vrf <NAME$vrf_name|all$vrf_all>]>",
        SHOW_STR
        "Show Nexthop Groups\n"
        "RIB information\n"
@@ -1500,11 +1506,16 @@ DEFPY (show_nexthop_group,
        "Show Singleton Nexthop-Groups\n"
        IP_STR
        IP6_STR
+       "Kernel (not installed via the zebra RIB)\n"
+       "Zebra (implicitly created by zebra)\n"
+       "Border Gateway Protocol (BGP)\n"
+       "Super Happy Advanced Routing Protocol (SHARP)\n"
        VRF_FULL_CMD_HELP_STR)
 {
 
        struct zebra_vrf *zvrf = NULL;
        afi_t afi = AFI_UNSPEC;
+       int type = 0;
 
        if (id)
                return show_nexthop_group_id_cmd_helper(vty, id);
@@ -1514,6 +1525,14 @@ DEFPY (show_nexthop_group,
        else if (v6)
                afi = AFI_IP6;
 
+       if (type_str) {
+               type = proto_redistnum((afi ? afi : AFI_IP), type_str);
+               if (type < 0) {
+                       /* assume zebra */
+                       type = ZEBRA_ROUTE_NHG;
+               }
+       }
+
        if (!vrf_is_backend_netns() && (vrf_name || vrf_all)) {
                vty_out(vty,
                        "VRF subcommand does not make any sense in l3mdev based vrf's\n");
@@ -1531,7 +1550,7 @@ DEFPY (show_nexthop_group,
                                continue;
 
                        vty_out(vty, "VRF: %s\n", vrf->name);
-                       show_nexthop_group_cmd_helper(vty, zvrf, afi);
+                       show_nexthop_group_cmd_helper(vty, zvrf, afi, type);
                }
 
                return CMD_SUCCESS;
@@ -1548,7 +1567,7 @@ DEFPY (show_nexthop_group,
                return CMD_WARNING;
        }
 
-       show_nexthop_group_cmd_helper(vty, zvrf, afi);
+       show_nexthop_group_cmd_helper(vty, zvrf, afi, type);
 
        return CMD_SUCCESS;
 }
@@ -1747,9 +1766,11 @@ DEFPY (show_route,
                if (vrf_name)
                        VRF_GET_ID(vrf_id, vrf_name, !!json);
                vrf = vrf_lookup_by_id(vrf_id);
-               if (vrf)
-                       zvrf = vrf->info;
-               if (!vrf || !zvrf)
+               if (!vrf)
+                       return CMD_SUCCESS;
+
+               zvrf = vrf->info;
+               if (!zvrf)
                        return CMD_SUCCESS;
 
                if (table_all)
@@ -1768,6 +1789,15 @@ DEFPY (show_route,
        return CMD_SUCCESS;
 }
 
+ALIAS_HIDDEN (show_route,
+              show_ro_cmd,
+              "show <ip$ipv4|ipv6$ipv6> ro",
+              SHOW_STR
+              IP_STR
+              IPV6_STR
+              "IP routing table\n");
+
+
 DEFPY (show_route_detail,
        show_route_detail_cmd,
        "show\
@@ -2405,6 +2435,20 @@ DEFPY (evpn_mh_neigh_holdtime,
                        no ? true : false);
 }
 
+DEFPY (evpn_mh_startup_delay,
+       evpn_mh_startup_delay_cmd,
+       "[no] evpn mh startup-delay(0-3600)$duration",
+       NO_STR
+       "EVPN\n"
+       "Multihoming\n"
+       "Startup delay\n"
+       "duration in seconds\n")
+{
+
+       return zebra_evpn_mh_startup_delay_update(vty, duration,
+                       no ? true : false);
+}
+
 DEFUN (default_vrf_vni_mapping,
        default_vrf_vni_mapping_cmd,
        "vni " CMD_VNI_RANGE "[prefix-routes-only]",
@@ -2586,7 +2630,7 @@ DEFUN (show_evpn_global,
 
 DEFPY(show_evpn_es,
       show_evpn_es_cmd,
-      "show evpn es [NAME$esi_str] [json$json] [detail$detail]",
+      "show evpn es [NAME$esi_str|detail$detail] [json$json]",
       SHOW_STR
       "EVPN\n"
       "Ethernet Segment\n"
@@ -2615,14 +2659,14 @@ DEFPY(show_evpn_es,
 
 DEFPY(show_evpn_es_evi,
       show_evpn_es_evi_cmd,
-      "show evpn es-evi [vni (1-16777215)$vni] [json$json] [detail$detail]",
+      "show evpn es-evi [vni (1-16777215)$vni] [detail$detail] [json$json]",
       SHOW_STR
       "EVPN\n"
       "Ethernet Segment per EVI\n"
       "VxLAN Network Identifier\n"
       "VNI\n"
-      JSON_STR
-      "Detailed information\n")
+      "Detailed information\n"
+      JSON_STR)
 {
        bool uj = !!json;
        bool ud = !!detail;
@@ -2637,13 +2681,13 @@ DEFPY(show_evpn_es_evi,
 
 DEFPY(show_evpn_access_vlan,
       show_evpn_access_vlan_cmd,
-      "show evpn access-vlan [(1-4094)$vid] [json$json] [detail$detail]",
+      "show evpn access-vlan [(1-4094)$vid | detail$detail] [json$json]",
       SHOW_STR
       "EVPN\n"
       "Access VLANs\n"
       "VLAN ID\n"
-      JSON_STR
-      "Detailed information\n")
+      "Detailed information\n"
+      JSON_STR)
 {
        bool uj = !!json;
 
@@ -3264,7 +3308,8 @@ DEFPY (clear_evpn_dup_addr,
 
        if (yang_dup) {
                listnode_add(input, yang_dup);
-               ret = nb_cli_rpc("/frr-zebra:clear-evpn-dup-addr", input, NULL);
+               ret = nb_cli_rpc(vty, "/frr-zebra:clear-evpn-dup-addr", input,
+                                NULL);
        }
 
        list_delete(&input);
@@ -3904,6 +3949,7 @@ void zebra_vty_init(void)
        install_element(VIEW_NODE, &show_vrf_cmd);
        install_element(VIEW_NODE, &show_vrf_vni_cmd);
        install_element(VIEW_NODE, &show_route_cmd);
+       install_element(VIEW_NODE, &show_ro_cmd);
        install_element(VIEW_NODE, &show_route_detail_cmd);
        install_element(VIEW_NODE, &show_route_summary_cmd);
        install_element(VIEW_NODE, &show_ip_nht_cmd);
@@ -3960,6 +4006,7 @@ void zebra_vty_init(void)
 
        install_element(CONFIG_NODE, &evpn_mh_mac_holdtime_cmd);
        install_element(CONFIG_NODE, &evpn_mh_neigh_holdtime_cmd);
+       install_element(CONFIG_NODE, &evpn_mh_startup_delay_cmd);
        install_element(CONFIG_NODE, &default_vrf_vni_mapping_cmd);
        install_element(CONFIG_NODE, &no_default_vrf_vni_mapping_cmd);
        install_element(VRF_NODE, &vrf_vni_mapping_cmd);
index d8ed58edef5b0c020ea5b79770687a26f94fbc01..4b3b142d4024bb804cee1a903edff68b61343310 100644 (file)
@@ -36,6 +36,7 @@
 #ifdef GNU_LINUX
 #include <linux/neighbour.h>
 #endif
+#include "lib/printfrr.h"
 
 #include "zebra/zebra_router.h"
 #include "zebra/debug.h"
@@ -309,8 +310,7 @@ static void zl3vni_print_nh(zebra_neigh_t *n, struct vty *vty,
                        rb_host_count(&n->host_rb));
                vty_out(vty, "  Prefixes:\n");
                RB_FOREACH (hle, host_rb_tree_entry, &n->host_rb)
-                       vty_out(vty, "    %s\n",
-                               prefix2str(&hle->p, buf2, sizeof(buf2)));
+                       vty_out(vty, "    %pFX\n", &hle->p);
        } else {
                json_hosts = json_object_new_array();
                json_object_string_add(
@@ -340,20 +340,21 @@ static void zl3vni_print_rmac(zebra_mac_t *zrmac, struct vty *vty,
        if (!json) {
                vty_out(vty, "MAC: %s\n",
                        prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
-               vty_out(vty, " Remote VTEP: %s\n",
-                       inet_ntoa(zrmac->fwd_info.r_vtep_ip));
+               vty_out(vty, " Remote VTEP: %pI4\n",
+                       &zrmac->fwd_info.r_vtep_ip);
                vty_out(vty, " Refcount: %d\n", rb_host_count(&zrmac->host_rb));
                vty_out(vty, "  Prefixes:\n");
                RB_FOREACH (hle, host_rb_tree_entry, &zrmac->host_rb)
-                       vty_out(vty, "    %s\n",
-                               prefix2str(&hle->p, buf2, sizeof(buf2)));
+                       vty_out(vty, "    %pFX\n", &hle->p);
        } else {
                json_hosts = json_object_new_array();
                json_object_string_add(
                        json, "routerMac",
                        prefix_mac2str(&zrmac->macaddr, buf1, sizeof(buf1)));
                json_object_string_add(json, "vtepIp",
-                                      inet_ntoa(zrmac->fwd_info.r_vtep_ip));
+                                      inet_ntop(AF_INET,
+                                                &zrmac->fwd_info.r_vtep_ip,
+                                                buf1, sizeof(buf1)));
                json_object_int_add(json, "refCount",
                                    rb_host_count(&zrmac->host_rb));
                json_object_int_add(json, "localSequence", zrmac->loc_seq);
@@ -630,7 +631,7 @@ static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
        struct vty *vty = NULL;
        struct json_object *json = NULL;
        struct json_object *json_rmac = NULL;
-       char buf[ETHER_ADDR_STRLEN];
+       char buf[PREFIX_STRLEN];
 
        wctx = (struct rmac_walk_ctx *)ctx;
        vty = wctx->vty;
@@ -640,15 +641,17 @@ static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
        zrmac = (zebra_mac_t *)bucket->data;
 
        if (!json) {
-               vty_out(vty, "%-17s %-21s\n",
+               vty_out(vty, "%-17s %-21pI4\n",
                        prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
-                       inet_ntoa(zrmac->fwd_info.r_vtep_ip));
+                       &zrmac->fwd_info.r_vtep_ip);
        } else {
                json_object_string_add(
                        json_rmac, "routerMac",
                        prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)));
                json_object_string_add(json_rmac, "vtepIp",
-                                      inet_ntoa(zrmac->fwd_info.r_vtep_ip));
+                                      inet_ntop(AF_INET,
+                                                &zrmac->fwd_info.r_vtep_ip,
+                                                buf, sizeof(buf)));
                json_object_object_add(
                        json, prefix_mac2str(&zrmac->macaddr, buf, sizeof(buf)),
                        json_rmac);
@@ -658,7 +661,7 @@ static void zl3vni_print_rmac_hash(struct hash_bucket *bucket, void *ctx)
 /* print a specific L3 VNI entry */
 static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
 {
-       char buf[ETHER_ADDR_STRLEN];
+       char buf[PREFIX_STRLEN];
        struct vty *vty = NULL;
        json_object *json = NULL;
        zebra_evpn_t *zevpn = NULL;
@@ -672,8 +675,8 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
                vty_out(vty, "VNI: %u\n", zl3vni->vni);
                vty_out(vty, "  Type: %s\n", "L3");
                vty_out(vty, "  Tenant VRF: %s\n", zl3vni_vrf_name(zl3vni));
-               vty_out(vty, "  Local Vtep Ip: %s\n",
-                       inet_ntoa(zl3vni->local_vtep_ip));
+               vty_out(vty, "  Local Vtep Ip: %pI4\n",
+                       &zl3vni->local_vtep_ip);
                vty_out(vty, "  Vxlan-Intf: %s\n",
                        zl3vni_vxlan_if_name(zl3vni));
                vty_out(vty, "  SVI-If: %s\n", zl3vni_svi_if_name(zl3vni));
@@ -694,8 +697,10 @@ static void zl3vni_print(zebra_l3vni_t *zl3vni, void **ctx)
                json_evpn_list = json_object_new_array();
                json_object_int_add(json, "vni", zl3vni->vni);
                json_object_string_add(json, "type", "L3");
-               json_object_string_add(json, "localVtepIp",
-                                      inet_ntoa(zl3vni->local_vtep_ip));
+               json_object_string_add(
+                       json, "localVtepIp",
+                       inet_ntop(AF_INET, &zl3vni->local_vtep_ip, buf,
+                                 sizeof(buf)));
                json_object_string_add(json, "vxlanIntf",
                                       zl3vni_vxlan_if_name(zl3vni));
                json_object_string_add(json, "sviIntf",
@@ -944,9 +949,9 @@ static int zevpn_build_hash_table_zns(struct ns *ns,
 
                        if (IS_ZEBRA_DEBUG_VXLAN)
                                zlog_debug(
-                                       "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %s",
+                                       "Create L2-VNI hash for intf %s(%u) L2-VNI %u local IP %pI4",
                                        ifp->name, ifp->ifindex, vni,
-                                       inet_ntoa(vxl->vtep_ip));
+                                       &vxl->vtep_ip);
 
                        /* EVPN hash entry is expected to exist, if the BGP process is killed */
                        zevpn = zebra_evpn_lookup(vni);
@@ -1269,7 +1274,6 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni,
 {
        char buf[ETHER_ADDR_STRLEN];
        char buf1[INET6_ADDRSTRLEN];
-       char buf2[PREFIX_STRLEN];
        zebra_mac_t *zrmac = NULL;
 
        zrmac = zl3vni_rmac_lookup(zl3vni, rmac);
@@ -1279,11 +1283,11 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni,
                zrmac = zl3vni_rmac_add(zl3vni, rmac);
                if (!zrmac) {
                        zlog_debug(
-                               "Failed to add RMAC %s L3VNI %u Remote VTEP %s, prefix %s",
+                               "Failed to add RMAC %s L3VNI %u Remote VTEP %s, prefix %pFX",
                                prefix_mac2str(rmac, buf, sizeof(buf)),
                                zl3vni->vni,
                                ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
-                               prefix2str(host_prefix, buf2, sizeof(buf2)));
+                               host_prefix);
                        return -1;
                }
                memset(&zrmac->fwd_info, 0, sizeof(zrmac->fwd_info));
@@ -1299,12 +1303,12 @@ static int zl3vni_remote_rmac_add(zebra_l3vni_t *zl3vni,
                                   &vtep_ip->ipaddr_v4)) {
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "L3VNI %u Remote VTEP change(%s -> %s) for RMAC %s, prefix %s",
+                               "L3VNI %u Remote VTEP change(%pI4 -> %s) for RMAC %s, prefix %pFX",
                                zl3vni->vni,
-                               inet_ntoa(zrmac->fwd_info.r_vtep_ip),
+                               &zrmac->fwd_info.r_vtep_ip,
                                ipaddr2str(vtep_ip, buf1, sizeof(buf1)),
                                prefix_mac2str(rmac, buf, sizeof(buf)),
-                               prefix2str(host_prefix, buf2, sizeof(buf2)));
+                               host_prefix);
 
                zrmac->fwd_info.r_vtep_ip = vtep_ip->ipaddr_v4;
 
@@ -1464,7 +1468,6 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni,
        char buf[ETHER_ADDR_STRLEN];
        char buf1[ETHER_ADDR_STRLEN];
        char buf2[INET6_ADDRSTRLEN];
-       char buf3[PREFIX_STRLEN];
        zebra_neigh_t *nh = NULL;
 
        /* Create the next hop entry, or update its mac, if necessary. */
@@ -1473,11 +1476,10 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni,
                nh = zl3vni_nh_add(zl3vni, vtep_ip, rmac);
                if (!nh) {
                        zlog_debug(
-                               "Failed to add NH %s as Neigh (RMAC %s L3-VNI %u prefix %s)",
+                               "Failed to add NH %s as Neigh (RMAC %s L3-VNI %u prefix %pFX)",
                                ipaddr2str(vtep_ip, buf1, sizeof(buf2)),
                                prefix_mac2str(rmac, buf, sizeof(buf)),
-                               zl3vni->vni,
-                               prefix2str(host_prefix, buf2, sizeof(buf2)));
+                               zl3vni->vni, host_prefix);
                        return -1;
                }
 
@@ -1485,12 +1487,13 @@ static int zl3vni_remote_nh_add(zebra_l3vni_t *zl3vni,
                zl3vni_nh_install(zl3vni, nh);
        } else if (memcmp(&nh->emac, rmac, ETH_ALEN) != 0) {
                if (IS_ZEBRA_DEBUG_VXLAN)
-                       zlog_debug("L3VNI %u RMAC change(%s --> %s) for nexthop %s, prefix %s",
-                                  zl3vni->vni,
-                                  prefix_mac2str(&nh->emac, buf, sizeof(buf)),
-                                  prefix_mac2str(rmac, buf1, sizeof(buf1)),
-                                  ipaddr2str(vtep_ip, buf2, sizeof(buf2)),
-                                  prefix2str(host_prefix, buf3, sizeof(buf3)));
+                       zlog_debug(
+                               "L3VNI %u RMAC change(%s --> %s) for nexthop %s, prefix %pFX",
+                               zl3vni->vni,
+                               prefix_mac2str(&nh->emac, buf, sizeof(buf)),
+                               prefix_mac2str(rmac, buf1, sizeof(buf1)),
+                               ipaddr2str(vtep_ip, buf2, sizeof(buf2)),
+                               host_prefix);
 
                memcpy(&nh->emac, rmac, ETH_ALEN);
                /* install (update) the nh neigh in kernel */
@@ -1912,11 +1915,11 @@ static int zl3vni_send_add_to_client(zebra_l3vni_t *zl3vni)
 
        if (IS_ZEBRA_DEBUG_VXLAN)
                zlog_debug(
-                       "Send L3_VNI_ADD %u VRF %s RMAC %s VRR %s local-ip %s filter %s to %s",
+                       "Send L3_VNI_ADD %u VRF %s RMAC %s VRR %s local-ip %pI4 filter %s to %s",
                        zl3vni->vni, vrf_id_to_name(zl3vni_vrf_id(zl3vni)),
                        prefix_mac2str(&svi_rmac, buf, sizeof(buf)),
                        prefix_mac2str(&vrr_rmac, buf1, sizeof(buf1)),
-                       inet_ntoa(zl3vni->local_vtep_ip),
+                       &zl3vni->local_vtep_ip,
                        CHECK_FLAG(zl3vni->filter, PREFIX_ROUTES_ONLY)
                                ? "prefix-routes-only"
                                : "none",
@@ -2994,7 +2997,8 @@ void zebra_vxlan_print_macs_vni_dad(struct vty *vty,
 }
 
 int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
-                                        struct ethaddr *macaddr)
+                                        struct ethaddr *macaddr, char *errmsg,
+                                        size_t errmsg_len)
 {
        zebra_evpn_t *zevpn;
        zebra_mac_t *mac;
@@ -3006,18 +3010,20 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
 
        zevpn = zebra_evpn_lookup(vni);
        if (!zevpn) {
-               zlog_warn("VNI %u does not exist\n", vni);
+               snprintfrr(errmsg, errmsg_len, "VNI %u does not exist", vni);
                return -1;
        }
 
        mac = zebra_evpn_mac_lookup(zevpn, macaddr);
        if (!mac) {
-               zlog_warn("Requested MAC does not exist in VNI %u\n", vni);
+               snprintf(errmsg, errmsg_len,
+                        "Requested MAC does not exist in VNI %u\n", vni);
                return -1;
        }
 
        if (!CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
-               zlog_warn("Requested MAC is not duplicate detected\n");
+               snprintfrr(errmsg, errmsg_len,
+                          "Requested MAC is not duplicate detected\n");
                return -1;
        }
 
@@ -3079,7 +3085,8 @@ int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf, vni_t vni,
 }
 
 int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni,
-                                       struct ipaddr *ip)
+                                       struct ipaddr *ip, char *errmsg,
+                                       size_t errmsg_len)
 {
        zebra_evpn_t *zevpn;
        zebra_neigh_t *nbr;
@@ -3092,28 +3099,31 @@ int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf, vni_t vni,
 
        zevpn = zebra_evpn_lookup(vni);
        if (!zevpn) {
-               zlog_debug("VNI %u does not exist\n", vni);
+               snprintfrr(errmsg, errmsg_len, "VNI %u does not exist\n", vni);
                return -1;
        }
 
        nbr = zebra_evpn_neigh_lookup(zevpn, ip);
        if (!nbr) {
-               zlog_warn("Requested host IP does not exist in VNI %u\n", vni);
+               snprintfrr(errmsg, errmsg_len,
+                          "Requested host IP does not exist in VNI %u\n", vni);
                return -1;
        }
 
        ipaddr2str(&nbr->ip, buf, sizeof(buf));
 
        if (!CHECK_FLAG(nbr->flags, ZEBRA_NEIGH_DUPLICATE)) {
-               zlog_warn("Requested host IP %s is not duplicate detected\n",
-                         buf);
+               snprintfrr(errmsg, errmsg_len,
+                          "Requested host IP %s is not duplicate detected\n",
+                          buf);
                return -1;
        }
 
        mac = zebra_evpn_mac_lookup(zevpn, &nbr->emac);
 
        if (CHECK_FLAG(mac->flags, ZEBRA_MAC_DUPLICATE)) {
-               zlog_warn(
+               snprintfrr(
+                       errmsg, errmsg_len,
                        "Requested IP's associated MAC %s is still in duplicate state\n",
                        prefix_mac2str(&nbr->emac, buf2, sizeof(buf2)));
                return -1;
@@ -3417,7 +3427,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
                json_object_int_add(json, "detectionTime", zvrf->dad_time);
                json_object_int_add(json, "detectionFreezeTime",
                                    zvrf->dad_freeze_time);
-
+               zebra_evpn_mh_json(json);
        } else {
                vty_out(vty, "L2 VNIs: %u\n", num_l2vnis);
                vty_out(vty, "L3 VNIs: %u\n", num_l3vnis);
@@ -3437,6 +3447,7 @@ void zebra_vxlan_print_evpn(struct vty *vty, bool uj)
                                vty_out(vty, "  Detection freeze %s\n",
                                        "permanent");
                }
+               zebra_evpn_mh_print(vty);
        }
 
        if (uj) {
@@ -3758,14 +3769,13 @@ void zebra_vxlan_remote_macip_del(ZAPI_HANDLER_ARGS)
                l += res_length;
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %s from %s",
+                               "Recv MACIP DEL VNI %u MAC %s%s%s Remote VTEP %pI4 from %s",
                                vni,
                                prefix_mac2str(&macaddr, buf, sizeof(buf)),
                                ipa_len ? " IP " : "",
                                ipa_len ?
                                ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
-                               inet_ntoa(vtep_ip),
-                               zebra_route_string(client->proto));
+                               &vtep_ip, zebra_route_string(client->proto));
 
                process_remote_macip_del(vni, &macaddr, ipa_len, &ip, vtep_ip);
        }
@@ -3820,7 +3830,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                        else
                                strlcpy(esi_buf, "-", ESI_STR_LEN);
                        zlog_debug(
-                               "Recv %sMACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %s ESI %s from %s",
+                               "Recv %sMACIP ADD VNI %u MAC %s%s%s flags 0x%x seq %u VTEP %pI4 ESI %s from %s",
                                (flags & ZEBRA_MACIP_TYPE_SYNC_PATH) ?
                                "sync-" : "",
                                vni,
@@ -3828,7 +3838,7 @@ void zebra_vxlan_remote_macip_add(ZAPI_HANDLER_ARGS)
                                ipa_len ? " IP " : "",
                                ipa_len ?
                                ipaddr2str(&ip, buf1, sizeof(buf1)) : "",
-                               flags, seq, inet_ntoa(vtep_ip), esi_buf,
+                               flags, seq, &vtep_ip, esi_buf,
                                zebra_route_string(client->proto));
                }
 
@@ -3879,8 +3889,8 @@ int zebra_vxlan_check_readd_vtep(struct interface *ifp,
 
        if (IS_ZEBRA_DEBUG_VXLAN)
                zlog_debug(
-                       "Del MAC for remote VTEP %s intf %s(%u) VNI %u - readd",
-                       inet_ntoa(vtep_ip), ifp->name, ifp->ifindex, vni);
+                       "Del MAC for remote VTEP %pI4 intf %s(%u) VNI %u - readd",
+                       &vtep_ip, ifp->name, ifp->ifindex, vni);
 
        zebra_evpn_vtep_install(zevpn, zvtep);
        return 0;
@@ -4120,8 +4130,8 @@ void zebra_vxlan_remote_vtep_del(ZAPI_HANDLER_ARGS)
                l += 4;
 
                if (IS_ZEBRA_DEBUG_VXLAN)
-                       zlog_debug("Recv VTEP_DEL %s VNI %u from %s",
-                                  inet_ntoa(vtep_ip), vni,
+                       zlog_debug("Recv VTEP_DEL %pI4 VNI %u from %s",
+                                  &vtep_ip, vni,
                                   zebra_route_string(client->proto));
 
                /* Locate VNI hash entry - expected to exist. */
@@ -4204,8 +4214,8 @@ void zebra_vxlan_remote_vtep_add(ZAPI_HANDLER_ARGS)
                l += IPV4_MAX_BYTELEN + 4;
 
                if (IS_ZEBRA_DEBUG_VXLAN)
-                       zlog_debug("Recv VTEP_ADD %s VNI %u flood %d from %s",
-                                       inet_ntoa(vtep_ip), vni, flood_control,
+                       zlog_debug("Recv VTEP_ADD %pI4 VNI %u flood %d from %s",
+                                       &vtep_ip, vni, flood_control,
                                        zebra_route_string(client->proto));
 
                /* Locate VNI hash entry - expected to exist. */
@@ -4787,9 +4797,9 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
 
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "Update L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
+                               "Update L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
                                vni, ifp->name, ifp->ifindex, vxl->access_vlan,
-                               inet_ntoa(vxl->vtep_ip),
+                               &vxl->vtep_ip,
                                zif->brslave_info.bridge_ifindex, chgflags);
 
                /* Removed from bridge? Cleanup and return */
@@ -4851,9 +4861,9 @@ int zebra_vxlan_if_update(struct interface *ifp, uint16_t chgflags)
 
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "Update L2-VNI %u intf %s(%u) VLAN %u local IP %s master %u chg 0x%x",
+                               "Update L2-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u chg 0x%x",
                                vni, ifp->name, ifp->ifindex, vxl->access_vlan,
-                               inet_ntoa(vxl->vtep_ip),
+                               &vxl->vtep_ip,
                                zif->brslave_info.bridge_ifindex, chgflags);
 
                /* Removed from bridge? Cleanup and return */
@@ -4958,9 +4968,9 @@ int zebra_vxlan_if_add(struct interface *ifp)
                /* process if-add for l3-vni*/
                if (IS_ZEBRA_DEBUG_VXLAN)
                        zlog_debug(
-                               "Add L3-VNI %u intf %s(%u) VLAN %u local IP %s master %u",
+                               "Add L3-VNI %u intf %s(%u) VLAN %u local IP %pI4 master %u",
                                vni, ifp->name, ifp->ifindex, vxl->access_vlan,
-                               inet_ntoa(vxl->vtep_ip),
+                               &vxl->vtep_ip,
                                zif->brslave_info.bridge_ifindex);
 
                /* associate with vxlan_if */
index 9c8af9d1fcfa043ee0fd82b12e401b79aba7c2f3..534e29936d5b6c05b4cedd6afe5e0e735b336e58 100644 (file)
@@ -208,9 +208,12 @@ extern void zebra_vxlan_evpn_vrf_route_del(vrf_id_t vrf_id,
                                           struct prefix *host_prefix);
 extern int zebra_vxlan_clear_dup_detect_vni_mac(struct zebra_vrf *zvrf,
                                                vni_t vni,
-                                               struct ethaddr *macaddr);
+                                               struct ethaddr *macaddr,
+                                               char *errmsg,
+                                               size_t errmsg_len);
 extern int zebra_vxlan_clear_dup_detect_vni_ip(struct zebra_vrf *zvrf,
-                                              vni_t vni, struct ipaddr *ip);
+                                              vni_t vni, struct ipaddr *ip,
+                                              char *errmsg, size_t errmsg_len);
 extern int zebra_vxlan_clear_dup_detect_vni_all(struct zebra_vrf *zvrf);
 extern int zebra_vxlan_clear_dup_detect_vni(struct zebra_vrf *zvrf, vni_t vni);
 extern void zebra_vxlan_handle_result(struct zebra_dplane_ctx *ctx);
index 44f4641fcf5f8b1c3ca9a7a158b6a84fd9e52734..4b5791530d0868ea774f6dddcae5a60c6853422a 100644 (file)
@@ -1172,11 +1172,9 @@ static void zebra_show_stale_client_detail(struct vty *vty,
                                }
                        }
                        vty_out(vty, "Current AFI : %d\n", info->current_afi);
-                       if (info->current_prefix) {
-                               prefix2str(info->current_prefix, buf,
-                                          sizeof(buf));
-                               vty_out(vty, "Current prefix : %s\n", buf);
-                       }
+                       if (info->current_prefix)
+                               vty_out(vty, "Current prefix : %pFX\n",
+                                       info->current_prefix);
                }
        }
        vty_out(vty, "\n");