]> git.proxmox.com Git - mirror_frr.git/commitdiff
Merge pull request #7261 from Niral-Networks/niral_dev_vrf_ospf6
authorRafael Zalamena <rzalamena@users.noreply.github.com>
Tue, 3 Nov 2020 14:59:38 +0000 (11:59 -0300)
committerGitHub <noreply@github.com>
Tue, 3 Nov 2020 14:59:38 +0000 (11:59 -0300)
ospf6d : Transformation changes for ospf6 vrf support.

709 files changed:
.github/ISSUE_TEMPLATE/bug_report.md
alpine/APKBUILD.in
babeld/babel_filter.c
babeld/babel_interface.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_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_mh.c
bgpd/bgp_evpn_mh.h
bgpd/bgp_evpn_private.h
bgpd/bgp_evpn_vty.c
bgpd/bgp_evpn_vty.h
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_mplsvpn.c
bgpd/bgp_nb.c
bgpd/bgp_nb.h
bgpd/bgp_nb_config.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.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/index.rst
doc/developer/tracing.rst [new file with mode: 0644]
doc/user/bgp.rst
doc/user/installation.rst
doc/user/isisd.rst
doc/user/ospfd.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_cli.c
isisd/isis_dr.c
isisd/isis_events.c
isisd/isis_ldp_sync.c
isisd/isis_lfa.c
isisd/isis_lfa.h
isisd/isis_lsp.c
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
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/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_group.c
lib/northbound.c
lib/northbound.h
lib/northbound_cli.c
lib/northbound_confd.c
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/netlink_arp.c
nhrpd/nhrp_interface.c
nhrpd/nhrp_nhs.c
nhrpd/nhrp_route.c
nhrpd/nhrp_shortcut.c
ospf6d/ospf6_abr.c
ospf6d/ospf6_area.c
ospf6d/ospf6_asbr.c
ospf6d/ospf6_bfd.c
ospf6d/ospf6_interface.c
ospf6d/ospf6_intra.c
ospf6d/ospf6_lsa.h
ospf6d/ospf6_lsdb.c
ospf6d/ospf6_message.c
ospf6d/ospf6_network.c
ospf6d/ospf6_network.h
ospf6d/ospf6_route.c
ospf6d/ospf6_spf.c
ospf6d/ospf6_top.c
ospf6d/ospf6_zebra.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
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_network.c
ospfd/ospf_nsm.c
ospfd/ospf_nsm.h
ospfd/ospf_opaque.c
ospfd/ospf_opaque.h
ospfd/ospf_packet.c
ospfd/ospf_ri.c
ospfd/ospf_route.c
ospfd/ospf_snmp.c
ospfd/ospf_spf.c
ospfd/ospf_sr.c
ospfd/ospf_te.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospfd.c
ospfd/ospfd.h
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_igmp.c
pimd/pim_igmp_mtrace.c
pimd/pim_igmpv3.c
pimd/pim_mlag.c
pimd/pim_msdp.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
redhat/frr.spec.in
ripd/rip_interface.c
ripd/rip_peer.c
ripd/rip_zebra.c
ripd/ripd.c
ripd/ripd.h
ripngd/ripng_interface.c
ripngd/ripng_peer.c
ripngd/ripngd.c
ripngd/ripngd.h
sharpd/sharp_nht.c
sharpd/sharp_vty.c
staticd/static_vty.c
staticd/static_zebra.c
tests/bgpd/test_bgp_table.c
tests/isisd/test_isis_spf.c
tests/isisd/test_isis_spf.refout
tests/lib/cli/test_cli.c
tests/lib/test_srcdest_table.c
tests/lib/test_table.c
tests/lib/test_timer_correctness.c
tests/lib/test_timer_performance.c
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/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_aggregate_address_topo1/peer1/exabgp.cfg
tests/topotests/bgp_aggregate_address_topo1/r1/bgpd.conf
tests/topotests/bgp_aggregate_address_topo1/test_bgp_aggregate_address_topo1.py
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/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/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/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/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/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/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/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/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/step3/show_ip_route.ref
tests/topotests/isis-sr-topo1/rt5/step3/show_mpls_table.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/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/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-tilfa-topo1/rt1/step4/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step4/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step4/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step5/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step5/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step5/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step7/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step7/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step7/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step8/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step8/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step8/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step9/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step9/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt1/step9/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step1/show_ip_route.ref
tests/topotests/isis-tilfa-topo1/rt2/step1/show_ipv6_route.ref
tests/topotests/isis-tilfa-topo1/rt2/step1/show_mpls_table.ref
tests/topotests/isis-tilfa-topo1/rt2/step2/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step2/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step2/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step3/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step3/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step3/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step4/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step4/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step4/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step5/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step5/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step5/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step7/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step7/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step7/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step8/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step8/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step8/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step9/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step9/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt2/step9/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step1/show_ip_route.ref
tests/topotests/isis-tilfa-topo1/rt3/step1/show_ipv6_route.ref
tests/topotests/isis-tilfa-topo1/rt3/step1/show_mpls_table.ref
tests/topotests/isis-tilfa-topo1/rt3/step4/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step4/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step4/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step5/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step5/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step5/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step6/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step6/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step6/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step7/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step7/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step7/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step8/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step8/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step8/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step9/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step9/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt3/step9/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step1/show_ip_route.ref
tests/topotests/isis-tilfa-topo1/rt4/step1/show_ipv6_route.ref
tests/topotests/isis-tilfa-topo1/rt4/step1/show_mpls_table.ref
tests/topotests/isis-tilfa-topo1/rt4/step4/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step4/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step4/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step5/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step5/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step5/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step6/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step6/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step6/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step7/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step7/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step7/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step8/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step8/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step8/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt4/step9/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step1/show_ip_route.ref
tests/topotests/isis-tilfa-topo1/rt5/step1/show_ipv6_route.ref
tests/topotests/isis-tilfa-topo1/rt5/step1/show_mpls_table.ref
tests/topotests/isis-tilfa-topo1/rt5/step4/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step4/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step4/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step5/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step5/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step5/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt5/step6/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step1/show_ip_route.ref
tests/topotests/isis-tilfa-topo1/rt6/step1/show_ipv6_route.ref
tests/topotests/isis-tilfa-topo1/rt6/step1/show_mpls_table.ref
tests/topotests/isis-tilfa-topo1/rt6/step4/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step4/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step4/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step5/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step5/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step5/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step6/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step6/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step6/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step7/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step7/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step7/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step8/show_ip_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step8/show_ipv6_route.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step8/show_mpls_table.ref.diff
tests/topotests/isis-tilfa-topo1/rt6/step9/show_mpls_table.ref.diff
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/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
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/gen_northbound_callbacks.c
tools/gen_yang_deviations.c
watchfrr/watchfrr.c
yang/frr-bgp-common.yang
yang/frr-bgp.yang
yang/frr-isisd.yang
yang/frr-nexthop.yang
yang/frr-route-types.yang
zebra/connected.c
zebra/if_netlink.c
zebra/interface.c
zebra/interface.h
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_mpls.c
zebra/zebra_mroute.c
zebra/zebra_nb_config.c
zebra/zebra_netns_notify.c
zebra/zebra_nhg.c
zebra/zebra_nhg.h
zebra/zebra_ptm.c
zebra/zebra_pw.c
zebra/zebra_rib.c
zebra/zebra_rnh.c
zebra/zebra_routemap.c
zebra/zebra_router.h
zebra/zebra_vrf.c
zebra/zebra_vty.c
zebra/zebra_vxlan.c
zebra/zserv.c

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 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 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 7f9ef0c9cdbf4cdb0f2c97156f9f613b8ade646c..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"
@@ -702,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);
 }
@@ -1032,19 +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 *)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
@@ -1311,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));
@@ -1459,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 {
@@ -1719,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) {
@@ -2000,18 +1995,17 @@ 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. */
@@ -2390,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. */
@@ -2481,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;
 }
@@ -2582,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. */
@@ -2620,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);
@@ -2851,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;
@@ -2880,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;
@@ -2941,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;
@@ -3114,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;
 
@@ -3140,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;
                }
@@ -4101,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 */
@@ -4173,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
@@ -4967,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);
 }
index 6fb5a44208b6ffae101901ae28c9912a190b41f0..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);
@@ -109,9 +114,10 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
            && !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(dest);
@@ -138,8 +144,9 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
 
        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)
@@ -362,10 +369,9 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
         */
        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;
        }
 
@@ -420,13 +426,13 @@ static int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
 
        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. */
@@ -467,12 +473,13 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es,
                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)
@@ -506,8 +513,10 @@ static int bgp_evpn_mh_route_delete(struct bgp *bgp, struct bgp_evpn_es *es,
 
 /*****************************************************************************
  * 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,
@@ -515,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;
 
@@ -540,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);
 }
 
@@ -574,12 +592,11 @@ static int bgp_evpn_type4_route_update(struct bgp *bgp,
        /* Create or update route entry. */
        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 %s",
-                               bgp->vrf_id, es->esi_str,
-                               inet_ntoa(es->originator_ip));
-       }
+       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;
@@ -697,7 +714,6 @@ 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_dest *rd_dest, *dest;
        struct bgp_table *table;
        struct bgp_path_info *pi;
@@ -742,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;
                                }
                        }
@@ -877,12 +891,12 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
                /* Create or update route entry. */
                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 %s",
-                                       bgp->vrf_id, es->esi_str, vpn->vni,
-                                       inet_ntoa(es->originator_ip));
-               }
+               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 */
@@ -900,10 +914,10 @@ static int bgp_evpn_type1_route_update(struct bgp *bgp,
                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;
        }
@@ -1142,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)
@@ -1155,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);
 
@@ -1163,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;
@@ -1191,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);
 
@@ -1218,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;
 }
@@ -1236,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);
 }
 
@@ -1319,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);
@@ -1353,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);
 }
 
@@ -1371,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 */
@@ -1382,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__);
                }
        }
 }
@@ -1428,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)
@@ -1511,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);
@@ -1533,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 */
@@ -1556,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);
 
@@ -1570,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)
@@ -1585,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);
@@ -1594,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();
@@ -1617,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)
 {
@@ -1686,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);
@@ -1702,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)
@@ -1718,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';
@@ -1727,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
@@ -1739,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);
@@ -1756,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");
        }
 }
@@ -1919,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) {
@@ -1955,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);
@@ -1980,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);
@@ -2296,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) {
@@ -2319,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;
                }
        }
@@ -2348,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)
@@ -2405,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)) {
@@ -2420,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);
@@ -2434,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();
@@ -2898,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 611566201eedf4d306fff85ab9838274a91deac8..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)
 {
index 2e1e9d635f8e12828954cf570225810866be33dc..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",
@@ -825,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;
@@ -848,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));
@@ -861,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)));
@@ -950,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;
@@ -980,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
@@ -1094,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;
@@ -1185,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",
@@ -3986,12 +4001,40 @@ 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
@@ -3999,20 +4042,10 @@ DEFUN(show_bgp_l2vpn_evpn_route,
       EVPN_RT_HELP_STR
       "Display Detailed Information\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
-      EVPN_TYPE_4_HELP_STR
-      EVPN_TYPE_4_HELP_STR
-      EVPN_TYPE_5_HELP_STR
-      EVPN_TYPE_5_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;
@@ -4027,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;
@@ -4067,7 +4081,7 @@ 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
@@ -4076,11 +4090,7 @@ DEFUN(show_bgp_l2vpn_evpn_route_rd,
       EVPN_RT_DIST_HELP_STR
       EVPN_ASN_IP_HELP_STR
       EVPN_TYPE_HELP_STR
-      EVPN_TYPE_1_HELP_STR
-      EVPN_TYPE_2_HELP_STR
-      EVPN_TYPE_3_HELP_STR
-      EVPN_TYPE_4_HELP_STR
-      EVPN_TYPE_5_HELP_STR
+      EVPN_TYPE_ALL_LIST_HELP_STR
       JSON_STR)
 {
        struct bgp *bgp;
@@ -4088,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;
 
@@ -4111,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);
 
@@ -4266,7 +4261,7 @@ 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
@@ -4276,7 +4271,10 @@ DEFUN(show_bgp_l2vpn_evpn_route_vni, show_bgp_l2vpn_evpn_route_vni_cmd,
       "VNI number\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"
@@ -4287,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;
 
@@ -4306,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);
@@ -4641,7 +4630,8 @@ DEFPY_HIDDEN(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;
@@ -4702,23 +4692,27 @@ 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_RT_HELP_STR
             "Display Detailed Information\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_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(
@@ -4735,13 +4729,15 @@ 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_RT_HELP_STR
        "VXLAN Network Identifier\n"
        "VNI number\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")
@@ -5071,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;
@@ -5106,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)));
@@ -5135,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",
@@ -5298,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;
@@ -5306,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;
@@ -5327,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;
 }
 
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 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 aa98515c3f041c386029d1ad41da6e4f8686737b..b9156df617abf14e21d43cb570f3955d685f8613 100644 (file)
@@ -31,7 +31,7 @@
 
 #define BGP_TIMER_OFF(T)                                                       \
        do {                                                                   \
-               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 d0a32ee408199c8aa2a4af9f144e79d5a9624452..21c880e95b2b79133f1130f588b87981373b9844 100644 (file)
@@ -62,6 +62,7 @@
 #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"
@@ -207,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();
 
index 67885cbf7ecdef9ef3829e64cc1871e2cfbc28ce..0c527efb8c4992fa26e70961deae8c53ba129e4e 100644 (file)
@@ -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;
@@ -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 551bdb0c2b895255f313d58776c8740f77e3e704..333ca3cce9cafd0daf9a7885fa87fb624eb6e1d7 100644 (file)
@@ -458,6 +458,8 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1279,8 +1281,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1306,8 +1310,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1329,11 +1335,32 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
                        }
                },
                {
@@ -1349,6 +1376,13 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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 = {
@@ -1387,6 +1421,14 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1405,8 +1447,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1423,25 +1467,29 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy,
                        }
                },
                {
@@ -1456,6 +1504,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1477,18 +1526,21 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1496,6 +1548,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1503,6 +1556,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1510,6 +1564,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1543,8 +1598,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1570,8 +1627,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1593,11 +1652,32 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
                        }
                },
                {
@@ -1613,10 +1693,59 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
                        }
                },
                {
@@ -1635,8 +1764,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1653,25 +1784,29 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy,
                        }
                },
                {
@@ -1733,6 +1868,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1740,6 +1876,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1774,6 +1911,14 @@ const struct frr_yang_module_info frr_bgp_info = {
                        .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,
                        }
                },
                {
@@ -1789,10 +1934,59 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
                        }
                },
                {
@@ -1808,11 +2002,54 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
                        }
                },
                {
@@ -1838,6 +2075,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
@@ -1861,32 +2099,76 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy,
+                       }
+               },
+               {
+                       .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,
                        }
                },
                {
@@ -1933,8 +2215,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
@@ -1960,6 +2244,7 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
@@ -1983,32 +2268,110 @@ const struct frr_yang_module_info frr_bgp_info = {
                                .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy,
                        }
                },
                {
                        .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,
-                               .destroy = bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_destroy,
                        }
                },
                {
@@ -2021,8 +2384,10 @@ const struct frr_yang_module_info frr_bgp_info = {
                {
                        .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,
                        }
                },
                {
index 341666c7ed654af6a61465d06a26ced21e55163a..532021425fafc9d7dc1954ba55f98be4a05e0e4c 100644 (file)
@@ -568,6 +568,14 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_expor
        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(
@@ -618,16 +626,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_i
        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_external_destroy(
-       struct nb_cb_destroy_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_internal_destroy(
-       struct nb_cb_destroy_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_admin_distance_local_destroy(
-       struct nb_cb_destroy_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(
@@ -706,6 +708,14 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_expor
        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(
@@ -716,6 +726,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_
        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(
@@ -738,16 +766,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i
        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_external_destroy(
-       struct nb_cb_destroy_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_internal_destroy(
-       struct nb_cb_destroy_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_admin_distance_local_destroy(
-       struct nb_cb_destroy_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(
@@ -808,6 +830,26 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_c
        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(
@@ -816,6 +858,24 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_c
        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(
@@ -842,22 +902,30 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_exp
        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_external_modify(
+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_external_destroy(
+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_internal_destroy(
-       struct nb_cb_destroy_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_admin_distance_local_destroy(
-       struct nb_cb_destroy_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(
@@ -906,22 +974,48 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_exp
        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_external_modify(
+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_external_destroy(
+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_admin_distance_internal_modify(
+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_admin_distance_internal_destroy(
+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_admin_distance_local_modify(
+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_admin_distance_local_destroy(
+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(
@@ -3421,10 +3515,68 @@ void cli_show_router_bgp_graceful_shutdown(struct vty *vty,
                                           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 */
@@ -3437,5 +3589,8 @@ void bgp_global_med_config_apply_finish(struct nb_cb_apply_finish_args *args);
        "/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
index f01325577c4d054978af3db563d2673f51ba7ab0..66dfa2aea7bb967008f690cf52f82badeea83a7f 100644 (file)
@@ -30,6 +30,7 @@
 #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", },
@@ -244,7 +245,6 @@ int bgp_global_local_as_modify(struct nb_cb_modify_args *args)
                                 bgp->as);
                        return NB_ERR_INCONSISTENCY;
                }
-
                break;
        }
 
@@ -509,7 +509,7 @@ int bgp_global_med_config_max_med_onstart_up_time_destroy(
 
                /* Cancel max-med onstartup if its on */
                if (bgp->t_maxmed_onstartup) {
-                       THREAD_TIMER_OFF(bgp->t_maxmed_onstartup);
+                       THREAD_OFF(bgp->t_maxmed_onstartup);
                        bgp->maxmed_onstartup_over = 1;
                }
 
@@ -2042,8 +2042,30 @@ int bgp_global_bmp_config_mirror_buffer_limit_destroy(
  */
 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:
@@ -5483,47 +5505,202 @@ int bgp_peer_groups_peer_group_afi_safis_afi_safi_enabled_modify(
        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:
-               /* TODO: implement me. */
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
+
                break;
        }
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
-               /* TODO: implement me. */
                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/backdoor
+ * /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_backdoor_modify(
+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:
@@ -5536,12 +5713,82 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_backdoor_modify(
        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/network-config/label-index
+ * /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_network_config_label_index_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -5555,16 +5802,16 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_modify
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_aggregate_route_destroy(args);
        }
 
        return NB_OK;
@@ -5572,9 +5819,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_label_index_destro
 
 /*
  * 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
+ * /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_network_config_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_as_set_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -5589,8 +5836,12 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -5606,10 +5857,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_network_config_rmap_policy_export
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route
+ * /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_create(
-       struct nb_cb_create_args *args)
+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:
@@ -5623,7 +5874,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -5640,9 +5891,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/aggregate-route/as-set
+ * /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_as_set_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_origin_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -5659,9 +5910,9 @@ int 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
+ * /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_summary_only_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_match_med_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -5678,9 +5929,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_summary_only_modi
 
 /*
  * 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
+ * /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_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -5695,7 +5946,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_expor
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_suppress_map_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -5710,6 +5961,60 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_aggregate_route_rmap_policy_expor
        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
@@ -5736,9 +6041,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_destroy(
        case NB_EV_VALIDATE:
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
        }
 
        return NB_OK;
@@ -5797,6 +6102,68 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_route_access_list_
        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
@@ -5806,10 +6173,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_enable_modif
 {
        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:
-               /* TODO: implement me. */
                break;
        }
 
@@ -5857,8 +6224,22 @@ int 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_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:
@@ -5952,6 +6333,45 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_deca
        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
@@ -5959,13 +6379,24 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_route_flap_dampening_unreach_deca
 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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
        }
 
        return NB_OK;
@@ -5973,17 +6404,68 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ebgp_maximum_p
 
 /*
  * 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
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/use-multiple-paths/ibgp
  */
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
-       struct nb_cb_modify_args *args)
+void bgp_global_afi_safi_ip_unicast_use_multiple_paths_ibgp_maximum_paths_apply_finish(
+       struct nb_cb_apply_finish_args *args)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
+       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:
-               /* TODO: implement me. */
                break;
        }
 
@@ -6024,6 +6506,49 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_use_multiple_paths_ibgp_cluster_l
        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
@@ -6045,6 +6570,1279 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_create(
 
 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:
@@ -6060,10 +7858,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/redistribution-list/metric
+ * /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_ipv4_unicast_redistribution_list_metric_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -6077,16 +7875,16 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_modify
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_aggregate_route_destroy(args);
        }
 
        return NB_OK;
@@ -6094,9 +7892,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_metric_destro
 
 /*
  * 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
+ * /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_ipv4_unicast_redistribution_list_rmap_policy_import_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_as_set_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6111,8 +7909,12 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_i
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_import_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -6128,9 +7930,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_redistribution_list_rmap_policy_i
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/external
+ * /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_ipv4_unicast_admin_distance_external_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6145,7 +7947,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_export_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6162,9 +7964,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_external_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/internal
+ * /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_ipv4_unicast_admin_distance_internal_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_origin_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6179,8 +7981,12 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -6196,9 +8002,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_internal_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/admin-distance/local
+ * /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_ipv4_unicast_admin_distance_local_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6213,7 +8019,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_suppress_map_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6230,10 +8036,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_admin_distance_local_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/filter-config/rmap-export
+ * /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_ipv4_unicast_filter_config_rmap_export_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -6247,16 +8053,16 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_filter_config_rmap_export_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
        }
 
        return NB_OK;
@@ -6264,9 +8070,9 @@ int 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
+ * /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_ipv4_unicast_vpn_config_rd_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6281,8 +8087,12 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -6296,12 +8106,8 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rd_destroy(
        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)
+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:
@@ -6315,15 +8121,19 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
-               /* TODO: implement me. */
                break;
        }
 
@@ -6332,9 +8142,9 @@ int 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
+ * /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_ipv4_unicast_vpn_config_label_auto_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6349,7 +8159,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_label_auto_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reach_decay_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6366,13 +8176,27 @@ int 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
+ * /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_ipv4_unicast_vpn_config_nexthop_modify(
+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:
@@ -6383,7 +8207,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_reuse_above_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6400,9 +8224,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_nexthop_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/import-vpn
+ * /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_ipv4_unicast_vpn_config_import_vpn_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_suppress_above_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6417,12 +8241,8 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vpn_modify(
        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)
+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:
@@ -6438,10 +8258,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_vpn_modify(
 
 /*
  * 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
+ * /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_ipv4_unicast_vpn_config_import_vrf_list_create(
-       struct nb_cb_create_args *args)
+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:
@@ -6455,7 +8275,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_create
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_route_flap_dampening_unreach_decay_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6472,25 +8292,40 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_vrf_list_destro
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-import
+ * /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_ipv4_unicast_vpn_config_rmap_import_modify(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
        }
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -6506,9 +8341,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_import_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-unicast/vpn-config/rmap-export
+ * /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_ipv4_unicast_vpn_config_rmap_export_modify(
+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) {
@@ -6523,7 +8358,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rmap_export_destroy(
+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) {
@@ -6540,10 +8375,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_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/redirect-rt
+ * /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_ipv4_unicast_vpn_config_redirect_rt_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -6557,15 +8392,34 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_redirect_rt_destroy(
+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:
-               /* TODO: implement me. */
+               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;
        }
 
@@ -6574,10 +8428,10 @@ int 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
+ * /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_ipv4_unicast_vpn_config_import_rt_list_create(
-       struct nb_cb_create_args *args)
+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:
@@ -6591,7 +8445,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_import_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6608,10 +8462,10 @@ int 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
+ * /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_ipv4_unicast_vpn_config_export_rt_list_create(
-       struct nb_cb_create_args *args)
+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:
@@ -6625,7 +8479,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_export_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6642,44 +8496,56 @@ int 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
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance
  */
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_create(
-       struct nb_cb_create_args *args)
+void bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       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;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_unicast_vpn_config_rt_list_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       /* 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/network-config
+ * /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_network_config_create(
-       struct nb_cb_create_args *args)
+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:
@@ -6693,7 +8559,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6710,18 +8576,54 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/network-config/backdoor
+ * /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_network_config_backdoor_modify(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rd_destroy(
+                       args);
        }
 
        return NB_OK;
@@ -6729,9 +8631,9 @@ int 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
+ * /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_network_config_label_index_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6746,7 +8648,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_modify
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6763,9 +8665,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_label_index_destro
 
 /*
  * 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
+ * /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_network_config_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6780,7 +8682,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6797,33 +8699,54 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_network_config_rmap_policy_export
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route
+ * /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_aggregate_route_create(
-       struct nb_cb_create_args *args)
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_modify(
+                       args);
        }
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_vpn_config_nexthop_destroy(
+                       args);
        }
 
        return NB_OK;
@@ -6831,9 +8754,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/aggregate-route/as-set
+ * /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_aggregate_route_as_set_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6850,9 +8773,9 @@ int 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
+ * /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_aggregate_route_summary_only_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_vpn_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6869,33 +8792,53 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_summary_only_modi
 
 /*
  * 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
+ * /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_aggregate_route_rmap_policy_export_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)
 {
+       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:
-               /* TODO: implement me. */
-               break;
+               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_aggregate_route_rmap_policy_export_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_vpn_config_import_vrf_list_destroy(
+                       args);
        }
 
        return NB_OK;
@@ -6903,33 +8846,35 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_aggregate_route_rmap_policy_expor
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route
+ * /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_admin_distance_route_create(
-       struct nb_cb_create_args *args)
+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:
-               /* TODO: implement me. */
-               break;
+               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_admin_distance_route_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_vpn_config_rmap_import_destroy(
+                       args, "import");
        }
 
        return NB_OK;
@@ -6937,18 +8882,35 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance-route/distance
+ * /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_admin_distance_route_distance_modify(
+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:
-               /* TODO: implement me. */
-               break;
+               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;
@@ -6956,9 +8918,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_distance_mod
 
 /*
  * 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
+ * /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_admin_distance_route_access_list_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -6973,7 +8935,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -6990,10 +8952,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_route_access_list_
 
 /*
  * 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
+ * /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_use_multiple_paths_ebgp_maximum_paths_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -7007,12 +8969,8 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ebgp_maximum_p
        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)
+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:
@@ -7028,10 +8986,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_maximum_p
 
 /*
  * 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
+ * /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_use_multiple_paths_ibgp_cluster_length_list_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -7045,7 +9003,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_l
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7062,9 +9020,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_use_multiple_paths_ibgp_cluster_l
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list
+ * /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_redistribution_list_create(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create(
        struct nb_cb_create_args *args)
 {
        switch (args->event) {
@@ -7079,7 +9037,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7096,25 +9054,40 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/redistribution-list/metric
+ * /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_ipv6_unicast_redistribution_list_metric_modify(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
        }
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -7130,9 +9103,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_metric_destro
 
 /*
  * 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
+ * /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_ipv6_unicast_redistribution_list_rmap_policy_import_modify(
+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) {
@@ -7147,7 +9120,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_import_destroy(
+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) {
@@ -7164,32 +9137,17 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_redistribution_list_rmap_policy_i
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/external
+ * /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_ipv6_unicast_admin_distance_external_modify(
+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:
-               /* TODO: implement me. */
-               break;
-       }
-
-       return NB_OK;
-}
-
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy(
-       struct nb_cb_destroy_args *args)
-{
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
                break;
        }
 
@@ -7198,9 +9156,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_external_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/internal
+ * /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_ipv6_unicast_admin_distance_internal_modify(
+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) {
@@ -7215,7 +9173,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy(
+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) {
@@ -7232,9 +9190,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_internal_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/admin-distance/local
+ * /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_ipv6_unicast_admin_distance_local_modify(
+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) {
@@ -7249,7 +9207,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy(
+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) {
@@ -7266,9 +9224,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_admin_distance_local_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/filter-config/rmap-export
+ * /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_ipv6_unicast_filter_config_rmap_export_modify(
+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) {
@@ -7283,7 +9241,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_filter_config_rmap_export_destroy(
+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) {
@@ -7300,9 +9258,9 @@ int 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
+ * /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_ipv6_unicast_vpn_config_rd_modify(
+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) {
@@ -7317,7 +9275,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rd_destroy(
+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) {
@@ -7334,28 +9292,53 @@ int 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
+ * /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_unicast_vpn_config_label_modify(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_ip_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+                       args);
        }
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -7368,9 +9351,9 @@ int 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
+ * /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_unicast_vpn_config_label_auto_modify(
+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) {
@@ -7385,7 +9368,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_label_auto_destroy(
+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) {
@@ -7402,32 +9385,17 @@ int 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
+ * /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_unicast_vpn_config_nexthop_modify(
+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:
-               /* TODO: implement me. */
-               break;
-       }
-
-       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:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
                break;
        }
 
@@ -7436,9 +9404,9 @@ int 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
+ * /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_unicast_vpn_config_import_vpn_modify(
+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) {
@@ -7453,12 +9421,8 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vpn_modify(
        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)
+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:
@@ -7474,10 +9438,10 @@ int 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
+ * /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_unicast_vpn_config_import_vrf_list_create(
-       struct nb_cb_create_args *args)
+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:
@@ -7491,7 +9455,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_create
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destroy(
+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) {
@@ -7508,9 +9472,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_vrf_list_destro
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-import
+ * /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_unicast_vpn_config_rmap_import_modify(
+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) {
@@ -7525,7 +9489,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy(
+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) {
@@ -7542,9 +9506,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_import_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-unicast/vpn-config/rmap-export
+ * /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_unicast_vpn_config_rmap_export_modify(
+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) {
@@ -7559,7 +9523,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rmap_export_destroy(
+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) {
@@ -7576,25 +9540,39 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_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/redirect-rt
+ * /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_ipv6_unicast_vpn_config_redirect_rt_modify(
-       struct nb_cb_modify_args *args)
+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:
-               /* TODO: implement me. */
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
                break;
        }
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_redirect_rt_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -7610,10 +9588,10 @@ int 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
+ * /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_ipv6_unicast_vpn_config_import_rt_list_create(
-       struct nb_cb_create_args *args)
+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:
@@ -7627,7 +9605,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_import_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7644,10 +9622,10 @@ int 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
+ * /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_ipv6_unicast_vpn_config_export_rt_list_create(
-       struct nb_cb_create_args *args)
+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:
@@ -7661,7 +9639,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_export_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7678,9 +9656,9 @@ int 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
+ * /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_ipv6_unicast_vpn_config_rt_list_create(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create(
        struct nb_cb_create_args *args)
 {
        switch (args->event) {
@@ -7695,7 +9673,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_unicast_vpn_config_rt_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7712,9 +9690,9 @@ int 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
+ * /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_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7731,9 +9709,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ebgp_m
 
 /*
  * 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
+ * /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_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7750,9 +9728,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_m
 
 /*
  * 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
+ * /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_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7767,7 +9745,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_c
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7784,9 +9762,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_labeled_unicast_use_multiple_paths_ibgp_c
 
 /*
  * 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
+ * /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_ipv6_labeled_unicast_use_multiple_paths_ebgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_origin_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7803,9 +9781,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ebgp_m
 
 /*
  * 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
+ * /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_ipv6_labeled_unicast_use_multiple_paths_ibgp_maximum_paths_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_match_med_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7822,9 +9800,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_m
 
 /*
  * 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
+ * /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_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7839,7 +9817,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_c
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_cluster_length_list_destroy(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_suppress_map_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -7856,9 +9834,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_labeled_unicast_use_multiple_paths_ibgp_c
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config
+ * /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_network_config_create(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create(
        struct nb_cb_create_args *args)
 {
        switch (args->event) {
@@ -7873,16 +9851,16 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
        }
 
        return NB_OK;
@@ -7890,9 +9868,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/network-config/backdoor
+ * /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_network_config_backdoor_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_distance_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7909,9 +9887,9 @@ int 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
+ * /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_network_config_label_index_modify(
+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) {
@@ -7926,7 +9904,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_modi
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_destroy(
+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) {
@@ -7943,9 +9921,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_label_index_dest
 
 /*
  * 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
+ * /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_ipv4_multicast_network_config_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_distance_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -7960,8 +9938,12 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_expo
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_export_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -7975,12 +9957,8 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_network_config_rmap_policy_expo
        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)
+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:
@@ -7994,15 +9972,19 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
-               /* TODO: implement me. */
                break;
        }
 
@@ -8011,9 +9993,9 @@ int 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
+ * /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_ipv4_multicast_aggregate_route_as_set_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reach_decay_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -8028,12 +10010,8 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_as_set_modify(
        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)
+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:
@@ -8049,9 +10027,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_summary_only_mo
 
 /*
  * 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
+ * /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_ipv4_multicast_aggregate_route_rmap_policy_export_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -8066,7 +10044,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_exp
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_export_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_reuse_above_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -8083,10 +10061,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_aggregate_route_rmap_policy_exp
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance-route
+ * /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_ipv4_multicast_admin_distance_route_create(
-       struct nb_cb_create_args *args)
+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:
@@ -8100,7 +10078,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_suppress_above_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -8117,9 +10095,9 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_route_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/external
+ * /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_ipv4_multicast_admin_distance_external_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -8134,7 +10112,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_route_flap_dampening_unreach_decay_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -8151,68 +10129,46 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_external_destroy
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance/internal
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance
  */
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
-       struct nb_cb_modify_args *args)
+void bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_apply_finish(
+       struct nb_cb_apply_finish_args *args)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
-
-       return NB_OK;
+       bgp_global_afi_safis_admin_distance_modify(args);
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_destroy(
-       struct nb_cb_destroy_args *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)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       /* 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
+ * /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_local_modify(
+int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_internal_modify(
        struct nb_cb_modify_args *args)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       /* Handled in admin_distance_apply_finish callback */
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv4_multicast_admin_distance_local_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       /* Handled in admin_distance_apply_finish callback */
 
        return NB_OK;
 }
@@ -8226,10 +10182,10 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_route_flap_dampening_enable_mod
 {
        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:
-               /* TODO: implement me. */
                break;
        }
 
@@ -8413,14 +10369,7 @@ int bgp_global_afi_safis_afi_safi_ipv4_multicast_filter_config_rmap_export_destr
 int bgp_global_afi_safis_afi_safi_ipv6_multicast_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;
-       }
+       /* Handled in network_config_apply_finish callback */
 
        return NB_OK;
 }
@@ -8432,8 +10381,11 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_network_config_destroy(
        case NB_EV_VALIDATE:
        case NB_EV_PREPARE:
        case NB_EV_ABORT:
+               return NB_OK;
        case NB_EV_APPLY:
-               /* TODO: implement me. */
+               return bgp_global_afi_safis_afi_safi_network_config_destroy(
+                       args);
+
                break;
        }
 
@@ -8635,10 +10587,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_rmap_policy_exp
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance-route
+ * /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_admin_distance_route_create(
-       struct nb_cb_create_args *args)
+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:
@@ -8652,8 +10604,12 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_create(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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:
@@ -8669,9 +10625,9 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_route_destroy(
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/external
+ * /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_admin_distance_external_modify(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_modify(
        struct nb_cb_modify_args *args)
 {
        switch (args->event) {
@@ -8686,7 +10642,7 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy(
+int bgp_global_afi_safis_afi_safi_ipv6_multicast_aggregate_route_suppress_map_destroy(
        struct nb_cb_destroy_args *args)
 {
        switch (args->event) {
@@ -8703,10 +10659,10 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_external_destroy
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/internal
+ * /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_internal_modify(
-       struct nb_cb_modify_args *args)
+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:
@@ -8720,16 +10676,16 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_modify(
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy(
+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:
-               /* TODO: implement me. */
-               break;
+               return bgp_global_afi_safi_admin_distance_route_destroy(args);
        }
 
        return NB_OK;
@@ -8737,34 +10693,46 @@ int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_internal_destroy
 
 /*
  * XPath:
- * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv6-multicast/admin-distance/local
+ * /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-bgp:bgp/global/afi-safis/afi-safi/ipv4-multicast/admin-distance
  */
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_modify(
+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)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       /* Handled in admin_distance_apply_finish callback */
 
        return NB_OK;
 }
 
-int bgp_global_afi_safis_afi_safi_ipv6_multicast_admin_distance_local_destroy(
-       struct nb_cb_destroy_args *args)
+/*
+ * 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)
 {
-       switch (args->event) {
-       case NB_EV_VALIDATE:
-       case NB_EV_PREPARE:
-       case NB_EV_ABORT:
-       case NB_EV_APPLY:
-               /* TODO: implement me. */
-               break;
-       }
+       /* 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;
 }
index 6cd38ec78f7ffe6a075b3c5858d4669b4b7173c3..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;
        }
 
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 73f5526fe254da2b2122f69ed2a6988975695721..566c5911e0222604ba2772bae17e9f5815ed1f5a 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;
@@ -723,18 +735,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;
                }
        }
@@ -1288,6 +1300,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 +1312,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;
+               }
+       }
+
+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 FILTER_PERMIT;
+       return ret;
 #undef FILTER_EXIST_WARN
 }
 
@@ -1328,6 +1358,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 +1370,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;
+               }
+       }
+
+       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");
        }
 
-       return FILTER_PERMIT;
+done:
+       return ret;
 #undef FILTER_EXIST_WARN
 }
 
@@ -1613,7 +1660,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 +1701,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;
@@ -1704,10 +1779,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
@@ -1944,7 +2017,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};
@@ -1969,7 +2043,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
@@ -2428,12 +2502,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],
@@ -2446,7 +2516,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,
@@ -2629,7 +2700,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;
        }
 
@@ -2937,18 +3008,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)
@@ -2968,7 +3042,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;
 
@@ -3025,13 +3099,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)
@@ -3427,6 +3501,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
@@ -4284,7 +4366,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);
 }
 
 /*
@@ -4308,6 +4390,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;
 }
 
@@ -4543,7 +4629,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];
@@ -4980,8 +5066,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;
                        }
                }
@@ -5535,28 +5621,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) {
@@ -5565,24 +5639,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. */
@@ -5603,8 +5678,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.  */
@@ -5666,7 +5742,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)
@@ -5742,9 +5818,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);
@@ -6116,25 +6192,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;
@@ -6147,27 +6225,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)
@@ -6177,11 +6330,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,
@@ -6376,13 +6637,11 @@ static bool bgp_aggregate_test_all_med(struct bgp_aggregate *aggregate,
  * Toggles the route suppression status for this aggregate address
  * configuration.
  */
-static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
-                                           struct bgp *bgp,
-                                           const struct prefix *p, afi_t afi,
-                                           safi_t safi, bool suppress)
+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];
-       struct bgp_path_info_extra *pie;
        const struct prefix *dest_p;
        struct bgp_dest *dest, *top;
        struct bgp_path_info *pi;
@@ -6403,32 +6662,17 @@ static void bgp_aggregate_toggle_suppressed(struct bgp_aggregate *aggregate,
                        if (pi->sub_type == BGP_ROUTE_AGGREGATE)
                                continue;
 
-                       /*
-                        * On installation it is possible that pi->extra is
-                        * set to NULL, otherwise it must exists.
-                        */
-                       assert(!suppress && pi->extra != NULL);
-
                        /* We are toggling suppression back. */
                        if (suppress) {
-                               pie = bgp_path_info_extra_get(pi);
                                /* Suppress route if not suppressed already. */
-                               pie->suppress++;
-                               bgp_path_info_set_flag(dest, pi,
-                                                      BGP_PATH_ATTR_CHANGED);
-                               toggle_suppression = true;
+                               if (aggr_suppress_path(aggregate, pi))
+                                       toggle_suppression = true;
                                continue;
                        }
 
-                       pie = pi->extra;
-                       assert(pie->suppress > 0);
-                       pie->suppress--;
                        /* Install route if there is no more suppression. */
-                       if (pie->suppress == 0) {
-                               bgp_path_info_set_flag(dest, pi,
-                                                      BGP_PATH_ATTR_CHANGED);
+                       if (aggr_unsuppress_path(aggregate, pi))
                                toggle_suppression = true;
-                       }
                }
 
                if (toggle_suppression)
@@ -6515,6 +6759,17 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
        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
@@ -6559,10 +6814,24 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
                         */
                        if (aggregate->summary_only
                            && AGGREGATE_MED_VALID(aggregate)) {
-                               (bgp_path_info_extra_get(pi))->suppress++;
-                               bgp_path_info_set_flag(dest, pi,
-                                                      BGP_PATH_ATTR_CHANGED);
-                               match++;
+                               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++;
@@ -6702,15 +6971,17 @@ void bgp_aggregate_delete(struct bgp *bgp, const struct prefix *p, afi_t afi,
 
                        if (aggregate->summary_only && pi->extra
                            && AGGREGATE_MED_VALID(aggregate)) {
-                               pi->extra->suppress--;
+                               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)
@@ -6801,7 +7072,11 @@ static void bgp_add_route_to_aggregate(struct bgp *bgp,
                                         pinew, true);
 
        if (aggregate->summary_only && AGGREGATE_MED_VALID(aggregate))
-               (bgp_path_info_extra_get(pinew))->suppress++;
+               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:
@@ -6897,19 +7172,17 @@ 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
-           && AGGREGATE_MED_VALID(aggregate)) {
-               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` check to avoid
+        * This must be called after `summary`, `suppress-map` check to avoid
         * "unsuppressing" twice.
         */
        if (aggregate->match_med)
@@ -7077,35 +7350,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);
@@ -7166,48 +7429,53 @@ 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, bool match_med)
+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;
                }
        }
 
@@ -7230,7 +7498,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");
                }
        }
@@ -7252,39 +7521,55 @@ 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;
 }
 
-DEFPY(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"
-      "}",
-      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")
-{
-       const char *prefix_s = NULL;
+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);
-       uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
-       int as_set = AGGREGATE_AS_UNSET;
        char prefix_buf[PREFIX2STR_BUFFER];
 
        if (addr_str) {
@@ -7293,75 +7578,158 @@ DEFPY(aggregate_addressv4, aggregate_addressv4_cmd,
                        vty_out(vty, "%% Inconsistent address and mask\n");
                        return CMD_WARNING_CONFIG_FAILED;
                }
-               prefix_s = prefix_buf;
-       } else
-               prefix_s = prefix_str;
-
-       if (origin_s) {
-               if (strcmp(origin_s, "egp") == 0)
-                       origin = BGP_ORIGIN_EGP;
-               else if (strcmp(origin_s, "igp") == 0)
-                       origin = BGP_ORIGIN_IGP;
-               else if (strcmp(origin_s, "incomplete") == 0)
-                       origin = BGP_ORIGIN_INCOMPLETE;
+       } else {
+               strlcpy(prefix_buf, prefix_str, sizeof(prefix_buf));
        }
 
-       if (as_set_s)
-               as_set = AGGREGATE_AS_SET;
+       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);
+       else
+               nb_cli_enqueue_change(vty, "./rmap-policy-export",
+                                     NB_OP_DESTROY, NULL);
+
+       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);
+
+       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);
 
-       /* Handle configuration removal, otherwise installation. */
        if (no)
-               return bgp_aggregate_unset(vty, prefix_s, AFI_IP, safi);
-
-       return bgp_aggregate_set(vty, prefix_s, AFI_IP, safi, rmap_name,
-                                summary_only != NULL, as_set, origin,
-                                match_med != NULL);
-}
-
-DEFPY(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"
-      "}",
-      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")
-{
-       uint8_t origin = BGP_ORIGIN_UNSPECIFIED;
-       int as_set = AGGREGATE_AS_UNSET;
-
-       if (origin_s) {
-               if (strcmp(origin_s, "egp") == 0)
-                       origin = BGP_ORIGIN_EGP;
-               else if (strcmp(origin_s, "igp") == 0)
-                       origin = BGP_ORIGIN_IGP;
-               else if (strcmp(origin_s, "incomplete") == 0)
-                       origin = BGP_ORIGIN_INCOMPLETE;
-       }
-
-       if (as_set_s)
-               as_set = AGGREGATE_AS_SET;
-
-       /* Handle configuration removal, otherwise installation. */
+               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);
+
+       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)
-               return bgp_aggregate_unset(vty, prefix_str, AFI_IP6,
-                                          SAFI_UNICAST);
+               nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+       else
+               nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       return bgp_aggregate_set(vty, prefix_str, AFI_IP6, SAFI_UNICAST,
-                                rmap_name, summary_only != NULL, as_set,
-                                origin, match_med != NULL);
+       return nb_cli_apply_changes(vty, base_xpath);
+}
+
+void cli_show_bgp_global_afi_safi_unicast_aggregate_route(
+       struct vty *vty, struct lyd_node *dnode, bool show_defaults)
+{
+       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. */
@@ -7617,13 +7985,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, "%pFX", p);
        } else if (p->family == AF_EVPN) {
                if (!json)
-                       len = vty_out(vty, "%s",
-                                     prefix2str((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) {
@@ -7672,7 +8037,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)
@@ -7709,7 +8074,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))
@@ -7879,10 +8244,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,
@@ -7910,13 +8279,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(
@@ -7946,10 +8318,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,
@@ -8257,18 +8633,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];
@@ -8278,11 +8660,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))
@@ -8310,15 +8697,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];
@@ -8403,22 +8787,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)))
@@ -8927,7 +9316,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;
@@ -8965,7 +9353,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,
@@ -8974,10 +9361,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                }
                if (safi == SAFI_EVPN) {
                        if (!json_paths) {
-                               prefix2str((struct prefix_evpn *)
-                                                  bgp_dest_get_prefix(bn),
-                                          buf2, sizeof(buf2));
-                               vty_out(vty, "  Route %s", buf2);
+                               vty_out(vty, "  Route %pFX",
+                                       (struct prefix_evpn *)
+                                               bgp_dest_get_prefix(bn));
                                if (tag_buf[0] != '\0')
                                        vty_out(vty, " VNI %s", tag_buf);
                                vty_out(vty, "\n");
@@ -9001,13 +9387,20 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
                                                pdest),
                                        buf1, sizeof(buf1));
                                if (is_pi_family_evpn(parent_ri)) {
-                                       prefix2str((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);
+                                       vty_out(vty,
+                                               "  Imported from %s:%pFX, VNI %s\n",
+                                               buf1,
+                                               (struct prefix_evpn *)
+                                                       bgp_dest_get_prefix(
+                                                               dest),
+                                               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));
                        }
                }
        }
@@ -9044,11 +9437,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");
@@ -9058,13 +9454,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);
                }
        }
 
@@ -9111,12 +9507,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(
@@ -9135,7 +9535,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(
@@ -9232,11 +9633,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 */
@@ -9289,8 +9695,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,
@@ -9600,14 +10005,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)) {
@@ -9621,8 +10029,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);
@@ -9646,9 +10056,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]);
                                }
                        }
                }
@@ -9872,13 +10281,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\" : {");
@@ -10056,9 +10466,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
@@ -10321,7 +10732,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 buf3[EVPN_ROUTE_STRLEN];
        char prefix_str[BUFSIZ];
        int count = 0;
        int best = 0;
@@ -10353,12 +10763,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 ? ":" : "",
-                               prefix2str((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)) :
@@ -10394,7 +10802,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)
@@ -12390,12 +12798,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);
@@ -12405,8 +12816,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
@@ -12498,11 +12910,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);
@@ -12514,8 +12930,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
@@ -13141,28 +13559,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);
@@ -13185,37 +13596,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;
        }
 
@@ -13293,9 +13699,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;
@@ -13315,237 +13720,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. */
@@ -13949,6 +14345,10 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
                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");
        }
 }
@@ -14071,54 +14471,27 @@ void bgp_route_init(void)
        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 962a086081b3e26d4da6a198fb2345a2b75dfc57..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;
@@ -398,6 +398,11 @@ struct bgp_aggregate {
 #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)                                      \
@@ -449,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
 
@@ -527,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 *);
@@ -658,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,
@@ -666,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);
@@ -710,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 968cda3f100261735a4acb053c4c16d1fb4487d8..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);
 
@@ -4033,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 31ea5554d585e4ff4f99725778fa3ff92c3df155..9dd27628ceb500bc16ca3d73d5333c4107d598e1 100644 (file)
@@ -469,6 +469,11 @@ 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 *)
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 1685f98181978bc1413213d6551886961772638c..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
@@ -796,13 +824,11 @@ static void update_subgroup_delete(struct update_subgroup *subgrp)
                UPDGRP_INCR_STAT(subgrp->update_group, subgrps_deleted);
 
        THREAD_OFF(subgrp->t_merge_check);
-
-       THREAD_TIMER_OFF(subgrp->t_coalesce);
+       THREAD_OFF(subgrp->t_coalesce);
 
        bpacket_queue_cleanup(SUBGRP_PKTQ(subgrp));
        subgroup_clear_table(subgrp);
 
-       THREAD_TIMER_OFF(subgrp->t_coalesce);
        sync_delete(subgrp);
 
        if (BGP_DEBUG(update_groups, UPDATE_GROUPS) && subgrp->update_group)
@@ -1768,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 c8a3c28523a498cc4b8339f993612a57f22bd721..00e781d804cb2304c4a68ca7ee63d1abe33b8683 100644 (file)
@@ -273,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)
 {
@@ -1585,23 +1616,16 @@ void cli_show_router_bgp_confederation_member_as(struct vty *vty,
  * @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;
@@ -1612,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",
@@ -1703,14 +1728,14 @@ DEFUN_YANG(no_bgp_maxmed_admin,
        return nb_cli_apply_changes(vty, NULL);
 }
 
-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")
+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")
 {
        int idx = 0;
 
@@ -1731,14 +1756,14 @@ DEFUN_YANG(bgp_maxmed_onstartup,
        return nb_cli_apply_changes(vty, NULL);
 }
 
-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")
+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")
 {
        nb_cli_enqueue_change(vty,
                              "./global/med-config/max-med-onstart-up-time",
@@ -1972,12 +1997,12 @@ 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_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")
+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(
@@ -1993,12 +2018,12 @@ DEFPY_YANG(bgp_wpkt_quanta,
        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")
+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(
@@ -2027,11 +2052,11 @@ void cli_show_router_global_update_group_config_coalesce_time(
 }
 
 
-DEFUN_YANG(bgp_coalesce_time,
-          bgp_coalesce_time_cmd,
-          "coalesce-time (0-4294967295)",
-          "Subgroup coalesce timer\n"
-          "Subgroup coalesce timer value (in ms)\n")
+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;
 
@@ -2058,15 +2083,37 @@ DEFUN_YANG(no_bgp_coalesce_time,
 }
 
 /* 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,
@@ -2074,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,
@@ -2092,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,
@@ -2114,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,
@@ -2129,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,
@@ -2170,13 +2302,13 @@ static void bgp_config_write_maxpaths(struct vty *vty, struct bgp *bgp,
 
 /* BGP timers.  */
 
-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")
+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")
 {
        int idx_number = 2;
        int idx_number_2 = 3;
@@ -2189,14 +2321,14 @@ DEFUN_YANG(bgp_timers,
        return nb_cli_apply_changes(vty, NULL);
 }
 
-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")
+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);
@@ -3883,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",
@@ -3893,10 +4024,9 @@ 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);
                        }
                }
        }
@@ -7045,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,
@@ -7892,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
  */
@@ -7934,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,
@@ -8085,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
@@ -8095,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) {
@@ -8108,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)
@@ -8232,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",
@@ -8243,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,
@@ -8386,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");
@@ -8415,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);
+       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 (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;
-               }
-       }
-
-       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
@@ -8486,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");
+
+       return nb_cli_apply_changes(vty, base_xpath);
+}
 
-       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);
-       }
+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");
+}
 
-       return CMD_SUCCESS;
+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,
@@ -8605,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>]",
@@ -8613,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;
 }
@@ -8637,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;
 }
@@ -8706,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,
@@ -9079,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",
@@ -9097,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)),
@@ -9148,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)
@@ -9614,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(
@@ -9627,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);
@@ -10710,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();
@@ -10984,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]);
@@ -11279,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]);
@@ -14108,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;
@@ -14162,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);
                }
        }
 
@@ -14248,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(
@@ -14273,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];
 
-       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);
+       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);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14309,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(
@@ -14344,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(
@@ -14390,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");
+
+       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_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);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14436,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,
@@ -14468,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];
 
-       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);
+       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);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_rmap,
@@ -14511,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);
 
-       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);
-       return bgp_redistribute_set(bgp, AFI_IP, protocol, instance, changed);
+       nb_cli_enqueue_change(vty, "./metric", NB_OP_CREATE,
+                             argv[idx_number_2]->arg);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(bgp_redistribute_ipv4_ospf_metric,
@@ -14555,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];
+
+       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_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, "./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(
@@ -14609,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);
+
+       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);
+       nb_cli_enqueue_change(vty, "./rmap-policy-import", NB_OP_CREATE,
+                             argv[idx_word]->arg);
 
-       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);
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14663,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);
 
-       instance = strtoul(argv[idx_number]->arg, NULL, 10);
-       return bgp_redistribute_unset(bgp, AFI_IP, protocol, instance);
+       nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+
+       return nb_cli_apply_changes(vty, base_xpath);
 }
 
 ALIAS_HIDDEN(
@@ -14704,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(
@@ -14738,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");
+
+       nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
 
-       bgp_redist_add(bgp, AFI_IP6, type, 0);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, false);
+       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];
+
+       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);
-       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);
+
+       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"
@@ -14795,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");
+
+       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_IP6, type, 0);
-       changed = bgp_redistribute_metric_set(bgp, red, AFI_IP6, type, metric);
-       return bgp_redistribute_set(bgp, AFI_IP6, type, 0, changed);
+       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,
@@ -14997,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;
        }
@@ -15182,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))
@@ -15892,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)
@@ -15959,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))
@@ -17386,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);
@@ -17933,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")
@@ -18554,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")
@@ -18619,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 a9e86ec09a999e23a0c300493dc4b03bf53e2431..349efbac454a3f738f90b629a4ad2505941bb003 100644 (file)
@@ -186,6 +186,13 @@ 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 1ee8a1a50b767e3384deed374d30dcbf5d0865d1..00213b4239431b703390796dfad274db40752195 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);
                }
        }
 
@@ -1436,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];
 
@@ -1596,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);
 }
@@ -2565,6 +2545,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)
@@ -2574,14 +2555,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;
 }
@@ -2788,7 +2770,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;
@@ -2799,8 +2780,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 3e2ca70a02c755b1990bedc2f4dbae696b37298c..cf16378de199f8ceaf1557a20e582a6fe8c4c7be 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
@@ -2740,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);
 
@@ -2753,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)) {
@@ -2765,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);
                }
        }
@@ -2983,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
@@ -3507,6 +3505,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 */
 
@@ -3772,7 +3773,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);
 
@@ -3789,12 +3789,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;
@@ -6587,6 +6586,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)
@@ -7087,8 +7252,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,
@@ -7293,14 +7456,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 00f1d5acc993563b4d1f89d292704a4f29173fad..74828e91df217411f128becc5625179f910e65e0 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;
 
@@ -682,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)
@@ -759,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. */
@@ -792,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,
@@ -1355,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];
@@ -1448,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)
@@ -1939,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);
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 b56261669c347f1853b6fd63339d9d96f9ecccc0..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 */
@@ -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 717e15707870542fae20c351a1049250304c36bc..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 \
@@ -104,6 +105,7 @@ bgpd_libbgp_a_SOURCES = \
        bgpd/bgpd.c \
        bgpd/bgp_nb.c \
        bgpd/bgp_nb_config.c \
+       bgpd/bgp_trace.c \
        # end
 
 if ENABLE_BGP_VNC
@@ -136,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 \
@@ -178,6 +181,7 @@ noinst_HEADERS += \
        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 \
@@ -208,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
index 8e86ba87ff78190bcffdde39e7c9ba05c0268851..237552c1408b0c2c380ea94e857f9b8b2bee445f 100755 (executable)
@@ -451,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
@@ -566,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],
@@ -1851,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 ------
@@ -2499,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
 ------------------------------
index 1f803b37725b27539e77c67cbc7c7149c0171bdb..1ba0f31c8a1a8fbb4ed6cedea8156180204f2af2 100644 (file)
@@ -9,6 +9,7 @@ FRRouting Developer's Guide
    packaging
    process-architecture
    library
+   tracing
    testing
    bgpd
    fpm
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 fb0ca10da458c698c8bca451fb07a7255822b655..3572734ba95b249c9dd0e832e4e02cbee0df306b 100644 (file)
@@ -1005,6 +1005,12 @@ Route Aggregation-IPv4 Address Family
    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
 
@@ -1063,6 +1069,11 @@ Route Aggregation-IPv6 Address Family
    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
@@ -2563,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
@@ -2584,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 ee06578b7c6123ec2c23fe1365054761d1952778..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/`
index df7c72f8dcb605524158d8a1051697ade3ddb156..98f5aff7dbdb759c6c527a92252243cb782bbbb5 100644 (file)
@@ -423,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] [backup]
-.. clicmd:: show isis route [level-1|level-2] [backup]
+.. 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.
@@ -515,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
index b66774ca0e1d14ae66a06d8061fdc186eea926eb..31b0df70ae892db6cf4f8f0d8d9f4f40d1c60241 100644 (file)
@@ -905,59 +905,63 @@ 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.
@@ -1177,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
 ==============
 
@@ -1279,6 +1318,11 @@ Debugging OSPF
 .. 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 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 2f3f3474236747fe5447046fdd89341dac2403d6..dd43dd047857612d88b2f5e5b749557309dcfa46 100644 (file)
@@ -358,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;
        }
 }
@@ -420,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 695e1318ae1063fb3c5f8da471efbd87e91df7f6..e3c70264f8089a1e6b544291cfe7fb00cff0a46e 100644 (file)
@@ -253,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) {
@@ -287,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) {
@@ -318,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;
@@ -331,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;
 
@@ -352,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");
                }
@@ -400,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,
@@ -613,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(
@@ -803,12 +800,12 @@ 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;
 
@@ -818,15 +815,15 @@ void isis_circuit_down(struct isis_circuit *circuit)
        } 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);
@@ -895,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",
@@ -980,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 a270636dde053201c396ef9996e8f3779aeb4e88..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");
 }
 
index 3324d74e0f05dcf8b73ac60d5e9f114f9793cf2d..d03f857a0c9d7e0193e0fdd4dc0d87f84d432553 100644 (file)
@@ -221,8 +221,8 @@ 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->isis->sysid, ISIS_SYS_ID_LEN);
@@ -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],
index c4c95138c44750deff3c901fc4f35df6ded065ea..0b987fc5cf50e2886c40ed94b371869f41ebbeee 100644 (file)
@@ -109,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 8360dfc59ea9233dfb06227e8fd4aac274d4d057..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,7 +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) {
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+               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);
        }
@@ -323,7 +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 : "");
 
-       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) {
@@ -662,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) {
index 8ca432f895d37b7eb15bd2abe63959e14dc34826..f22e4a708555d9f78c66cf857110291bedfb584f 100644 (file)
@@ -180,23 +180,6 @@ bool isis_lfa_excise_node_check(const struct isis_spftree *spftree,
        return false;
 }
 
-/* Find SRGB associated to a System ID. */
-static struct isis_sr_block *tilfa_find_srgb(struct lspdb_head *lspdb,
-                                            const uint8_t *sysid)
-{
-       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;
-}
-
 struct tilfa_find_pnode_prefix_sid_args {
        uint32_t sid_index;
 };
@@ -308,25 +291,30 @@ tilfa_compute_label_stack(struct lspdb_head *lspdb,
        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:
-                       srgb = tilfa_find_srgb(lspdb, sadj->id);
+                       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(sadj->id));
+                                         print_sys_hostname(target_node));
                                goto error;
                        }
 
                        /* Check if the SID index falls inside the SRGB. */
-                       if (sid->value.index >= srgb->range_size) {
+                       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);
+                                       __func__, sid->value.index.value);
                                goto error;
                        }
 
@@ -334,7 +322,7 @@ tilfa_compute_label_stack(struct lspdb_head *lspdb,
                         * Prefix-SID: map SID index to label value within the
                         * SRGB.
                         */
-                       label = srgb->lower_bound + sid->value.index;
+                       label = srgb->lower_bound + sid->value.index.value;
                        break;
                case TILFA_SID_ADJ:
                        /* Adj-SID: absolute label value can be used directly */
@@ -446,7 +434,8 @@ static int tilfa_build_repair_list(struct isis_spftree *spftree_pc,
        struct listnode *node;
        bool is_pnode, is_qnode;
        char buf[VID2STR_BUFFER];
-       struct isis_tilfa_sid sid_qnode, sid_pnode;
+       struct isis_tilfa_sid sid_dest = {}, sid_qnode = {}, sid_pnode = {};
+       uint32_t sid_index;
        mpls_label_t label_qnode;
 
        if (IS_DEBUG_TILFA) {
@@ -455,6 +444,24 @@ static int tilfa_build_repair_list(struct isis_spftree *spftree_pc,
                           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
@@ -492,8 +499,6 @@ static int tilfa_build_repair_list(struct isis_spftree *spftree_pc,
 
        /* Push Prefix-SID label when necessary. */
        if (is_pnode) {
-               uint32_t sid_index;
-
                /* 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)
@@ -521,10 +526,10 @@ static int tilfa_build_repair_list(struct isis_spftree *spftree_pc,
 
                if (IS_DEBUG_TILFA)
                        zlog_debug(
-                               "ISIS-TI-LFA: pushing Prefix-SID to %s (index %u)",
+                               "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 = sid_index;
+               sid_pnode.value.index.value = sid_index;
                listnode_add_head(repair_list, &sid_pnode);
 
                /* Apply repair list. */
@@ -614,6 +619,10 @@ static bool lfa_check_needs_protection(const struct isis_spftree *spftree_pc,
        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,
@@ -700,7 +709,7 @@ int isis_lfa_check(struct isis_spftree *spftree_pc, struct isis_vertex *vertex)
                struct route_table *route_table;
 
                route_table = spftree_pc->lfa.old.spftree->route_table_backup;
-               if (route_node_lookup(route_table, &vertex->N.ip.dest)) {
+               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",
index 62a7666f9c44ab921802df177cf0ced6a60b5567..835618760c0f637bd975d730d964579ade830b62 100644 (file)
@@ -28,7 +28,11 @@ enum isis_tilfa_sid_type {
 struct isis_tilfa_sid {
        enum isis_tilfa_sid_type type;
        union {
-               uint32_t index;
+               struct {
+                       uint32_t value;
+                       bool remote;
+                       uint8_t remote_sysid[ISIS_SYS_ID_LEN];
+               } index;
                mpls_label_t label;
        } value;
 };
index 7abfbe63cce443d974962c52a86d51185bfbf11e..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)) {
@@ -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(
@@ -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 d04012c4dac6b9cf4d7691983873cd15e1cc4d91..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 = {
index 303a7b46963ae227bafb30cbad5d9bde7f5f6985..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);
index 2710c3c13fad1f73201f56586ecf521b3a0df1a9..6cb7d32c25dd52784d38e43ff4cbec4af827ea0a 100644 (file)
@@ -1837,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
  */
@@ -2844,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;
index d6f2571178ba80d4328cfcd1e66c99f02b74d42b..72de5d6543fa3625eba453721a1845da9897d592 100644 (file)
@@ -205,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);
 
@@ -497,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);
 
@@ -1987,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,
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 0868ab487c2a104ba7d16e780b339dcbe177f554..d664a6f8962545c55eb25ed384b57d8137140c44 100644 (file)
@@ -71,7 +71,6 @@ 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;
 }
@@ -117,7 +116,7 @@ static struct isis_nexthop *nexthoplookup(struct list *nexthops, int family,
 }
 
 void adjinfo2nexthop(int family, struct list *nexthops,
-                    struct isis_adjacency *adj,
+                    struct isis_adjacency *adj, struct isis_sr_psid_info *sr,
                     struct mpls_label_stack *label_stack)
 {
        struct isis_nexthop *nh;
@@ -134,6 +133,8 @@ 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;
@@ -150,6 +151,8 @@ 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;
@@ -165,22 +168,22 @@ void adjinfo2nexthop(int family, struct list *nexthops,
 
 static void isis_route_add_dummy_nexthops(struct isis_route_info *rinfo,
                                          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;
@@ -192,6 +195,7 @@ 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;
 
                /*
@@ -199,7 +203,7 @@ static struct isis_route_info *isis_route_info_new(struct prefix *prefix,
                 * 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;
                }
@@ -227,12 +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;
 }
@@ -254,12 +259,28 @@ void isis_route_node_cleanup(struct route_table *table, struct route_node *node)
                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)
@@ -275,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)",
@@ -282,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 */
@@ -303,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,
@@ -409,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);
@@ -418,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);
index fbb548a79e41b59bac662567d895ddebd3aa28c0..b5e4aed6cccbe6df6e968d5dc8a8ceeee4df2445 100644 (file)
@@ -32,7 +32,7 @@ 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;
 };
 
@@ -43,6 +43,8 @@ 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;
 };
@@ -54,15 +56,13 @@ DECLARE_HOOK(isis_route_update_hook,
 
 void isis_nexthop_delete(struct isis_nexthop *nexthop);
 void adjinfo2nexthop(int family, struct list *nexthops,
-                    struct isis_adjacency *adj,
+                    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 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);
 
 /* Walk the given table and install new routes to zebra and remove old ones.
  * route status is tracked using ISIS_ROUTE_FLAG_ACTIVE */
index 39a1c9ebe97e4f3931eb8ed6326f9567715dfe22..690ea9f1a5e8979fd68c0478a71c563f75b861f0 100644 (file)
@@ -176,9 +176,8 @@ const char *vid2string(const 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;
@@ -466,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;
@@ -496,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);
@@ -508,9 +536,10 @@ 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
@@ -528,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;
@@ -538,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)
@@ -558,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
@@ -628,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);
@@ -656,7 +688,7 @@ static void process_N(struct isis_spftree *spftree, enum vertextype vtype,
                   (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;
 }
 
@@ -675,6 +707,7 @@ 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)
@@ -739,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);
                        }
                }
@@ -773,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);
                }
        }
 
@@ -798,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);
                        }
                }
        }
@@ -823,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);
                }
        }
 
@@ -865,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);
                }
        }
 
@@ -922,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;
@@ -936,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;
 }
@@ -985,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);
@@ -1222,8 +1333,9 @@ static void isis_spf_build_adj_list(struct isis_spftree *spftree,
 static void add_to_paths(struct isis_spftree *spftree,
                         struct isis_vertex *vertex)
 {
-       struct isis_area *area = spftree->area;
+#ifdef EXTREME_DEBUG
        char buff[VID2STR_BUFFER];
+#endif /* EXTREME_DEBUG */
 
        if (isis_find_vertex(&spftree->paths, &vertex->N, vertex->type))
                return;
@@ -1235,6 +1347,24 @@ static void add_to_paths(struct isis_spftree *spftree,
                   vid2string(vertex, buff, sizeof(buff)), vertex->depth,
                   vertex->d_N);
 #endif /* EXTREME_DEBUG */
+}
+
+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);
+
+       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)) {
@@ -1261,7 +1391,7 @@ static void add_to_paths(struct isis_spftree *spftree,
 
        if (VTYPE_IP(vertex->type)
            && !CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ROUTES)) {
-               if (listcount(vertex->Adj_N) > 0) {
+               if (vertex->depth == 1 || listcount(vertex->Adj_N) > 0) {
                        struct route_table *route_table;
 
                        if (spftree->type == SPF_TYPE_TI_LFA) {
@@ -1272,8 +1402,9 @@ static void add_to_paths(struct isis_spftree *spftree,
                        } else
                                route_table = spftree->route_table;
 
-                       isis_route_create(&vertex->N.ip.dest, &vertex->N.ip.src,
-                                         vertex->d_N, vertex->depth,
+                       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(
@@ -1281,19 +1412,6 @@ static void add_to_paths(struct isis_spftree *spftree,
                                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);
-
-       spftree->mtid = mtid;
 }
 
 static void isis_spf_loop(struct isis_spftree *spftree,
@@ -1301,6 +1419,7 @@ static void isis_spf_loop(struct isis_spftree *spftree,
 {
        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);
@@ -1327,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,
@@ -1508,8 +1644,6 @@ static int isis_run_spf_cb(struct thread *thread)
 
        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;
@@ -1800,12 +1934,126 @@ DEFUN(show_isis_topology, show_isis_topology_cmd,
        return CMD_SUCCESS;
 }
 
+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 backup)
+                      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)
@@ -1831,82 +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, '-');
 
+       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->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.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. */
@@ -1921,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, bool backup)
+                                  struct isis *isis, bool prefix_sid,
+                                  bool backup)
 {
        struct listnode *node;
        struct isis_area *area;
@@ -1941,19 +2136,19 @@ static void show_isis_route_common(struct vty *vty, int levels,
                                isis_print_routes(
                                        vty,
                                        area->spftree[SPFTREE_IPV4][level - 1],
-                                       backup);
+                                       prefix_sid, backup);
                        }
                        if (area->ipv6_circuits > 0) {
                                isis_print_routes(
                                        vty,
                                        area->spftree[SPFTREE_IPV6][level - 1],
-                                       backup);
+                                       prefix_sid, backup);
                        }
                        if (isis_area_ipv6_dstsrc_enabled(area)) {
                                isis_print_routes(vty,
                                                  area->spftree[SPFTREE_DSTSRC]
                                                               [level - 1],
-                                                 backup);
+                                                 prefix_sid, backup);
                        }
                }
        }
@@ -1965,13 +2160,14 @@ DEFUN(show_isis_route, show_isis_route_cmd,
 #ifndef FABRICD
       " [<level-1|level-2>]"
 #endif
-      " [backup]",
+      " [<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;
@@ -1979,6 +2175,7 @@ DEFUN(show_isis_route, show_isis_route_cmd,
        struct listnode *node;
        const char *vrf_name = VRF_DEFAULT_NAME;
        bool all_vrf = false;
+       bool prefix_sid = false;
        bool backup = false;
        int idx = 0;
 
@@ -1995,6 +2192,8 @@ 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;
 
@@ -2002,12 +2201,13 @@ DEFUN(show_isis_route, show_isis_route_cmd,
                if (all_vrf) {
                        for (ALL_LIST_ELEMENTS_RO(im->isis, node, isis))
                                show_isis_route_common(vty, levels, isis,
-                                                      backup);
+                                                      prefix_sid, backup);
                        return CMD_SUCCESS;
                }
                isis = isis_lookup_by_vrfname(vrf_name);
                if (isis != NULL)
-                       show_isis_route_common(vty, levels, isis, backup);
+                       show_isis_route_common(vty, levels, isis, prefix_sid,
+                                              backup);
        }
 
        return CMD_SUCCESS;
index 5d07c80d20a9198997fb573fd1645903f034bb1c..15d3ff92727831265cd8a83ca2b4a7d619902714 100644 (file)
@@ -68,7 +68,7 @@ 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,
-                      bool backup);
+                      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);
index 1a2e969bd9f11fb305540f318ff97fb3481b022a..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;
@@ -351,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");
        }
index 842103de1e17502e9adc118a829f0686e21c8d60..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"
@@ -50,8 +51,6 @@
 /* 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,
@@ -61,53 +60,149 @@ 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 --- */
 
@@ -162,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,
@@ -179,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. */
@@ -231,1028 +316,137 @@ int isis_sr_cfg_srlb_update(struct isis_area *area, uint32_t lower_bound,
        srdb->config.srlb_lower_bound = lower_bound;
        srdb->config.srlb_upper_bound = upper_bound;
 
-       if (srdb->enabled) {
-               /* Initialize new SRLB */
-               if (sr_local_block_init(area) != 0)
-                       return -1;
-
-               /* Reinstall local Adjacency-SIDs with new labels. */
-               for (ALL_LIST_ELEMENTS_RO(area->srdb.adj_sids, node, sra))
-                       sr_adj_sid_update(sra, &srdb->srlb);
-
-               /* Update and Flood LSP */
-               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;
+       if (srdb->enabled) {
+               /* Initialize new SRLB */
+               if (sr_local_block_init(area) != 0)
+                       return -1;
 
-               /* Only SPF algorithm is supported right now */
-               if (psid->algorithm != SR_ALGORITHM_SPF)
-                       continue;
+               /* Reinstall local Adjacency-SIDs with new labels. */
+               for (ALL_LIST_ELEMENTS_RO(area->srdb.adj_sids, node, sra))
+                       sr_adj_sid_update(sra, &srdb->srlb);
 
-               /* 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;
+               /* Update and Flood LSP */
+               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;
 }
 
 /**
- * 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);
+       /* 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);
+       }
 }
 
 /**
@@ -1272,89 +466,6 @@ void isis_area_delete_backup_adj_sids(struct isis_area *area, int level)
                        sr_adj_sid_del(sra);
 }
 
-/**
- * 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);
-       }
-}
-
-/**
- * Once a route is updated in the SPT, reinstall or uninstall its corresponding
- * Prefix-SID (if any).
- *
- * @param area         IS-IS area
- * @param prefix       Prefix to be updated
- * @param route_info   New Route Information
- *
- * @return             0
- */
-static int sr_route_update(struct isis_area *area, struct prefix *prefix,
-                          struct isis_route_info *route_info)
-{
-       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;
-       }
-
-       return 0;
-}
-
 /* --- Segment Routing Local Block management functions --------------------- */
 
 /**
@@ -1588,7 +699,7 @@ void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup,
                        struct mpls_label_stack *label_stack;
 
                        label_stack = vadj->label_stack;
-                       adjinfo2nexthop(family, sra->backup_nexthops, adj,
+                       adjinfo2nexthop(family, sra->backup_nexthops, adj, NULL,
                                        label_stack);
                }
        }
@@ -1838,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);
                }
@@ -1847,8 +958,6 @@ static int sr_if_new_hook(struct interface *ifp)
        return 0;
 }
 
-/* --- Segment Routing Show information functions --------------------------- */
-
 /**
  * Show LFIB operation in human readable format.
  *
@@ -1856,13 +965,11 @@ static int sr_if_new_hook(struct interface *ifp)
  * @param size       Size of the buffer
  * @param label_in    Input Label
  * @param label_out   Output Label
- * @param label_stack Output Label Stack (TI-LFA)
  *
  * @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,
-                      const struct mpls_label_stack *label_stack)
+char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
+               mpls_label_t label_out)
 {
        if (size < 24)
                return NULL;
@@ -1872,16 +979,6 @@ static char *sr_op2str(char *buf, size_t size, mpls_label_t label_in,
                return buf;
        }
 
-       if (label_stack) {
-               char buf_labels[256];
-
-               mpls_label2str(label_stack->num_labels, &label_stack->label[0],
-                              buf_labels, sizeof(buf_labels), 1);
-
-               snprintf(buf, size, "Swap(%u, %s)", label_in, buf_labels);
-               return buf;
-       }
-
        switch (label_out) {
        case MPLS_LABEL_IMPLICIT_NULL:
                snprintf(buf, size, "Pop(%u)", label_in);
@@ -1900,215 +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, 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, bool backup)
-{
-       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;
-       struct isis_route_info *rinfo;
-
-       (void)prefix2str(&srp->prefix, buf_prefix, sizeof(buf_prefix));
-
-       rinfo = srp->u.remote.rinfo;
-       if (rinfo && backup)
-               rinfo = rinfo->backup;
-       if (!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, NULL));
-               return;
-       }
-
-       for (ALL_LIST_ELEMENTS_RO(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, nexthop->label_stack);
-
-               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,
-                            bool backup)
-{
-       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, backup);
-                       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 [backup]",
-      SHOW_STR PROTO_HELP VRF_CMD_HELP_STR
-      "All VRFs\n"
-      "Segment-Routing\n"
-      "Segment-Routing Prefix-SIDs\n"
-      "Show backup 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;
-       bool backup = false;
-       int idx = 0;
-
-       ISIS_FIND_VRF_ARGS(argv, argc, idx, vrf_name, all_vrf);
-       if (argv_find(argv, argc, "backup", &idx))
-               backup = true;
-
-       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, backup);
-                               }
-                       }
-                       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,
-                                                        backup);
-                       }
-               }
-       }
-
-       return CMD_SUCCESS;
-}
-
 /**
  * Show Segment Routing Node.
  *
@@ -2118,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]);
@@ -2134,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. */
@@ -2184,7 +1073,6 @@ DEFUN(show_sr_node, show_sr_node_cmd,
        return CMD_SUCCESS;
 }
 
-
 /* --- IS-IS Segment Routing Management function ---------------------------- */
 
 /**
@@ -2284,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,
@@ -2332,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);
@@ -2386,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);
 }
 
@@ -2406,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 2e4f3a69f79413a75d15c183c8f44b51f895b2e2..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;
@@ -106,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,
@@ -217,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;
 
@@ -235,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;
@@ -267,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,
@@ -279,16 +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 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 void isis_area_verify_sr(struct isis_area *area);
+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 0e92dc2a8942e98d7cc461f695d01531cc68f12e..805ede1e44593c24e68f6f63f7405556e44c8762 100644 (file)
@@ -87,10 +87,6 @@ static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
 {
        struct isis_circuit *circuit;
        struct connected *c;
-#ifdef EXTREME_DEBUG
-       struct prefix *p;
-       char buf[PREFIX2STR_BUFFER];
-#endif /* EXTREME_DEBUG */
 
        c = zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD,
                                         zclient->ibuf, vrf_id);
@@ -99,13 +95,10 @@ static int isis_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
                return 0;
 
 #ifdef EXTREME_DEBUG
-       p = c->address;
-       prefix2str(p, buf, sizeof(buf));
-
        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)) {
@@ -121,10 +114,6 @@ static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
 {
        struct isis_circuit *circuit;
        struct connected *c;
-#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);
@@ -133,13 +122,10 @@ static int isis_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
                return 0;
 
 #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(c->ifp)) {
@@ -169,16 +155,14 @@ static int isis_zebra_link_params(ZAPI_CALLBACK_ARGS)
 }
 
 enum isis_zebra_nexthop_type {
-       ISIS_ROUTE_NEXTHOP_MAIN = 0,
-       ISIS_ROUTE_NEXTHOP_BACKUP,
-       ISIS_MPLS_NEXTHOP_MAIN,
-       ISIS_MPLS_NEXTHOP_BACKUP,
+       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,
-                                  uint8_t backup_nhs)
+                                  bool mpls_lsp, uint8_t backup_nhs)
 {
        struct isis_nexthop *nexthop;
        struct listnode *node;
@@ -224,23 +208,18 @@ static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
 
                /* Add MPLS label(s). */
                switch (type) {
-               case ISIS_ROUTE_NEXTHOP_MAIN:
-               case ISIS_ROUTE_NEXTHOP_BACKUP:
-                       /*
-                        * SR/TI-LFA labels are installed using separate
-                        * messages.
-                        */
-                       break;
-               case ISIS_MPLS_NEXTHOP_MAIN:
-                       if (nexthop->sr.label != MPLS_INVALID_LABEL) {
+               case ISIS_NEXTHOP_MAIN:
+                       if (nexthop->sr.present) {
                                api_nh->label_num = 1;
                                api_nh->labels[0] = nexthop->sr.label;
-                       } else {
-                               api_nh->label_num = 1;
-                               api_nh->labels[0] = MPLS_LABEL_IMPLICIT_NULL;
-                       }
+                       } else if (mpls_lsp)
+                               /*
+                                * Do not use non-SR enabled nexthops to prevent
+                                * broken LSPs from being formed.
+                                */
+                               continue;
                        break;
-               case ISIS_MPLS_NEXTHOP_BACKUP:
+               case ISIS_NEXTHOP_BACKUP:
                        if (nexthop->label_stack) {
                                api_nh->label_num =
                                        nexthop->label_stack->num_labels;
@@ -248,7 +227,11 @@ static int isis_zebra_add_nexthops(struct isis *isis, struct list *nexthops,
                                       nexthop->label_stack->label,
                                       sizeof(mpls_label_t)
                                               * api_nh->label_num);
-                       } else {
+                       } 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;
                        }
@@ -280,7 +263,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
        struct zapi_route api;
        int count = 0;
 
-       if (zclient->sock < 0)
+       if (zclient->sock < 0 || list_isempty(route_info->nexthops))
                return;
 
        memset(&api, 0, sizeof(api));
@@ -300,7 +283,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
        if (route_info->backup) {
                count = isis_zebra_add_nexthops(
                        isis, route_info->backup->nexthops, api.backup_nexthops,
-                       ISIS_ROUTE_NEXTHOP_BACKUP, 0);
+                       ISIS_NEXTHOP_BACKUP, false, 0);
                if (count > 0) {
                        SET_FLAG(api.message, ZAPI_MESSAGE_BACKUP_NEXTHOPS);
                        api.backup_nexthop_num = count;
@@ -309,7 +292,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
 
        /* Add primary nexthops. */
        count = isis_zebra_add_nexthops(isis, route_info->nexthops,
-                                       api.nexthops, ISIS_ROUTE_NEXTHOP_MAIN,
+                                       api.nexthops, ISIS_NEXTHOP_MAIN, false,
                                        count);
        if (!count)
                return;
@@ -342,31 +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 isis *isis = srp->srn->area->isis;
        struct zapi_labels zl;
-       struct zapi_nexthop *znh;
-       struct interface *ifp;
-       struct isis_route_info *rinfo;
        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;
                }
 
@@ -375,21 +366,12 @@ 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;
-
-               rinfo = srp->u.remote.rinfo;
-
+       } else {
                /* Add backup nexthops first. */
                if (rinfo->backup) {
                        count = isis_zebra_add_nexthops(
-                               isis, rinfo->backup->nexthops,
-                               zl.backup_nexthops, ISIS_MPLS_NEXTHOP_BACKUP,
+                               area->isis, rinfo->backup->nexthops,
+                               zl.backup_nexthops, ISIS_NEXTHOP_BACKUP, true,
                                0);
                        if (count > 0) {
                                SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
@@ -398,13 +380,12 @@ static void isis_zebra_prefix_install_prefix_sid(const struct sr_prefix *srp)
                }
 
                /* Add primary nexthops. */
-               count = isis_zebra_add_nexthops(isis, rinfo->nexthops,
-                                               zl.nexthops,
-                                               ISIS_MPLS_NEXTHOP_MAIN, count);
+               count = isis_zebra_add_nexthops(area->isis, rinfo->nexthops,
+                                               zl.nexthops, ISIS_NEXTHOP_MAIN,
+                                               true, count);
                if (!count)
                        return;
                zl.nexthop_num = count;
-               break;
        }
 
        /* Send message to zebra. */
@@ -412,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.
  *
@@ -504,7 +460,7 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
 
                count = isis_zebra_add_nexthops(isis, sra->backup_nexthops,
                                                zl.backup_nexthops,
-                                               ISIS_MPLS_NEXTHOP_BACKUP, 0);
+                                               ISIS_NEXTHOP_BACKUP, true, 0);
                if (count > 0) {
                        SET_FLAG(zl.message, ZAPI_LABELS_HAS_BACKUPS);
                        zl.backup_nexthop_num = count;
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 57d3e9c7c0ea8a9bf9c42d762dd4cef20921c5c2..057ede0e38b683a73445787f3b02e2aa9ccfe14a 100644 (file)
@@ -442,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]);
@@ -457,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);
 
@@ -583,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);
 }
 
@@ -2373,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;
 }
 
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 677d4b2dad6cf029d93e3c2f22480902e64402cf..bb007b08683af952007481eaa1c04da5df104a4c 100644 (file)
@@ -462,6 +462,14 @@ struct cmd_node {
 #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);
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 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 9657f0b1dfa9f1020ec98c8767579bc2d1a2b5a3..c9d7eb37cfd2d0ba9fa551b46882095c0999c761 100644 (file)
@@ -79,7 +79,7 @@ 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) {
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+               THREAD_OFF(ldp_sync_info->t_holddown);
 
                if (ldp_sync_info->state == LDP_IGP_SYNC_STATE_REQUIRED_UP)
                        ldp_sync_info->state =
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 f1575649b17b9e99bd5fd3a1f4b26cb464354a32..b2fa9456909fe802834a5d1c225bf1ce3385aa33 100644 (file)
@@ -431,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 4afb1d642a35426ae181d2a296cbe06d6db7c5ce..dee98ad8d73ab7ee06b25e50483102ad01ef70e6 100644 (file)
@@ -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 c99f993ea5159a2715a95a405200fb7ff9df1020..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;
 }
@@ -2232,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,
@@ -2258,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 16f19b3d5b5336acb703b332572bca32c359b41a..3f6e4dc46e5a7af494d904bcee60a5181994c91e 100644 (file)
@@ -1237,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 a7f3a1b305707ff3b286097368c3d34983c8e4b5..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);
 
@@ -312,7 +312,7 @@ int nb_cli_rpc(struct vty *vty, const char *xpath, struct list *input,
 
 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;
 }
@@ -377,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 c1cb0fc11d27e196c78dc4e28a6c49a087ae7bf8..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);
 
@@ -1189,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))
@@ -1276,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));
@@ -1393,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;
 }
@@ -1426,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 3cd310c5a7ecbd7a793f03897b0f85d616b32294..c027f4de726f6677fce214f267922737a70debcb 100644 (file)
@@ -575,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);
@@ -599,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);
@@ -686,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 24def1bac4dc41894a67a9933f6840435106a8a4..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")
@@ -1336,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 acb208e5e73111fa2baa8471419c401ae2eff19f..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,7 +131,7 @@ static int spf_backoff_holddown_elapsed(struct thread *thread)
 {
        struct spf_backoff *backoff = THREAD_ARG(thread);
 
-       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",
@@ -166,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 55f127b019a871ffd4fd946372c1ac57e0b7ef39..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 \
@@ -204,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 \
@@ -251,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 \
@@ -401,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 \
@@ -411,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 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 204056120a4f372ef0317ffa2e5139f8023a5824..f087289df657d60416844640a82b7db041db1e0b 100644 (file)
@@ -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;
        }
 
@@ -372,11 +361,10 @@ 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, area->ospf6);
                        return 0;
@@ -414,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;
                        }
        }
@@ -431,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;
                }
 
@@ -804,7 +783,6 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old,
                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
@@ -826,16 +804,13 @@ void ospf6_abr_old_route_remove(struct ospf6_lsa *lsa, struct ospf6_route *old,
 
                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, ospf6);
@@ -1146,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
index 7a1c19fe7d0d040f834ee7faa36f73329c767de8..e98764cd26d61130663e099d8d14ebb3b967a5d9 100644 (file)
@@ -525,13 +525,12 @@ 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)) {
index 8a467716ffc9374e905b93475147ac20f43ebf4f..c053716f26c8e792440db7543e2f1d522ebe41f7 100644 (file)
@@ -65,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));
@@ -215,7 +213,6 @@ void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
        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,
@@ -375,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)
@@ -405,32 +400,27 @@ 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)
@@ -458,7 +448,6 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6)
        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);
@@ -489,10 +478,8 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6)
        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;
        }
 
@@ -532,15 +519,13 @@ void ospf6_asbr_lsa_add(struct ospf6_lsa *lsa, struct ospf6 *ospf6)
        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) {
@@ -1079,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;
 
@@ -1089,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) {
@@ -1160,10 +1143,9 @@ 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);
@@ -1214,9 +1196,9 @@ 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, 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);
@@ -1235,16 +1217,14 @@ void ospf6_asbr_redistribute_remove(int type, ifindex_t ifindex,
        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;
        }
 
@@ -1252,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),
@@ -1877,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))
@@ -1890,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
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 c7d037f43f4b191fcb25b8798f2a36d32cfa717f..75917b9d859e9325e46670a374c9e469083f8784 100644 (file)
@@ -437,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;
                        }
@@ -939,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;
                }
        }
index 15bfabb75d835f4f55aa9efae2a3ff5e3c5dfd72..2102afd84401435974535e6e16b8f818d4d72935 100644 (file)
@@ -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,10 +984,8 @@ 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, oa->ospf6);
                }
@@ -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,10 +1251,8 @@ 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,
                                        oi->area->ospf6);
@@ -1556,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;
                                }
@@ -1584,16 +1576,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.
index 36f9431ab9462ce9bd83ba19bd5719086920ccc8..814e2767967e0ebd27123566c2bb0d65144fb65f 100644 (file)
@@ -157,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;                                                      \
        }
 
index db6f9a7801516e910695b1c03c82d6d050f4eaaa..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);
 
index 5996000dd87f9b68a939325c06a40db531f36a45..5f9953782c896201622104c686da177d8f4e213b 100644 (file)
@@ -1701,7 +1701,7 @@ static void ospf6_send(struct in6_addr *src, struct in6_addr *dst,
 
        /* send message */
        if (oi->area->ospf6->fd != -1) {
-               len = ospf6_sendmsg(src, dst, &oi->interface->ifindex, iovector,
+               len = ospf6_sendmsg(src, dst, oi->interface->ifindex, iovector,
                                    oi->area->ospf6->fd);
                if (len != ntohs(oh->length))
                        flog_err(EC_LIB_DEVELOPMENT,
index e3e8cdbeae82bb4547fc664e3122d2844ae1af3a..76f98fecdd8e2deb4d520edd3ca6135cf4bbce10 100644 (file)
@@ -170,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, int ospf6_sock)
+                 ifindex_t ifindex, struct iovec *message, int ospf6_sock)
 {
        int retval;
        struct msghdr smsghdr;
@@ -183,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;
@@ -191,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
@@ -203,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;
@@ -222,7 +221,8 @@ 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;
index 56a73fe25f96fb0b3870e396f069be6a3035bc6a..08d8be4445d5bf73805cfdb5b1ae522b2f023e23 100644 (file)
@@ -29,9 +29,11 @@ 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 *, int ospf6_sock);
-extern int ospf6_recvmsg(struct in6_addr *, struct in6_addr *, ifindex_t *,
-                        struct iovec *, int ospf6_sock);
+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 374acd7b5f1c3e0ebebf74e14a8206628c061424..2602854f33d8524f56525068b40373c1096c5be6 100644 (file)
@@ -549,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);
@@ -578,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);
@@ -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),
index 70164818a4b1149f0994f31ff289946d03926ebc..4dd1d5a462e4ad88101491779ccec018a2db49a5 100644 (file)
@@ -321,7 +321,6 @@ static int ospf6_spf_install(struct ospf6_vertex *v,
 {
        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,
@@ -336,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;
index 08beb98f2089a41e8fe1f7bff1fc33c91c4798ac..95c72290d0ce24a3f89bb03ff69002c0eec55603 100644 (file)
@@ -1163,15 +1163,11 @@ static int ospf6_distance_config_write(struct vty *vty, struct ospf6 *ospf6)
        }
 
        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;
 }
 
index 6ab6153798c0a8b78635b800ddbbaebab8274364..b6c712176a5b4d8eea39d37c718233c56dee2c82 100644 (file)
@@ -133,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);
@@ -141,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);
@@ -157,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);
@@ -165,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);
@@ -206,19 +200,13 @@ 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,
@@ -265,16 +253,13 @@ 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))
@@ -367,7 +352,6 @@ void ospf6_zebra_route_update_remove(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)) {
@@ -381,19 +365,14 @@ void ospf6_zebra_add_discard(struct ospf6_route *request, struct ospf6 *ospf6)
                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);
        }
 }
 
@@ -401,7 +380,6 @@ 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)) {
@@ -415,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);
        }
 }
 
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..639f9cb35e63ba18cd083a23c67b30310292695e 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) {
+               lsa = 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
+               lsa = 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 7fd1b5c64e6a971fbffd967875d4f949194d0dc4..e15c9c42c77991e7e038a381234e28c46d9179a2 100644 (file)
@@ -242,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)
@@ -292,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));
@@ -317,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)
@@ -333,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++)
@@ -349,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);
        }
@@ -427,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);
@@ -519,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));
@@ -1001,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;
@@ -1018,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;
@@ -1025,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"
@@ -1047,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;
@@ -1075,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;
@@ -1092,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;
@@ -1099,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
@@ -1107,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
@@ -1123,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;
index a2df4ff22c1ebfecd7bf54612cf8e4d56f4e8219..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
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 7d461d45878e4523622af3e899b82f647f9198d1..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));
 
@@ -345,9 +387,9 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
                        /*  Handling Max age grace LSA.*/
                        if (IS_DEBUG_OSPF_GR_HELPER)
                                zlog_debug(
-                                       "%s, Received a maxage GRACE-LSA from router %s",
+                                       "%s, Received a maxage GRACE-LSA from router %pI4",
                                        __PRETTY_FUNCTION__,
-                                       inet_ntoa(new->data->adv_router));
+                                       &new->data->adv_router);
 
                        if (current) {
                                ospf_process_maxage_grace_lsa(ospf, new, nbr);
@@ -361,9 +403,9 @@ int ospf_flood(struct ospf *ospf, struct ospf_neighbor *nbr,
                } else {
                        if (IS_DEBUG_OSPF_GR_HELPER)
                                zlog_debug(
-                                       "%s, Received a GRACE-LSA from router %s",
+                                       "%s, Received a GRACE-LSA from router %pI4",
                                        __PRETTY_FUNCTION__,
-                                       inet_ntoa(new->data->adv_router));
+                                       &new->data->adv_router);
 
                        if (ospf_process_grace_lsa(ospf, new, nbr)
                            == OSPF_GR_NOT_HELPER) {
@@ -412,11 +454,15 @@ 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))
@@ -437,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));
@@ -773,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);
@@ -800,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);
@@ -862,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);
@@ -879,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);
@@ -894,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);
@@ -984,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);
index 616013fb9e501f326a1bccbf76603b255552912f..9c029a49ba523474c0ceadb408f57ecea6df791f 100644 (file)
@@ -377,8 +377,8 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
 
        if (IS_DEBUG_OSPF_GR_HELPER)
                zlog_debug(
-                       "%s, Grace LSA received from %s, grace interval:%u, restartreason :%s",
-                       __PRETTY_FUNCTION__, inet_ntoa(restart_addr),
+                       "%s, Grace LSA received from %pI4, grace interval:%u, restartreason :%s",
+                       __PRETTY_FUNCTION__, &restart_addr,
                        grace_interval,
                        ospf_restart_reason2str(restart_reason));
 
@@ -392,9 +392,9 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
                if (!restarter) {
                        if (IS_DEBUG_OSPF_GR_HELPER)
                                zlog_debug(
-                                       "%s, Restarter is not a nbr(%s) for this router.",
+                                       "%s, Restarter is not a nbr(%pI4) for this router.",
                                        __PRETTY_FUNCTION__,
-                                       inet_ntoa(restart_addr));
+                                       &restart_addr);
                        return OSPF_GR_NOT_HELPER;
                }
        } else
@@ -425,8 +425,8 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
        if (!IS_NBR_STATE_FULL(restarter)) {
                if (IS_DEBUG_OSPF_GR_HELPER)
                        zlog_debug(
-                               "%s, This Neighbour %s is not in FULL state.",
-                               __PRETTY_FUNCTION__, inet_ntoa(restarter->src));
+                               "%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;
@@ -501,8 +501,8 @@ int ospf_process_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
        } else {
                if (IS_DEBUG_OSPF_GR_HELPER)
                        zlog_debug(
-                               "%s, This Router becomes a HELPER for the neighbour %s",
-                               __PRETTY_FUNCTION__, inet_ntoa(restarter->src));
+                               "%s, This Router becomes a HELPER for the neighbour %pI4",
+                               __PRETTY_FUNCTION__, &restarter->src);
        }
 
        /* Became a Helper to the RESTART neighbour.
@@ -606,8 +606,8 @@ void ospf_helper_handle_topo_chg(struct ospf *ospf, struct ospf_lsa *lsa)
 
        if (IS_DEBUG_OSPF_GR_HELPER)
                zlog_debug(
-                       "%s, Topo change detected due to lsa LSID:%s type:%d",
-                       __PRETTY_FUNCTION__, inet_ntoa(lsa->data->id),
+                       "%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;
@@ -670,8 +670,8 @@ void ospf_gr_helper_exit(struct ospf_neighbor *nbr,
                return;
 
        if (IS_DEBUG_OSPF_GR_HELPER)
-               zlog_debug("%s, Exiting from HELPER support to %s, due to %s",
-                          __PRETTY_FUNCTION__, inet_ntoa(nbr->src),
+               zlog_debug("%s, Exiting from HELPER support to %pI4, due to %s",
+                          __PRETTY_FUNCTION__, &nbr->src,
                           ospf_exit_reason2str(reason));
 
        /* Reset helper status*/
@@ -758,8 +758,8 @@ void ospf_process_maxage_grace_lsa(struct ospf *ospf, struct ospf_lsa *lsa,
        }
 
        if (IS_DEBUG_OSPF_GR_HELPER)
-               zlog_debug("%s, GraceLSA received for neighbour %s.",
-                          __PRETTY_FUNCTION__, inet_ntoa(restartAddr));
+               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
@@ -1066,8 +1066,8 @@ static void show_ospf_grace_lsa_info(struct vty *vty, struct ospf_lsa *lsa)
                        restartAddr = (struct grace_tlv_restart_addr *)tlvh;
                        sum += TLV_SIZE(tlvh);
 
-                       vty_out(vty, "   Restarter address:%s\n",
-                               inet_ntoa(restartAddr->addr));
+                       vty_out(vty, "   Restarter address:%pI4\n",
+                               &restartAddr->addr);
                        break;
                default:
                        vty_out(vty, "   Unknown TLV type %d\n",
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 3d2c28b1e4684300b55f694b40ef41280eeeb1e3..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);
@@ -977,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))
@@ -1109,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;
@@ -1128,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)
@@ -1198,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);
        }
 
@@ -1276,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(
@@ -1297,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);
@@ -1362,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(
@@ -1373,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 e9faa415fe3c615ac3ff650e281d668362fd2dd2..36e97f877906de225d4369006fa559c5886e0e4d 100644 (file)
@@ -223,8 +223,8 @@ 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 @@ 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 67ea4c4684f5d929d8affd9051c388e767c443c4..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)                                          \
index 96fa04b5886d6a2de8808026476030f5a1bfefe3..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,7 +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) {
-               THREAD_TIMER_OFF(ldp_sync_info->t_holddown);
+               THREAD_OFF(ldp_sync_info->t_holddown);
                ldp_sync_info->state = LDP_IGP_SYNC_STATE_REQUIRED_NOT_UP;
                ospf_if_recalculate_output_cost(ifp);
        }
@@ -337,7 +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);
-       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))
@@ -386,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");
@@ -436,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)
@@ -486,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);
@@ -980,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 0200bf5e260384de9fee4a5dd6da0fb0489f488e..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);
@@ -281,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);
 }
@@ -297,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);
@@ -628,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;
@@ -837,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);
        }
@@ -876,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);
        }
 
@@ -929,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);
@@ -1059,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);
        }
@@ -1082,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;
@@ -1112,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);
        }
 
@@ -1231,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);
        }
@@ -1267,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);
        }
 
@@ -1374,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);
        }
@@ -1408,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);
        }
 
@@ -1758,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;
        }
 
@@ -1792,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;
        }
 
@@ -1802,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;
        }
 
@@ -1812,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++;
@@ -1878,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;
        }
 
@@ -1887,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;
        }
 
@@ -1899,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;
        }
 
@@ -1979,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;
        }
 
@@ -2010,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);
        }
@@ -2058,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++) {
@@ -2089,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.");
                        }
                }
        }
@@ -2117,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);
@@ -2139,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;
        }
 
@@ -2195,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(
@@ -2229,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);
+                                       }
                                }
                        }
                }
@@ -2247,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;
        }
 
@@ -2281,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;
        }
 
@@ -2307,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);
        }
 
@@ -2683,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:
@@ -2694,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;
                }
        }
@@ -2711,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);
        }
@@ -2788,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))
@@ -2814,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);
                        }
                }
 
@@ -2873,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;
        }
@@ -3109,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;
 }
@@ -3206,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);
@@ -3244,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);
@@ -3259,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);
@@ -3363,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;
@@ -3380,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;
@@ -3456,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);
@@ -3479,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:
@@ -3530,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])
@@ -3543,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);
        }
 }
@@ -3615,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);
@@ -3648,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 90f7b5363258a2b1c6def579689110908697c6f5..c5de287948103b0bd61d8dec551a43d96f73dcd5 100644 (file)
@@ -313,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 *);
@@ -339,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 d102fddf86e4a5c2c37a4cc4ab7bbb1bf31556dd..ae22cec414ad4f791135d32e79e87f14c3b98e6c 100644 (file)
@@ -57,3 +57,4 @@ 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 58f23aa9c739d7c0a0e624aa5542a13a3bce76e4..624b1d33063c0d7adbc27ca79840a7d0259af784 100644 (file)
@@ -56,5 +56,6 @@ 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 b0ff40afe5d94e296cc496431bebb3fb3e72258f..2fa43923ab3c5cbe4bfdaeaba58ce9d853a06867 100644 (file)
@@ -184,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 {
@@ -284,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;
@@ -401,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);
                }
@@ -459,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 28aec41eba77ef8a5be9d4c94780b5c7bbb38bd9..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
 
index 2931831826cce836abb624082dc556e663eed101..26e7855e8c86e910ca696154841e7e75744c3389 100644 (file)
@@ -66,8 +66,8 @@ 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));
 
        /* Dont trigger NSM_InactivityTimer event , if the current
@@ -91,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. */
@@ -398,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));
        }
 
@@ -597,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),
@@ -608,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),
@@ -691,8 +691,8 @@ 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));
@@ -749,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);
        }
@@ -777,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]);
@@ -802,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 c219ba7386e2d2e3a11468feae906a9949bea0fe..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)                                          \
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 160982a23866ef563d745ce491fd403aa4e022b6..ef39b6c2f67c1e118b64ada6dec57016c47665d0 100644 (file)
@@ -468,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);
 }
 
@@ -606,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;
@@ -659,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;
        }
 
@@ -799,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));
 
@@ -820,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(
@@ -896,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;
        }
@@ -916,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;
                }
@@ -925,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;
@@ -938,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;
@@ -947,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));
 
@@ -962,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 */
@@ -975,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 */
@@ -993,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
@@ -1011,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;
        }
@@ -1147,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;
                }
@@ -1162,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"
@@ -1218,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);
                }
        }
@@ -1287,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;
        }
 
@@ -1297,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;
        }
@@ -1324,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);
        }
 
@@ -1335,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 */
@@ -1356,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);
 
@@ -1369,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;
@@ -1392,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);
 
@@ -1406,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;
                        }
                }
@@ -1417,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;
                }
 
@@ -1434,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 ");
@@ -1445,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. */
                        }
@@ -1462,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;
@@ -1481,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(
@@ -1493,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;
                }
@@ -1502,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;
                }
@@ -1515,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;
                }
@@ -1530,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)
@@ -1564,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;
        }
 }
@@ -1591,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;
        }
 
@@ -1604,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;
        }
@@ -1712,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;
                }
 
@@ -1747,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 */
@@ -1760,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;
                }
 
@@ -1796,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);
        }
@@ -1838,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;
        }
 
@@ -1850,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;
@@ -2241,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;
        }
 
@@ -2252,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;
@@ -2485,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;
@@ -2515,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;
@@ -2916,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;
        }
 
@@ -2925,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;
        }
 
@@ -2984,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;
                }
@@ -2995,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;
        }
@@ -3074,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;
                }
        }
@@ -3087,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];
@@ -3122,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);
@@ -3136,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;
        }
 
@@ -3149,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(
@@ -3736,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);
 
@@ -3757,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);
 
@@ -3875,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);
 }
 
@@ -3895,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);
 }
 
@@ -3992,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
@@ -4010,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;
@@ -4043,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)
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 8e5cb5bb36dd6ce48c7f2f64dfc2e00384ad70b8..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;
@@ -2513,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 64d7b39acda9e098b5ba649315de439639988a1c..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)
@@ -1883,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);
@@ -1947,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");
@@ -2449,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;
        }
 
@@ -2572,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);
@@ -2598,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;
        }
@@ -2633,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;
                }
@@ -2660,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;
@@ -2673,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",
@@ -2700,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);
@@ -2764,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();
@@ -2779,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",
@@ -2787,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)
@@ -2837,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;
 
@@ -2848,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 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 5c82e11393c972cc538d7a5aabbcf80fd81095c6..cfdcde9914f350caa1390f7b294debeb363085f6 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) {
@@ -5778,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;
@@ -5808,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:
@@ -5820,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:
@@ -5836,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;
@@ -5857,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",
@@ -5872,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[] = {
@@ -5927,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);
+
+               if (!json)
+                       vty_out(vty, "   Number of Links: %d\n\n",
+                               ntohs(rl->links));
+               else
+                       json_object_int_add(json, "numOfLinks",
+                                           ntohs(rl->links));
 
-               vty_out(vty, "   Number of Links: %d\n\n", ntohs(rl->links));
+               show_ip_ospf_database_router_links(vty, rl, json);
 
-               show_ip_ospf_database_router_links(vty, rl);
-               vty_out(vty, "\n");
+               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;
@@ -6069,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");
@@ -6079,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,
@@ -6155,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);
@@ -6167,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);
        }
@@ -6178,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;
        }
@@ -6204,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:
@@ -6269,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);
+                               }
+
+                               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);
+                                       }
 
-                               vty_out(vty, "\n");
+                                       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:
@@ -6293,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) {
+                               if (json) {
+                                       json_lsa = json_object_new_object();
+                                       json_object_array_add(json_lsa_array,
+                                                             json_lsa);
+                               }
 
-                       LSDB_LOOP (AS_LSDB(ospf, type), rn, lsa)
-                               show_lsa_summary(vty, lsa, self);
+                               show_lsa_summary(vty, lsa, self, json_lsa);
+                       }
 
-                       vty_out(vty, "\n");
+                       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"
@@ -6348,23 +6773,53 @@ 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);
+       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_vrf, "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);
+       }
 
        /* Show all LSA. */
-       if (argc == arg_base + 4) {
-               show_ip_ospf_database_summary(vty, ospf, 0);
+       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;
        }
 
@@ -6382,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;
@@ -6397,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 {
@@ -6417,24 +6893,37 @@ 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);
                }
        }
 
-       return CMD_SUCCESS;
-}
-
-DEFUN (show_ip_ospf_database_max,
-       show_ip_ospf_database_max_cmd,
-       "show ip ospf [vrf <NAME|all>] database <max-age|self-originate>",
-       SHOW_STR
+       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_database_max,
+       show_ip_ospf_database_max_cmd,
+       "show ip ospf [vrf <NAME|all>] database <max-age|self-originate> [json]",
+       SHOW_STR
        IP_STR
        "OSPF information\n"
        VRF_CMD_HELP_STR
        "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;
@@ -6444,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);
 
@@ -6459,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)
@@ -6471,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 */
@@ -6483,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;
@@ -6491,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"
@@ -6502,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;
@@ -6513,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);
@@ -6522,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");
@@ -6537,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);
@@ -6547,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 */
@@ -6558,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;
@@ -6566,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);
 
@@ -6590,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;
 }
 
 
@@ -6598,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);
+       }
 
-       vty_out(vty, "\n       OSPF Router with ID (%s)\n\n",
-               inet_ntoa(ospf->router_id));
+       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);
+       }
 
        /* Set database type to show. */
        if (strncmp(argv[arg_base + idx_type]->text, "r", 1) == 0)
@@ -6643,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"
@@ -6660,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;
@@ -6671,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);
@@ -6683,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);
@@ -6700,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");
@@ -6712,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 */
@@ -6723,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));*/
@@ -8119,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);
@@ -8143,15 +8715,28 @@ DEFUN (ip_ospf_area,
                 * 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);
+                       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--;
+                               ospf->if_ospf_cli_count -= count;
                        }
                }
+
                return CMD_NOT_MY_INSTANCE;
        }
 
@@ -8165,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)) {
@@ -8184,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);
@@ -9193,6 +9778,88 @@ DEFPY(ospf_gr_helper_planned_only,
        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",
@@ -9215,7 +9882,7 @@ static int ospf_print_vty_helper_dis_rtr_walkcb(struct hash_bucket *backet,
        struct vty *vty = (struct vty *)arg;
        static unsigned int count;
 
-       vty_out(vty, "%-6s,", inet_ntoa(rtr->advRtrAddr));
+       vty_out(vty, "%-6pI4,", &rtr->advRtrAddr);
        count++;
 
        if (count % 5 == 0)
@@ -9230,6 +9897,7 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
 {
        struct listnode *node;
        struct ospf_interface *oi;
+       char buf[PREFIX_STRLEN];
        json_object *json_vrf = NULL;
 
        if (uj) {
@@ -9264,10 +9932,11 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
        /* Show Router ID. */
        if (uj) {
                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, "\n       OSPF Router with ID (%s)\n\n",
-                       inet_ntoa(ospf->router_id));
+               vty_out(vty, "\n       OSPF Router with ID (%pI4)\n\n",
+                       &ospf->router_id);
        }
 
        if (!uj) {
@@ -9379,11 +10048,10 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
 
                                if (!uj) {
                                        vty_out(vty, " Neighbour %d :\n", cnt);
-                                       vty_out(vty, "   Address  : %s\n",
-                                               inet_ntoa(nbr->address.u
-                                                                 .prefix4));
-                                       vty_out(vty, "   Routerid : %s\n",
-                                               inet_ntoa(nbr->router_id));
+                                       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
@@ -9407,11 +10075,14 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
                                        json_neigh = json_object_new_object();
                                        json_object_string_add(
                                                json_neigh, "srcAddr",
-                                               inet_ntoa(nbr->src));
+                                               inet_ntop(AF_INET, &nbr->src,
+                                                         buf, sizeof(buf)));
 
                                        json_object_string_add(
                                                json_neigh, "routerid",
-                                               inet_ntoa(nbr->router_id));
+                                               inet_ntop(AF_INET,
+                                                         &nbr->router_id,
+                                                         buf, sizeof(buf)));
                                        json_object_int_add(
                                                json_neigh,
                                                "recvdGraceInterval",
@@ -9434,12 +10105,100 @@ static int ospf_show_gr_helper_details(struct vty *vty, struct ospf *ospf,
                                                        .gr_restart_reason));
                                        json_object_object_add(
                                                json_neighbors,
-                                               inet_ntoa(nbr->src),
+                                               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;
 }
@@ -9546,6 +10305,21 @@ DEFPY (show_ip_ospf_gr_helper,
        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)
 {
@@ -9576,6 +10350,7 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
        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;
 
@@ -9584,11 +10359,11 @@ static void show_ip_ospf_route_network(struct vty *vty, struct ospf *ospf,
                        "============ 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;
-               char buf1[PREFIX2STR_BUFFER];
 
-               memset(buf1, 0, sizeof(buf1));
                prefix2str(&rn->p, buf1, sizeof(buf1));
 
                json_route = json_object_new_object();
@@ -9609,12 +10384,14 @@ static void show_ip_ospf_route_network(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,
+                                                         buf1, sizeof(buf1)));
                                } else {
                                        vty_out(vty,
-                                               "N IA %-18s    [%d] area: %s\n",
+                                               "N IA %-18s    [%d] area: %pI4\n",
                                                buf1, or->cost,
-                                               inet_ntoa(or->u.std.area_id));
+                                               &or->u.std.area_id);
                                }
                        } else if (or->type == OSPF_DESTINATION_DISCARD) {
                                if (json) {
@@ -9636,11 +10413,12 @@ static void show_ip_ospf_route_network(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,
+                                                 buf1, sizeof(buf1)));
                        } else {
-                               vty_out(vty, "N    %-18s    [%d] area: %s\n",
+                               vty_out(vty, "N    %-18s    [%d] area: %pI4\n",
                                        buf1, or->cost,
-                                       inet_ntoa(or->u.std.area_id));
+                                       &or->u.std.area_id);
                        }
                        break;
                default:
@@ -9689,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",
@@ -9699,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));
@@ -9727,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;
 
@@ -9741,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)) {
@@ -9761,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");
@@ -9774,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
@@ -9828,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",
@@ -9838,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));
@@ -9865,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;
 
@@ -9878,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);
@@ -9954,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(
@@ -9963,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));
@@ -10276,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) {
@@ -10306,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);
                }
        }
 
@@ -10340,6 +11130,265 @@ 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;
+               }
+               ret = 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. */
@@ -10388,9 +11437,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");
                                }
                        }
@@ -10425,8 +11473,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");
                        }
 
@@ -10436,8 +11484,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");
                        }
 
@@ -10449,9 +11497,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");
                                }
                        }
@@ -10461,8 +11508,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");
                        }
 
@@ -10472,8 +11519,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");
                        }
 
@@ -10494,8 +11541,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");
                        }
 
@@ -10506,8 +11553,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");
                        }
 
@@ -10519,8 +11566,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");
                        }
 
@@ -10531,8 +11578,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");
                        }
 
@@ -10550,8 +11597,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");
                        }
 
@@ -10567,8 +11614,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");
                        }
 
@@ -10632,9 +11679,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;
@@ -10705,9 +11750,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)
@@ -10720,8 +11764,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");
@@ -10755,7 +11799,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)
@@ -10799,21 +11843,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 */
@@ -10822,8 +11866,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);
                }
        }
@@ -10875,8 +11919,8 @@ static int ospf_cfg_write_helper_dis_rtr_walkcb(struct hash_bucket *backet,
        struct advRtr *rtr = backet->data;
        struct vty *vty = (struct vty *)arg;
 
-       vty_out(vty, " graceful-restart helper-only %s\n",
-               inet_ntoa(rtr->advRtrAddr));
+       vty_out(vty, " graceful-restart helper-only %pI4\n",
+               &rtr->advRtrAddr);
        return HASHWALK_CONTINUE;
 }
 
@@ -10886,7 +11930,8 @@ static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *ospf)
                vty_out(vty, " graceful-restart helper-only\n");
 
        if (!ospf->strict_lsa_check)
-               vty_out(vty, " no graceful-restart helper strict-lsa-checking\n");
+               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");
@@ -10900,6 +11945,30 @@ static int config_write_ospf_gr_helper(struct vty *vty, struct ospf *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;
 }
@@ -10975,9 +12044,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
                                                       : "");
                }
@@ -11010,8 +12078,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)
@@ -11074,6 +12142,9 @@ static int ospf_config_write_one(struct vty *vty, struct ospf *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");
@@ -11108,9 +12179,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. */
@@ -11220,8 +12291,10 @@ void ospf_vty_show_init(void)
 
        /* "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. */
@@ -11345,6 +12418,17 @@ static void ospf_vty_zebra_init(void)
        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 aa063a0759af436ef6c3116c2dfd5e4d8e20cb4f..a839806720ea22d39baef04b88216f31006aded1 100644 (file)
@@ -103,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;
 
@@ -123,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)) {
 
@@ -162,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,
@@ -312,6 +312,8 @@ static struct ospf *ospf_new(unsigned short instance, const char *name)
 
        ospf_gr_helper_init(new);
 
+       ospf_asbr_external_aggregator_init(new);
+
        QOBJ_REG(new, ospf);
 
        new->fd = -1;
@@ -385,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 */
@@ -398,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;
@@ -417,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);
        }
 
@@ -581,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;
@@ -628,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);
@@ -698,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);
@@ -766,6 +787,22 @@ 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);
 
@@ -1144,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
  */
@@ -1324,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)
@@ -1338,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))
@@ -1378,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) {
@@ -2158,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 5009355d48d3f2414631253e950f7ab9fd91b9fa..bdd09e1e766cb15398d4b3400ffcd608529ac25f 100644 (file)
@@ -355,6 +355,22 @@ struct ospf {
        /* 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;
 
@@ -535,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;
@@ -614,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 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 c423668ebd7de0e9b06263da018c618c832a288a..eb51516c24418eefbaec80028ca4b53acc8c1676 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);
@@ -1058,17 +1055,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",
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 f542b2eafaff0039e3cde20803578650a0f465cd..1acfece895a0aaeed020b01e19273355552facc5 100644 (file)
@@ -170,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);
@@ -184,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);
 
@@ -377,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);
@@ -402,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);
 }
@@ -616,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 */
@@ -625,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 38123cc8f67f647ef8b8c3b556a91e2363e73a76..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,
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 d4d47377bdb87246cfe3c38f25845e2205d05525..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);
        }
 }
@@ -900,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));
@@ -1000,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;
        }
 
@@ -1009,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;
@@ -1153,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 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 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 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 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 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 389a54f22432d0cafd7ff7b4b1617d173dd1a3ce..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);
@@ -3611,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 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 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 c2eb7c6ee4535ff05bd66e14180c64c1370e4d0e..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);
 
@@ -2730,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 077e2b29eb4ac39c3e3fd389a766fdbf572c6692..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);
index 0c3bf7af78f3e105efca5131dff13fa1fd24a4a0..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;
 }
index 6608811cc6d6efbd47796142516cbc4ab5340f65..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);
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 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 7ac8611bd95bf4c6a791858441289448ae901370..4c89a5be0a267663b79ef741a6fb5f513999e765 100644 (file)
@@ -66,7 +66,7 @@ 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, false);
+       isis_print_routes(vty, spftree, false, false);
 
        /* Cleanup SPF tree. */
        isis_spftree_del(spftree);
@@ -122,7 +122,7 @@ static void test_run_ti_lfa(struct vty *vty,
 
        /* Print the post-convergence SPT and the correspoding routing table. */
        isis_print_spftree(vty, spftree_pc);
-       isis_print_routes(vty, spftree_self, true);
+       isis_print_routes(vty, spftree_self, false, true);
 
        /* Cleanup everything. */
        isis_spftree_del(spftree_self);
index ea7cc14d7aecc91d976c079d4739fb6353cb54ed..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,12 @@ 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
@@ -732,10 +753,10 @@ rt2                  TE-IS        50     rt3                  -         rt4(4)
 \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     \r
- 10.0.255.4/32  50      -          rt3      16060     \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
@@ -768,10 +789,10 @@ rt2                  TE-IS        50     rt3                  -         rt4(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::2/128  60      -          rt3      16061     \r
- 2001:db8::4/128  50      -          rt3      16061     \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
@@ -818,9 +839,9 @@ rt3                  TE-IS        50     rt5                  -         rt5(4)
 \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  \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
@@ -866,9 +887,9 @@ rt3                  TE-IS        50     rt5                  -         rt5(4)
 \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  \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
@@ -906,11 +927,11 @@ rt5                  TE-IS        65     rt2                  -         rt1(2)
 \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  \r
- 10.0.255.5/32  75      -          rt2      16020/18  \r
- 10.0.255.6/32  75      -          rt2      16020/18  \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
@@ -947,11 +968,11 @@ rt5                  TE-IS        65     rt2                  -         rt1(2)
 \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  \r
- 2001:db8::5/128  75      -          rt2      16021/19  \r
- 2001:db8::6/128  75      -          rt2      16021/19  \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
@@ -992,11 +1013,11 @@ rt2                  TE-IS        45     rt6                  -         rt1(4)
 \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     \r
- 10.0.255.2/32  55      -          rt6      16040     \r
- 10.0.255.4/32  30      -          rt6              \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
@@ -1036,11 +1057,11 @@ rt2                  TE-IS        45     rt6                  -         rt1(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::1/128  40      -          rt6      16041     \r
- 2001:db8::2/128  55      -          rt6      16041     \r
- 2001:db8::4/128  30      -          rt6              \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
@@ -1088,10 +1109,10 @@ IS-IS L1 IPv4 routing table:
 \r
  Prefix         Metric  Interface  Nexthop  Label(s)  \r
  -----------------------------------------------------\r
- 10.0.255.1/32  50      -          rt3      -         \r
-                        -          rt6      -         \r
- 10.0.255.2/32  40      -          rt6      -         \r
- 10.0.255.4/32  30      -          rt6      -         \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
@@ -1176,12 +1197,12 @@ rt2                  TE-IS        90     rt3                  -         rt4(4)
 \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  \r
- 10.0.255.4/32  90      -          rt3      16050/17  \r
- 10.0.255.6/32  80      -          rt3      16050/17  \r
- 10.0.255.8/32  90      -          rt3      16050/17  \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
@@ -1223,10 +1244,10 @@ rt8                  TE-IS        100    rt2                  -         rt6(4)
 \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  \r
- 10.0.255.8/32  110     -          rt2      16050/17  \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
@@ -1267,11 +1288,11 @@ rt2                  TE-IS        70     rt3                  -         rt4(4)
 \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     \r
- 10.0.255.4/32  70      -          rt3      16080     \r
- 10.0.255.6/32  60      -          rt3      16080     \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
@@ -1317,9 +1338,9 @@ rt7                  TE-IS        30     rt6                  -         rt5(4)
 \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     \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
@@ -1378,16 +1399,16 @@ rt3                  TE-IS        60     rt12                 -         rt6(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.1/32  60      -          rt10             \r
- 10.0.255.2/32  60      -          rt12     16090     \r
- 10.0.255.3/32  70      -          rt12     16090     \r
- 10.0.255.4/32  50      -          rt10             \r
- 10.0.255.5/32  50      -          rt12     16090     \r
- 10.0.255.6/32  60      -          rt12     16090     \r
- 10.0.255.7/32  40      -          rt10             \r
- 10.0.255.8/32  40      -          rt12     16090     \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
@@ -1458,19 +1479,19 @@ rt10                 TE-IS        60     rt9                  -         rt11(4)
 \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     \r
- 10.0.255.4/32   50      -          rt3      16020     \r
- 10.0.255.5/32   40      -          rt3      16020     \r
- 10.0.255.7/32   60      -          rt9              \r
-                         -          rt3              \r
- 10.0.255.8/32   50      -          rt9              \r
-                         -          rt3              \r
- 10.0.255.10/32  70      -          rt9              \r
-                         -          rt3              \r
- 10.0.255.11/32  60      -          rt9              \r
-                         -          rt3              \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
@@ -1532,12 +1553,12 @@ rt1                  TE-IS        90     rt5                  -         rt4(4)
 \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  \r
- 10.0.255.4/32   90      -          rt5      16110/17  \r
- 10.0.255.7/32   80      -          rt5      16110/17  \r
- 10.0.255.10/32  70      -          rt5      16110/17  \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
@@ -1595,13 +1616,13 @@ rt12                 TE-IS        60     rt3                  -         rt9(4)
 \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     \r
- 10.0.255.8/32   50      -          rt3      16060     \r
- 10.0.255.9/32   60      -          rt3      16060     \r
- 10.0.255.11/32  60      -          rt3      16060     \r
- 10.0.255.12/32  70      -          rt3      16060     \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
@@ -1651,9 +1672,9 @@ rt3                  TE-IS        120    rt2                  -         rt4(4)
 \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  \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
@@ -1702,9 +1723,9 @@ rt3                  TE-IS        120    rt2                  -         rt4(4)
 \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  \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
@@ -1748,15 +1769,15 @@ rt8                  TE-IS        140    rt3                  -         rt4(4)
 \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  \r
- 10.0.255.4/32  120     -          rt3      16030/18  \r
- 10.0.255.5/32  130     -          rt3      16030/18  \r
- 10.0.255.6/32  150     -          rt3      16030/18  \r
- 10.0.255.7/32  150     -          rt3      16030/18  \r
- 10.0.255.8/32  150     -          rt3      16030/18  \r
- 10.0.255.9/32  140     -          rt3      16030/18  \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
@@ -1799,15 +1820,15 @@ rt8                  TE-IS        140    rt3                  -         rt4(4)
 \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  \r
- 2001:db8::4/128  120     -          rt3      16031/19  \r
- 2001:db8::5/128  130     -          rt3      16031/19  \r
- 2001:db8::6/128  150     -          rt3      16031/19  \r
- 2001:db8::7/128  150     -          rt3      16031/19  \r
- 2001:db8::8/128  150     -          rt3      16031/19  \r
- 2001:db8::9/128  140     -          rt3      16031/19  \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
@@ -1874,23 +1895,23 @@ rt3                  TE-IS        70     rt6                  -         rt1(4)
 \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  \r
-                        -          rt7      16070/16  \r
-                        -          rt8      16080/16  \r
- 10.0.255.2/32  60      -          rt6      16060/16  \r
-                        -          rt7      16070/16  \r
-                        -          rt8      16080/16  \r
- 10.0.255.3/32  80      -          rt6      16060/16  \r
-                        -          rt7      16070/16  \r
-                        -          rt8      16080/16  \r
- 10.0.255.4/32  50      -          rt6      16060/16  \r
-                        -          rt7      16070/16  \r
-                        -          rt8      16080/16  \r
- 10.0.255.5/32  60      -          rt6      16060/16  \r
-                        -          rt7      16070/16  \r
-                        -          rt8      16080/16  \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
@@ -1956,23 +1977,23 @@ rt3                  TE-IS        70     rt6                  -         rt1(4)
 \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  \r
-                          -          rt7      16071/17  \r
-                          -          rt8      16081/17  \r
- 2001:db8::2/128  60      -          rt6      16061/17  \r
-                          -          rt7      16071/17  \r
-                          -          rt8      16081/17  \r
- 2001:db8::3/128  80      -          rt6      16061/17  \r
-                          -          rt7      16071/17  \r
-                          -          rt8      16081/17  \r
- 2001:db8::4/128  50      -          rt6      16061/17  \r
-                          -          rt7      16071/17  \r
-                          -          rt8      16081/17  \r
- 2001:db8::5/128  60      -          rt6      16061/17  \r
-                          -          rt7      16071/17  \r
-                          -          rt8      16081/17  \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
@@ -2023,9 +2044,9 @@ rt3                  TE-IS        50     rt5                  -         rt1(4)
 \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  \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
@@ -2075,9 +2096,9 @@ rt3                  TE-IS        50     rt5                  -         rt1(4)
 \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  \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
@@ -2126,14 +2147,14 @@ rt2                  TE-IS        100    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  110     -          rt3      20060/18  \r
-                        -          rt4      16070/18  \r
- 10.0.255.5/32  100     -          rt3      20060/18  \r
-                        -          rt4      16070/18  \r
- 10.0.255.8/32  90      -          rt3      20060/18  \r
-                        -          rt4      16070/18  \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
@@ -2181,14 +2202,14 @@ rt2                  TE-IS        100    rt3                  -         rt5(4)
 \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  \r
-                          -          rt4      16071/19  \r
- 2001:db8::5/128  100     -          rt3      20061/19  \r
-                          -          rt4      16071/19  \r
- 2001:db8::8/128  90      -          rt3      20061/19  \r
-                          -          rt4      16071/19  \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
@@ -2232,10 +2253,10 @@ rt4                  TE-IS        90     rt2                  -         rt7(4)
 \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  \r
- 10.0.255.7/32  90      -          rt2      16080/20  \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
@@ -2278,10 +2299,10 @@ rt4                  TE-IS        90     rt2                  -         rt7(4)
 \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  \r
- 2001:db8::7/128  90      -          rt2      16081/21  \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
@@ -2322,13 +2343,13 @@ rt6                  TE-IS        70     rt3                  -         rt5(4)
 \r
 IS-IS L1 IPv4 routing table:\r
 \r
- Prefix         Metric  Interface  Nexthop  Label(s)  \r
- -----------------------------------------------------\r
- 10.0.255.1/32  60      -          rt1      -         \r
- 10.0.255.3/32  60      -          rt3      -         \r
- 10.0.255.4/32  80      -          rt3      16050     \r
- 10.0.255.5/32  70      -          rt3      -         \r
- 10.0.255.6/32  80      -          rt3      -         \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
@@ -2368,13 +2389,13 @@ rt6                  TE-IS        70     rt3                  -         rt5(4)
 \r
 IS-IS L1 IPv6 routing table:\r
 \r
- Prefix           Metric  Interface  Nexthop  Label(s)  \r
- -------------------------------------------------------\r
- 2001:db8::1/128  60      -          rt1      -         \r
- 2001:db8::3/128  60      -          rt3      -         \r
- 2001:db8::4/128  80      -          rt3      16051     \r
- 2001:db8::5/128  70      -          rt3      -         \r
- 2001:db8::6/128  80      -          rt3      -         \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
@@ -2419,12 +2440,12 @@ rt3                  TE-IS        740    rt2                  -         rt5(4)
 \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  \r
- 10.0.255.5/32  350     -          rt2      16080/17/16     \r
- 10.0.255.7/32  150     -          rt2      16080/17        \r
- 10.0.255.9/32  160     -          rt2      16080/17/18     \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
@@ -2461,12 +2482,12 @@ 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.3/32  40      -          rt2      16040     \r
- 10.0.255.5/32  50      -          rt2      16040     \r
- 10.0.255.6/32  50      -          rt2      16040     \r
- 10.0.255.7/32  60      -          rt2      16040     \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 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 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 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 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 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 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 8a8a49a23e7cc9beb9e279b78373b975d91b1ece..4c56d1a02d81cc0ae60694d9c143501657da3d0f 100644 (file)
@@ -658,6 +658,125 @@ 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:]
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 277c6603adecbf6a5d02b41cc5ee5d6d23b21971..e0f6ab601f72b2fadb748615a3df5c9374ca0b58 100644 (file)
@@ -13,5 +13,9 @@ neighbor 10.0.0.1 {
     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;
   }
 }
index 4e1406177df7fca70fed2d9d1d4852e75f42ead0..fa5215008556947f8df2ffc9815a0d2602819f80 100644 (file)
@@ -1,3 +1,20 @@
+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
@@ -8,5 +25,6 @@ router bgp 65000
    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
 !
index d3656b87016935ed654573a73749a92d58b16cf0..3f3b71dea3e4fc8b563b03f577b88b1fd1a0137e 100644 (file)
@@ -85,6 +85,20 @@ def teardown_module(mod):
     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."
 
@@ -185,6 +199,79 @@ aggregate-address 192.168.1.0/24 matching-MED-only summary-only
     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()
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 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 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 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 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 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 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 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 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 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 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 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 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 ccea94c42c3ba1778c08ee05da2329ad3130f9a0..1a9307ddb99f7d4bdd7aabab7083c84c0c95c896 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step3/show_ip_route.ref        2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step4/show_ip_route.ref        2020-08-31 22:42:48.831561460 -0300
+--- 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",
index 13e098858a24a0a62519272b66fdb25671a5be8d..f5036aeda82c15efe7d8f742f9dc7d1d52fd0692 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step3/show_ipv6_route.ref      2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step4/show_ipv6_route.ref      2020-08-31 22:42:48.831561460 -0300
+--- 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",
index 9531fbc2f065deda11ddfdf9cdfe8036d3f660ee..30c612b5449bf5f9f64eadcfbbfd5c5acc0fad59 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step3/show_mpls_table.ref      2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step4/show_mpls_table.ref      2020-08-31 22:42:48.831561460 -0300
+--- 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 @@
        }
      ]
index 2a2cb762a7661de8b0133905be4b0a8c6cc4093c..79a452ef69f8c5ee0c4325ce1d8956241714638a 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step4/show_ip_route.ref        2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step5/show_ip_route.ref        2020-08-31 22:42:48.831561460 -0300
+--- 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",
index 94bf3c1db31d2b99bddef3523f6c245f0ecf8a38..805266aaaa920f2a0cbf1ed5a2f70334bcbc160c 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step4/show_ipv6_route.ref      2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step5/show_ipv6_route.ref      2020-08-31 22:42:48.831561460 -0300
+--- 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",
index 0fd252e45574f93c15762a6e5664ea6fd93abe05..d7ab66ee189b0710cbd6fcfa081bdfd40f5e1045 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step4/show_mpls_table.ref      2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step5/show_mpls_table.ref      2020-08-31 22:42:48.831561460 -0300
+--- 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 @@
        }
      ]
index 22f7ce9a2e6097a2cd401eba4c5cb7ffc7a095e2..9aa0cd2e39ae493a2878eaab8204256d453d85a9 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step6/show_ip_route.ref        2020-08-31 22:42:48.831561460 -0300
-+++ rt1/step7/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
+--- 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",
index 4b07bd77626dcda9cd813a60a673edd736bb64d2..52fd7caf915b7579477b41656744c637c6248b0a 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step6/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step7/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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",
index b62ca10fa354bb3447b5955ab297d2bf73cf0d0f..53332be5691323ea3f077c8c7646f92140b08a43 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step6/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step7/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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 @@
        }
      ]
index 2bf88c8346a2eecaee84a95771f6533543c0afb9..af9f72e718afb4b3a24d01a81c94b3578b9739bc 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step7/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step8/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
+--- 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",
index a01038a7a800a9023422d6555494669f9c77a895..b733b33ed9d9bfb00dbcafe1447f307c1b668605 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step7/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step8/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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",
index e3f83613158f70b226b640880ef0fbb7de12751a..b6f8c962f0fc7f8e6855af0fc8e75189c3242f52 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step7/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step8/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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 @@
        }
      ]
index c10f97b86af1083ea1756105bfd3b5b6eb9c68ed..1d963415571ccb262bc2e74f9bc5b4b3eeedc7c8 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step8/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step9/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
+--- 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,
index 7a909f64101c843fe4a687c8bc7b0be56926f343..232b823ac2bcc5c18da9bd360b78b824c8c7993c 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step8/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step9/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
index b794a674f8d2fd498110a2387938500b84561a9b..7f0d50f5f2263a6add1f74935622a20dbbab9675 100644 (file)
@@ -1,5 +1,5 @@
---- rt1/step8/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt1/step9/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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 @@
        }
      ]
index 7c6f6f8b65e5b60cce2fcd70127dc8f0dbf268c2..23e07b7cdad329c08e3d1b73dda0037306e936b4 100644 (file)
@@ -31,7 +31,8 @@
           "interfaceName":"eth-rt4-1",
           "active":true,
           "labels":[
-            16050
+            16050,
+            16010
           ]
         },
         {
@@ -40,7 +41,8 @@
           "interfaceName":"eth-rt4-2",
           "active":true,
           "labels":[
-            16050
+            16050,
+            16010
           ]
         }
       ]
@@ -78,7 +80,8 @@
           "interfaceName":"eth-rt4-1",
           "active":true,
           "labels":[
-            16050
+            16050,
+            16030
           ]
         },
         {
@@ -87,7 +90,8 @@
           "interfaceName":"eth-rt4-2",
           "active":true,
           "labels":[
-            16050
+            16050,
+            16030
           ]
         }
       ]
           "afi":"ipv4",
           "interfaceName":"eth-rt4-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
           "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
+          ]
+        }
       ]
     }
   ],
           "afi":"ipv4",
           "interfaceName":"eth-rt4-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16060
           ]
           "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
+        }
       ]
     }
   ],
           "ip":"10.0.2.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4-1",
-          "active":true
+          "active":true,
+          "labels":[
+            16050
+          ]
         },
         {
           "ip":"10.0.3.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4-2",
-          "active":true
+          "active":true,
+          "labels":[
+            16050
+          ]
         }
       ]
     }
         {
           "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
+          ]
         }
       ]
     }
           "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
+          ]
         }
       ]
     }
           "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,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.3",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
           "active":true
         }
       ]
           "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
+          ]
         }
       ]
     }
index 68569b7265b8ec9e4180b710e038b3efc5d131da..d9bd04ef30f5dc228f99f8e37030546460f3dfa8 100644 (file)
@@ -29,7 +29,8 @@
           "interfaceName":"eth-rt4-1",
           "active":true,
           "labels":[
-            16051
+            16051,
+            16011
           ]
         },
         {
@@ -37,7 +38,8 @@
           "interfaceName":"eth-rt4-2",
           "active":true,
           "labels":[
-            16051
+            16051,
+            16011
           ]
         }
       ]
@@ -73,7 +75,8 @@
           "interfaceName":"eth-rt4-1",
           "active":true,
           "labels":[
-            16051
+            16051,
+            16031
           ]
         },
         {
@@ -81,7 +84,8 @@
           "interfaceName":"eth-rt4-2",
           "active":true,
           "labels":[
-            16051
+            16051,
+            16031
           ]
         }
       ]
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4-1",
+          "interfaceName":"eth-rt4-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4-2",
+          "interfaceName":"eth-rt4-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16051,
+            16041
+          ]
+        }
       ]
     }
   ],
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4-1",
+          "interfaceName":"eth-sw1",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-sw1",
+          "interfaceName":"eth-rt4-2",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4-2",
+          "interfaceName":"eth-rt4-1",
           "active":true,
           "labels":[
             16051
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4-1",
+          "interfaceName":"eth-rt4-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16061
           ]
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4-2",
+          "interfaceName":"eth-rt4-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16061
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
       ]
     }
   ]
index 4c18e20472470a814c140b81de5f226e64defec5..cd2f879593a0015ce8b20a5f1cd80cc739d36eb2 100644 (file)
         "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"
       }
     ]
   },
         "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"
+        "interface":"eth-rt4-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16051,
+        "interface":"eth-sw1"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.3.4"
+        "nexthop":"10.0.3.4",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.2.4"
+        "nexthop":"10.0.2.4",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.1.3"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-2"
+        "interface":"eth-rt4-2",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt4-1"
+        "interface":"eth-rt4-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-sw1"
       }
     ]
   }
index 24237769e996a712b57d6f049fc119c9b70000e1..22b896f6840e5678c83cc15d34b29ec57b501210 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step1/show_ip_route.ref        2020-08-31 15:36:25.999825589 -0300
-+++ rt2/step2/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-@@ -15,34 +15,10 @@
+--- 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,
@@ -20,7 +20,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16010
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16010
 -          ]
 -        }
        ]
      }
    ],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -55,7 +57,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16030
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16030
 -          ]
 -        }
        ]
      }
    ],
-@@ -212,34 +164,12 @@
+@@ -248,40 +196,12 @@
          {
            "ip":"10.0.1.1",
            "afi":"ipv4",
 -          "ip":"10.0.2.4",
 -          "afi":"ipv4",
 -          "interfaceName":"eth-rt4-1",
--          "active":true
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
 -        },
 -        {
 -          "ip":"10.0.3.4",
 -          "afi":"ipv4",
 -          "interfaceName":"eth-rt4-2",
--          "active":true
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
 +          "interfaceName":"eth-sw1"
          }
        ]
      }
-@@ -301,24 +231,6 @@
+@@ -377,24 +297,6 @@
            "ip":"10.0.1.3",
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true
          }
        ]
-@@ -339,24 +251,6 @@
+@@ -415,24 +317,6 @@
            "ip":"10.0.1.3",
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
index 7c9f1e965a9fba03748588e4da51ddd54213704a..08c7d2b1fcc8ff2116c5cf68151f45b0e8eba62b 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step1/show_ipv6_route.ref      2020-08-31 15:36:25.999825589 -0300
-+++ rt2/step2/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-@@ -14,32 +14,10 @@
+--- 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,
@@ -19,7 +19,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16011
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16011
 -          ]
 -        }
        ]
      }
    ],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -52,7 +54,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16031
 -          ]
 -        },
 -        {
@@ -60,7 +63,8 @@
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16031
 -          ]
 -        }
        ]
index 1c3e037b96bf89a4ddaff5d29afa0e041744ee3f..4feb927156ad2ffa1b19d704285e71cef2b6d9c4 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step1/show_mpls_table.ref      2020-08-31 15:36:25.999825589 -0300
-+++ rt2/step2/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
index 4613c2c63da920a40e509b5b9bb3719f37f2752b..af1cebc76da0c658b09cc8340c7cae3244967399 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step2/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step3/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-@@ -15,10 +15,34 @@
+--- 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,
@@ -20,7 +20,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16010
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16010
 +          ]
 +        }
        ]
      }
    ],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -55,7 +57,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16030
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16030
 +          ]
 +        }
        ]
      }
    ],
-@@ -164,12 +212,34 @@
+@@ -196,12 +248,40 @@
          {
            "ip":"10.0.1.1",
            "afi":"ipv4",
 +          "ip":"10.0.2.4",
 +          "afi":"ipv4",
 +          "interfaceName":"eth-rt4-1",
-+          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
 +        },
 +        {
 +          "ip":"10.0.3.4",
 +          "afi":"ipv4",
 +          "interfaceName":"eth-rt4-2",
-+          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
          }
        ]
      }
-@@ -231,6 +301,24 @@
+@@ -297,6 +377,24 @@
            "ip":"10.0.1.3",
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true
          }
        ]
-@@ -251,6 +339,24 @@
+@@ -317,6 +415,24 @@
            "ip":"10.0.1.3",
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
index 84b528336078f5917d8918d26650d8d03ad5e3c8..9809c316e87f06d2c7372990f147c00243d343f7 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step2/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step3/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-@@ -14,10 +14,32 @@
+--- 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,
@@ -19,7 +19,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16011
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16011
 +          ]
 +        }
        ]
      }
    ],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -52,7 +54,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16031
 +          ]
 +        },
 +        {
@@ -60,7 +63,8 @@
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16031
 +          ]
 +        }
        ]
index 5dc90e442c094e9f0e0bd5603253fce60f3d42de..180323e4c830a22639cc4488600150d354be210a 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step2/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step3/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
index f703db555ff7a8e9fd40e65d3b0bd92740ac9898..12d45bbe07af85d774c1665017a10ed9af0ad6ac 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step3/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step4/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-@@ -15,34 +15,10 @@
+--- 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,
@@ -20,7 +20,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16010
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16010
 -          ]
 -        }
        ]
      }
    ],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -55,7 +57,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16030
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16030
 -          ]
 -        }
        ]
      }
    ],
-@@ -108,20 +60,14 @@
-           "ip":"10.0.2.4",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt4-1",
--          "active":true,
+@@ -115,9 +63,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
 -          "labels":[
 -            3
--          ]
-+          "active":true
+           ]
          },
          {
-           "fib":true,
-           "ip":"10.0.3.4",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt4-2",
--          "active":true,
+@@ -128,9 +73,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
 -          "labels":[
 -            3
--          ]
-+          "active":true
-         }
-       ]
-     }
-@@ -153,7 +99,7 @@
-           "interfaceName":"eth-rt4-1",
-           "active":true,
-           "labels":[
--            16050
-+            3
            ]
-         },
-         {
-@@ -163,7 +109,7 @@
-           "interfaceName":"eth-rt4-2",
+         }
+       ],
+@@ -141,8 +83,7 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
--            16050
-+            3
+-            16050,
+-            16040
++            16050
            ]
          }
        ]
-@@ -184,20 +130,14 @@
+@@ -173,20 +114,14 @@
            "ip":"10.0.2.4",
            "afi":"ipv4",
            "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16060
+-            16050
 -          ]
 +          "active":true
          },
            "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16060
+-            16050
 -          ]
 +          "active":true
          }
        ]
      }
-@@ -212,34 +152,12 @@
+@@ -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",
 -          "ip":"10.0.2.4",
 -          "afi":"ipv4",
 -          "interfaceName":"eth-rt4-1",
--          "active":true
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
 -        },
 -        {
 -          "ip":"10.0.3.4",
 -          "afi":"ipv4",
 -          "interfaceName":"eth-rt4-2",
--          "active":true
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
 +          "interfaceName":"eth-sw1"
          }
        ]
index fdd4a5166e800399d5c0236ed3a4d78b5de01444..fdf658d59d2191f0d9dd2038ebf7173f8639370c 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step3/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step4/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-@@ -14,32 +14,10 @@
+--- 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,
@@ -19,7 +19,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16011
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16011
 -          ]
 -        }
        ]
      }
    ],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -52,7 +54,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16031
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16031
 -          ]
 -        }
        ]
      }
    ],
-@@ -101,19 +57,13 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt4-1",
--          "active":true,
+@@ -108,9 +60,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
 -          "labels":[
 -            3
--          ]
-+          "active":true
+           ]
          },
          {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt4-2",
--          "active":true,
+@@ -120,9 +69,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
 -          "labels":[
 -            3
--          ]
-+          "active":true
-         }
-       ]
-     }
-@@ -134,7 +84,7 @@
-           "interfaceName":"eth-rt4-1",
-           "active":true,
-           "labels":[
--            16051
-+            3
            ]
-         },
-         {
-@@ -152,7 +102,7 @@
-           "interfaceName":"eth-rt4-2",
+         }
+       ],
+@@ -132,8 +78,7 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
--            16051
-+            3
+-            16051,
+-            16041
++            16051
            ]
          }
        ]
-@@ -172,19 +122,13 @@
+@@ -162,19 +107,13 @@
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt4-1",
+           "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16061
+-            16051
 -          ]
 +          "active":true
          },
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt4-2",
+           "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16061
+-            16051
 -          ]
 +          "active":true
          }
        ]
      }
+@@ -196,9 +135,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16061
+           ]
+         },
+         {
+@@ -208,9 +144,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            16061
+           ]
+         }
+       ],
index dcc4532e54185c509e7f8762d2771f6b00c6b326..a78f79c5765a5f2cba0f558e43e046603586bb49 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step3/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step4/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
@@ -75,7 +75,7 @@
        }
      ]
    },
-@@ -91,59 +43,7 @@
+@@ -91,84 +43,6 @@
          "type":"SR (IS-IS)",
          "outLabel":3,
          "installed":true,
 -        "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"
 -      }
 -    ]
 -  },
 -        "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"
-+        "interface":"eth-sw1"
-       }
-     ]
-   },
-@@ -153,13 +53,13 @@
-     "nexthops":[
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16050,
-+        "outLabel":3,
-         "installed":true,
-         "nexthop":"10.0.3.4"
-       },
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16050,
-+        "outLabel":3,
-         "installed":true,
-         "nexthop":"10.0.2.4"
-       },
-@@ -177,13 +77,13 @@
-     "nexthops":[
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16051,
-+        "outLabel":3,
-         "installed":true,
-         "interface":"eth-rt4-2"
-       },
-       {
-         "type":"SR (IS-IS)",
+-        "interface":"eth-rt4-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
 -        "outLabel":16051,
-+        "outLabel":3,
-         "installed":true,
-         "interface":"eth-rt4-1"
-       },
-@@ -194,41 +94,5 @@
          "interface":"eth-sw1"
        }
      ]
--  },
--  "16060":{
--    "inLabel":16060,
--    "installed":true,
--    "nexthops":[
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":16060,
--        "installed":true,
+@@ -181,18 +55,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16050,
+         "installed":true,
 -        "nexthop":"10.0.3.4"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
--        "outLabel":16060,
+-        "outLabel":16050,
 -        "installed":true,
 -        "nexthop":"10.0.2.4"
--      }
--    ]
--  },
--  "16061":{
--    "inLabel":16061,
--    "installed":true,
--    "nexthops":[
+-      },
 -      {
 -        "type":"SR (IS-IS)",
--        "outLabel":16061,
+-        "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":16061,
+-        "outLabel":16051,
 -        "installed":true,
 -        "interface":"eth-rt4-1"
--      }
--    ]
-   }
- }
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16051,
+         "installed":true,
+         "interface":"eth-sw1"
+       }
index 22a5cb6579e0ef6b64fb8a2aad0a85824f24eef7..7d20fad3f453615837f407148f02fc5983e1c9dd 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step4/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step5/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-@@ -15,10 +15,34 @@
+--- 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,
@@ -20,7 +20,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16010
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16010
 +          ]
 +        }
        ]
      }
    ],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -55,7 +57,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16030
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16030
 +          ]
 +        }
        ]
      }
    ],
-@@ -60,14 +108,20 @@
-           "ip":"10.0.2.4",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt4-1",
--          "active":true
-+          "active":true,
+@@ -63,6 +115,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
 +          "labels":[
 +            3
-+          ]
+           ]
          },
          {
-           "fib":true,
-           "ip":"10.0.3.4",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt4-2",
--          "active":true
-+          "active":true,
+@@ -73,6 +128,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
 +          "labels":[
 +            3
-+          ]
-         }
-       ]
-     }
-@@ -99,7 +153,7 @@
-           "interfaceName":"eth-rt4-1",
-           "active":true,
-           "labels":[
--            3
-+            16050
            ]
-         },
-         {
-@@ -109,7 +163,7 @@
-           "interfaceName":"eth-rt4-2",
+         }
+       ],
+@@ -83,7 +141,8 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
--            3
-+            16050
+-            16050
++            16050,
++            16040
            ]
          }
        ]
-@@ -130,14 +184,20 @@
+@@ -114,14 +173,20 @@
            "ip":"10.0.2.4",
            "afi":"ipv4",
            "interfaceName":"eth-rt4-1",
 -          "active":true
 +          "active":true,
 +          "labels":[
-+            16060
++            16050
 +          ]
          },
          {
 -          "active":true
 +          "active":true,
 +          "labels":[
-+            16060
++            16050
 +          ]
          }
        ]
      }
-@@ -152,12 +212,34 @@
+@@ -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",
 +          "ip":"10.0.2.4",
 +          "afi":"ipv4",
 +          "interfaceName":"eth-rt4-1",
-+          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
 +        },
 +        {
 +          "ip":"10.0.3.4",
 +          "afi":"ipv4",
 +          "interfaceName":"eth-rt4-2",
-+          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
          }
        ]
      }
index 819a153f7a430340edd19143d0fb9d44646f6c57..93309643388cfd390be6b781ee73f52d3c07ca91 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step4/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step5/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-@@ -14,10 +14,32 @@
+--- 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,
@@ -19,7 +19,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16011
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16011
 +          ]
 +        }
        ]
      }
    ],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -52,7 +54,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16031
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16031
 +          ]
 +        }
        ]
      }
    ],
-@@ -57,13 +101,19 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt4-1",
--          "active":true
-+          "active":true,
+@@ -60,6 +108,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
 +          "labels":[
 +            3
-+          ]
+           ]
          },
          {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt4-2",
--          "active":true
-+          "active":true,
+@@ -69,6 +120,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
 +          "labels":[
 +            3
-+          ]
-         }
-       ]
-     }
-@@ -84,7 +134,7 @@
-           "interfaceName":"eth-rt4-1",
-           "active":true,
-           "labels":[
--            3
-+            16051
            ]
-         },
-         {
-@@ -102,7 +152,7 @@
-           "interfaceName":"eth-rt4-2",
+         }
+       ],
+@@ -78,7 +132,8 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
--            3
-+            16051
+-            16051
++            16051,
++            16041
            ]
          }
        ]
-@@ -122,13 +172,19 @@
+@@ -107,13 +162,19 @@
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt4-1",
+           "interfaceName":"eth-rt4-2",
 -          "active":true
 +          "active":true,
 +          "labels":[
-+            16061
++            16051
 +          ]
          },
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt4-2",
+           "interfaceName":"eth-rt4-1",
 -          "active":true
 +          "active":true,
 +          "labels":[
-+            16061
++            16051
 +          ]
          }
        ]
      }
+@@ -135,6 +196,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16061
+           ]
+         },
+         {
+@@ -144,6 +208,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            16061
+           ]
+         }
+       ],
index 7f851effadd9c2e20f5dcc57dfe46880931fc597..b1e44a727f2b87e142ac5f303d62565846a15b32 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step4/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step5/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
        }
      ]
    },
-@@ -43,12 +91,28 @@
+@@ -43,6 +91,84 @@
          "type":"SR (IS-IS)",
          "outLabel":3,
          "installed":true,
--        "interface":"eth-sw1"
 +        "interface":"eth-sw1",
 +        "backupIndex":[
 +          0,
 +        "type":"SR (IS-IS)",
 +        "outLabel":16051,
 +        "interface":"eth-rt4-2"
-       }
-     ]
-   },
--  "16050":{
--    "inLabel":16050,
-+  "16040":{
-+    "inLabel":16040,
-     "installed":true,
-     "nexthops":[
-       {
-@@ -62,6 +126,42 @@
-         "outLabel":3,
-         "installed":true,
-         "nexthop":"10.0.2.4"
 +      }
 +    ]
 +  },
-+  "16041":{
-+    "inLabel":16041,
++  "16040":{
++    "inLabel":16040,
 +    "installed":true,
 +    "nexthops":[
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "installed":true,
-+        "interface":"eth-rt4-2"
++        "nexthop":"10.0.3.4",
++        "backupIndex":[
++          0
++        ]
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "installed":true,
-+        "interface":"eth-rt4-1"
++        "nexthop":"10.0.2.4",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16050,
++        "nexthop":"10.0.1.3"
 +      }
 +    ]
 +  },
-+  "16050":{
-+    "inLabel":16050,
++  "16041":{
++    "inLabel":16041,
 +    "installed":true,
 +    "nexthops":[
 +      {
 +        "type":"SR (IS-IS)",
-+        "outLabel":16050,
++        "outLabel":3,
 +        "installed":true,
-+        "nexthop":"10.0.3.4"
++        "interface":"eth-rt4-2",
++        "backupIndex":[
++          0
++        ]
 +      },
 +      {
 +        "type":"SR (IS-IS)",
-+        "outLabel":16050,
++        "outLabel":3,
 +        "installed":true,
-+        "nexthop":"10.0.2.4"
-       },
-       {
-         "type":"SR (IS-IS)",
-@@ -77,13 +177,13 @@
-     "nexthops":[
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":3,
-+        "outLabel":16051,
-         "installed":true,
-         "interface":"eth-rt4-2"
-       },
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":3,
++        "interface":"eth-rt4-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
 +        "outLabel":16051,
-         "installed":true,
-         "interface":"eth-rt4-1"
-       },
-@@ -94,5 +194,41 @@
          "interface":"eth-sw1"
        }
      ]
-+  },
-+  "16060":{
-+    "inLabel":16060,
-+    "installed":true,
-+    "nexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":16060,
-+        "installed":true,
+@@ -55,6 +181,18 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16050,
+         "installed":true,
 +        "nexthop":"10.0.3.4"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
-+        "outLabel":16060,
++        "outLabel":16050,
 +        "installed":true,
 +        "nexthop":"10.0.2.4"
-+      }
-+    ]
-+  },
-+  "16061":{
-+    "inLabel":16061,
-+    "installed":true,
-+    "nexthops":[
++      },
 +      {
 +        "type":"SR (IS-IS)",
-+        "outLabel":16061,
++        "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":16061,
++        "outLabel":16051,
 +        "installed":true,
 +        "interface":"eth-rt4-1"
-+      }
-+    ]
-   }
- }
++      },
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16051,
+         "installed":true,
+         "interface":"eth-sw1"
+       }
index 109ab8ea6aafda3b73ca1d38a84508e012060601..c92195d7040a9f97d4d952d4dae99b2990a21bc3 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step6/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step7/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-@@ -15,34 +15,10 @@
+--- 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,
@@ -20,7 +20,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16010
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16010
 -          ]
 -        }
        ]
      }
    ],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -55,7 +57,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16030
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16050
+-            16050,
+-            16030
 -          ]
 -        }
        ]
      }
    ],
-@@ -141,30 +93,21 @@
+@@ -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",
          }
        ]
      }
-@@ -212,34 +155,12 @@
+@@ -248,40 +169,12 @@
          {
            "ip":"10.0.1.1",
            "afi":"ipv4",
 -          "ip":"10.0.2.4",
 -          "afi":"ipv4",
 -          "interfaceName":"eth-rt4-1",
--          "active":true
+-          "active":true,
+-          "labels":[
+-            16050
+-          ]
 -        },
 -        {
 -          "ip":"10.0.3.4",
 -          "afi":"ipv4",
 -          "interfaceName":"eth-rt4-2",
--          "active":true
+-          "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
+         }
+       ]
+     }
index 871fd98b7eb03dcd012a414547e61f87d8a7b60b..140c7b08bf1daee2143f87ed74756ec183976325 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step6/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step7/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-@@ -14,32 +14,10 @@
+--- 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,
@@ -19,7 +19,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16011
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16011
 -          ]
 -        }
        ]
      }
    ],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -52,7 +54,8 @@
 -          "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16031
 -          ]
 -        },
 -        {
 -          "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
--            16051
+-            16051,
+-            16031
 -          ]
 -        }
        ]
      }
    ],
-@@ -132,28 +88,19 @@
-           "fib":true,
+@@ -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
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-sw1",
+           "interfaceName":"eth-rt4-2",
 -          "active":true,
 -          "labels":[
 -            16051
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt4-2",
+           "interfaceName":"eth-rt4-1",
 -          "active":true,
 -          "labels":[
 -            16051
index ad48c50f32ed983c4590b6d3e039a1579c36c1ee..f8476cd0bbf0182535b59903b89a5fe6ab9c2cea 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step6/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step7/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
        }
      ]
    },
-@@ -147,54 +83,6 @@
+@@ -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,
 -        "type":"SR (IS-IS)",
 -        "outLabel":16051,
 -        "installed":true,
--        "interface":"eth-rt4-2"
--      },
--      {
--        "type":"SR (IS-IS)",
+         "interface":"eth-rt4-2"
+       },
+       {
+         "type":"SR (IS-IS)",
 -        "outLabel":16051,
--        "installed":true,
--        "interface":"eth-rt4-1"
++        "outLabel":3,
+         "installed":true,
+         "interface":"eth-rt4-1"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16051,
 -        "installed":true,
 -        "interface":"eth-sw1"
--      }
--    ]
--  },
-   "16060":{
-     "inLabel":16060,
-     "installed":true,
+       }
+     ]
+   },
index 3511a595c30c8009fdccaea921dad5eb5143a4f5..7d5237e7405df62311305d0661a4ea85b9803b1a 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step7/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step8/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-@@ -15,10 +15,34 @@
+--- 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,
@@ -20,7 +20,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16010
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16010
 +          ]
 +        }
        ]
      }
    ],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -55,7 +57,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16030
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16050
++            16050,
++            16030
 +          ]
 +        }
        ]
      }
    ],
-@@ -93,21 +141,30 @@
+@@ -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",
          }
        ]
      }
-@@ -155,12 +212,34 @@
+@@ -169,12 +248,40 @@
          {
            "ip":"10.0.1.1",
            "afi":"ipv4",
 +          "ip":"10.0.2.4",
 +          "afi":"ipv4",
 +          "interfaceName":"eth-rt4-1",
-+          "active":true
++          "active":true,
++          "labels":[
++            16050
++          ]
 +        },
 +        {
 +          "ip":"10.0.3.4",
 +          "afi":"ipv4",
 +          "interfaceName":"eth-rt4-2",
-+          "active":true
++          "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
++          ]
          }
        ]
      }
index 96a60197ab9cf9fb64240fd7348ebd89fbabef57..45322214e68b994ab6e82dc11b641f413ac2d670 100644 (file)
@@ -1,6 +1,6 @@
---- rt2/step7/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step8/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-@@ -14,10 +14,32 @@
+--- 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,
@@ -19,7 +19,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16011
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16011
 +          ]
 +        }
        ]
      }
    ],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
@@ -52,7 +54,8 @@
 +          "interfaceName":"eth-rt4-1",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16031
 +          ]
 +        },
 +        {
 +          "interfaceName":"eth-rt4-2",
 +          "active":true,
 +          "labels":[
-+            16051
++            16051,
++            16031
 +          ]
 +        }
        ]
      }
    ],
-@@ -88,19 +132,28 @@
-           "fib":true,
+@@ -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":[
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-sw1",
+           "interfaceName":"eth-rt4-2",
 -          "active":true
 +          "active":true,
 +          "labels":[
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt4-2",
+           "interfaceName":"eth-rt4-1",
 -          "active":true
 +          "active":true,
 +          "labels":[
index 04b8e997250bd614af0c2a0f3199f1c980853e23..083c6478028c2c38ed44122e01b59ccb9f0b154f 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step7/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step8/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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,
        }
      ]
    },
-@@ -83,6 +147,54 @@
+@@ -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,
 +        "type":"SR (IS-IS)",
 +        "outLabel":16051,
 +        "installed":true,
-+        "interface":"eth-rt4-1"
+         "interface":"eth-rt4-1"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16051,
 +        "installed":true,
 +        "interface":"eth-sw1"
-+      }
-+    ]
-+  },
-   "16060":{
-     "inLabel":16060,
-     "installed":true,
+       }
+     ]
+   },
index b7deb80554dd3903829f5569ba530e6a55339f1e..15370a0a6293a040ea3b6fc2045e5598494e204c 100644 (file)
@@ -1,15 +1,69 @@
---- rt2/step8/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step9/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
+--- 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
            ]
          },
          {
-@@ -40,7 +40,7 @@
+@@ -175,7 +175,7 @@
+           "interfaceName":"eth-rt4-1",
+           "active":true,
+           "labels":[
+-            16050
++            16500
+           ]
+         },
+         {
+@@ -185,7 +185,7 @@
            "interfaceName":"eth-rt4-2",
            "active":true,
            "labels":[
@@ -18,7 +72,7 @@
            ]
          }
        ]
-@@ -78,7 +78,7 @@
+@@ -271,7 +271,7 @@
            "interfaceName":"eth-rt4-1",
            "active":true,
            "labels":[
@@ -27,7 +81,7 @@
            ]
          },
          {
-@@ -87,7 +87,7 @@
+@@ -280,7 +280,7 @@
            "interfaceName":"eth-rt4-2",
            "active":true,
            "labels":[
            ]
          }
        ]
-@@ -143,7 +143,7 @@
+@@ -318,7 +318,7 @@
            "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
 -            16050
 +            16500
            ]
-         },
-         {
-@@ -153,7 +153,7 @@
-           "interfaceName":"eth-rt4-1",
+         }
+       ]
+@@ -356,7 +356,7 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
 -            16050
 +            16500
            ]
-         },
-         {
-@@ -163,7 +163,7 @@
-           "interfaceName":"eth-rt4-2",
+         }
+       ]
+@@ -517,7 +517,7 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
 -            16050
index cd634af4e6eeb138ceed8e36039e99068281b968..2585f32595dc25d4677e3cdc1c94b9e1c0744813 100644 (file)
@@ -1,43 +1,52 @@
---- rt2/step8/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step9/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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
+-            16051,
++            16501,
+             16011
            ]
          },
-         {
-@@ -37,7 +37,7 @@
+@@ -38,7 +38,7 @@
            "interfaceName":"eth-rt4-2",
            "active":true,
            "labels":[
--            16051
-+            16501
+-            16051,
++            16501,
+             16011
            ]
          }
-       ]
-@@ -73,7 +73,7 @@
+@@ -75,7 +75,7 @@
            "interfaceName":"eth-rt4-1",
            "active":true,
            "labels":[
--            16051
-+            16501
+-            16051,
++            16501,
+             16031
            ]
          },
-         {
-@@ -81,7 +81,7 @@
+@@ -84,7 +84,7 @@
            "interfaceName":"eth-rt4-2",
            "active":true,
            "labels":[
--            16051
-+            16501
+-            16051,
++            16501,
+             16031
            ]
          }
-       ]
-@@ -134,7 +134,7 @@
-           "interfaceName":"eth-rt4-1",
+@@ -132,7 +132,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16051,
++            16501,
+             16041
+           ]
+         }
+@@ -155,7 +155,7 @@
+           "interfaceName":"eth-sw1",
            "active":true,
            "labels":[
 -            16051
@@ -45,8 +54,8 @@
            ]
          },
          {
-@@ -143,7 +143,7 @@
-           "interfaceName":"eth-sw1",
+@@ -164,7 +164,7 @@
+           "interfaceName":"eth-rt4-2",
            "active":true,
            "labels":[
 -            16051
@@ -54,8 +63,8 @@
            ]
          },
          {
-@@ -152,7 +152,7 @@
-           "interfaceName":"eth-rt4-2",
+@@ -173,7 +173,7 @@
+           "interfaceName":"eth-rt4-1",
            "active":true,
            "labels":[
 -            16051
index f195264f5a3d61d2b43c650792734deeff17ab45..b90b889ebad2a452ba89a3c985fde5a409cefa7e 100644 (file)
@@ -1,5 +1,5 @@
---- rt2/step8/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt2/step9/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
+--- 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":[
        {
          "interface":"eth-rt4-2"
        }
      ]
-@@ -147,87 +147,87 @@
-       }
-     ]
-   },
--  "16050":{
--    "inLabel":16050,
-+  "16060":{
-+    "inLabel":16060,
-     "installed":true,
-     "nexthops":[
+@@ -137,7 +137,7 @@
+     "backupNexthops":[
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16050,
-+        "outLabel":16060,
-         "installed":true,
-         "nexthop":"10.0.3.4"
-       },
++        "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,
-+        "outLabel":16060,
-         "installed":true,
-         "nexthop":"10.0.2.4"
+-        "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,
-+  "16061":{
-+    "inLabel":16061,
-     "installed":true,
-     "nexthops":[
-       {
-         "type":"SR (IS-IS)",
+-    "installed":true,
+-    "nexthops":[
+-      {
+-        "type":"SR (IS-IS)",
 -        "outLabel":16051,
-+        "outLabel":16061,
-         "installed":true,
-         "interface":"eth-rt4-2"
-       },
-       {
-         "type":"SR (IS-IS)",
+-        "installed":true,
+-        "interface":"eth-rt4-2"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
 -        "outLabel":16051,
-+        "outLabel":16061,
-         "installed":true,
-         "interface":"eth-rt4-1"
+-        "installed":true,
+-        "interface":"eth-rt4-1"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16051,
 -        "installed":true,
--        "interface":"eth-sw1"
++        "outLabel":16501,
+         "interface":"eth-sw1"
+       }
+     ]
+@@ -282,5 +234,53 @@
+         "interface":"eth-sw1"
        }
      ]
-   },
--  "16060":{
--    "inLabel":16060,
++  },
 +  "16500":{
 +    "inLabel":16500,
-     "installed":true,
-     "nexthops":[
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16060,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
 +        "outLabel":16500,
-         "installed":true,
-         "nexthop":"10.0.3.4"
-       },
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16060,
++        "installed":true,
++        "nexthop":"10.0.3.4"
++      },
++      {
++        "type":"SR (IS-IS)",
 +        "outLabel":16500,
-         "installed":true,
-         "nexthop":"10.0.2.4"
++        "installed":true,
++        "nexthop":"10.0.2.4"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16500,
 +        "installed":true,
 +        "nexthop":"10.0.1.3"
-       }
-     ]
-   },
--  "16061":{
--    "inLabel":16061,
++      }
++    ]
++  },
 +  "16501":{
 +    "inLabel":16501,
-     "installed":true,
-     "nexthops":[
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16061,
++    "installed":true,
++    "nexthops":[
++      {
++        "type":"SR (IS-IS)",
 +        "outLabel":16501,
-         "installed":true,
-         "interface":"eth-rt4-2"
-       },
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16061,
++        "installed":true,
++        "interface":"eth-rt4-2"
++      },
++      {
++        "type":"SR (IS-IS)",
 +        "outLabel":16501,
-         "installed":true,
-         "interface":"eth-rt4-1"
++        "installed":true,
++        "interface":"eth-rt4-1"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16501,
 +        "installed":true,
 +        "interface":"eth-sw1"
-       }
-     ]
++      }
++    ]
    }
+ }
index 5a4e1ce033976baea78b410e185c2a7f683de4e5..8c37180daf2cdf2db2c38ef5bf32483d88266477 100644 (file)
       ],
       "backupNexthops":[
         {
-          "ip":"10.0.5.5",
+          "ip":"10.0.4.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
-            16040
+            16040,
+            16010
           ]
         },
         {
-          "ip":"10.0.4.5",
+          "ip":"10.0.5.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
-            16040
+            16040,
+            16010
           ]
         }
       ]
       ],
       "backupNexthops":[
         {
-          "ip":"10.0.5.5",
+          "ip":"10.0.4.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
-            16040
+            16040,
+            16020
           ]
         },
         {
-          "ip":"10.0.4.5",
+          "ip":"10.0.5.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
-            16040
+            16040,
+            16020
           ]
         }
       ]
           "afi":"ipv4",
           "interfaceName":"eth-rt5-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
           "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
+          ]
+        }
       ]
     }
   ],
           "afi":"ipv4",
           "interfaceName":"eth-rt5-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16060
           ]
           "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
+        }
       ]
     }
   ],
       ],
       "backupNexthops":[
         {
-          "ip":"10.0.5.5",
+          "ip":"10.0.4.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-2",
-          "active":true
+          "interfaceName":"eth-rt5-1",
+          "active":true,
+          "labels":[
+            16040
+          ]
         },
         {
-          "ip":"10.0.4.5",
+          "ip":"10.0.5.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-1",
-          "active":true
+          "interfaceName":"eth-rt5-2",
+          "active":true,
+          "labels":[
+            16040
+          ]
         }
       ]
     }
       ],
       "backupNexthops":[
         {
-          "ip":"10.0.5.5",
+          "ip":"10.0.4.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true
         },
         {
-          "ip":"10.0.4.5",
+          "ip":"10.0.5.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true
         }
       ]
       ],
       "backupNexthops":[
         {
-          "ip":"10.0.5.5",
+          "ip":"10.0.4.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true
         },
         {
-          "ip":"10.0.4.5",
+          "ip":"10.0.5.5",
           "afi":"ipv4",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true
         }
       ]
         {
           "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
+          ]
         }
       ]
     }
           "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
+          ]
         }
       ]
     }
           "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,
+          "backupIndex":[
+            0
+          ]
+        }
+      ],
+      "backupNexthops":[
+        {
+          "ip":"10.0.1.2",
+          "afi":"ipv4",
+          "interfaceName":"eth-sw1",
           "active":true
         }
       ]
           "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
+          ]
         }
       ]
     }
index 525a87f31d620be6d3d21ea7c18f2fadf077a885..5ddb24af5a0f93c309dd2fdc5fe9b3af6255c70c 100644 (file)
       "backupNexthops":[
         {
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
-            16041
+            16041,
+            16011
           ]
         },
         {
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
-            16041
+            16041,
+            16011
           ]
         }
       ]
       "backupNexthops":[
         {
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
-            16041
+            16041,
+            16021
           ]
         },
         {
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
-            16041
+            16041,
+            16021
           ]
         }
       ]
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-2",
+          "interfaceName":"eth-sw1",
           "active":true,
           "labels":[
             16041
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5-1",
+          "interfaceName":"eth-rt5-2",
           "active":true,
           "labels":[
             16041
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-sw1",
+          "interfaceName":"eth-rt5-1",
           "active":true,
           "labels":[
             16041
           "afi":"ipv6",
           "interfaceName":"eth-rt5-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
           "afi":"ipv6",
           "interfaceName":"eth-rt5-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true,
+          "labels":[
+            16041,
+            16051
+          ]
+        }
       ]
     }
   ],
           "afi":"ipv6",
           "interfaceName":"eth-rt5-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16061
           ]
           "afi":"ipv6",
           "interfaceName":"eth-rt5-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16061
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-sw1",
+          "active":true
+        }
       ]
     }
   ]
index 13f5f2c703ef9c793b436b39b104e83751fcb626..f68d1f4244f248d72e7127683d9df59717cbc2d0 100644 (file)
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
-        "nexthop":"10.0.5.5"
+        "nexthop":"10.0.4.5"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
-        "nexthop":"10.0.4.5"
+        "nexthop":"10.0.5.5"
       }
     ]
   },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
-        "interface":"eth-rt5-2"
+        "interface":"eth-rt5-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
-        "interface":"eth-rt5-1"
+        "interface":"eth-rt5-2"
       }
     ]
   },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
-        "nexthop":"10.0.5.5"
+        "nexthop":"10.0.4.5"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16040,
-        "nexthop":"10.0.4.5"
+        "nexthop":"10.0.5.5"
       }
     ]
   },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
-        "interface":"eth-rt5-2"
+        "interface":"eth-rt5-1"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16041,
-        "interface":"eth-rt5-1"
+        "interface":"eth-rt5-2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.1.2"
+        "nexthop":"10.0.5.5"
       },
       {
         "type":"SR (IS-IS)",
         "type":"SR (IS-IS)",
         "outLabel":16040,
         "installed":true,
-        "nexthop":"10.0.5.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)",
         "type":"SR (IS-IS)",
         "outLabel":16041,
         "installed":true,
-        "interface":"eth-rt5-2"
+        "interface":"eth-sw1"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":3,
         "installed":true,
-        "nexthop":"10.0.4.5"
+        "nexthop":"10.0.5.5",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":3,
         "installed":true,
-        "nexthop":"10.0.5.5"
+        "nexthop":"10.0.4.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16040,
+        "nexthop":"10.0.1.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":3,
         "installed":true,
-        "interface":"eth-rt5-1"
+        "interface":"eth-rt5-2",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":3,
         "installed":true,
-        "interface":"eth-rt5-2"
+        "interface":"eth-rt5-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":16041,
+        "interface":"eth-sw1"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.4.5"
+        "nexthop":"10.0.5.5",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16060,
         "installed":true,
-        "nexthop":"10.0.5.5"
+        "nexthop":"10.0.4.5",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.1.2"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt5-1"
+        "interface":"eth-rt5-2",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16061,
         "installed":true,
-        "interface":"eth-rt5-2"
+        "interface":"eth-rt5-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-sw1"
       }
     ]
   }
index e5fe6e7589f6b7a4936ab178404c3c026be3b0da..707f95495d85a1150496c0d0b0e28b6117206b1e 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step3/show_ip_route.ref        2020-08-31 22:42:48.835561429 -0300
-+++ rt3/step4/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -15,34 +15,10 @@
+--- 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,
 -      ],
 -      "backupNexthops":[
 -        {
--          "ip":"10.0.5.5",
+-          "ip":"10.0.4.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt5-2",
+-          "interfaceName":"eth-rt5-1",
 -          "active":true,
 -          "labels":[
--            16040
+-            16040,
+-            16010
 -          ]
 -        },
 -        {
--          "ip":"10.0.4.5",
+-          "ip":"10.0.5.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt5-1",
+-          "interfaceName":"eth-rt5-2",
 -          "active":true,
 -          "labels":[
--            16040
+-            16040,
+-            16010
 -          ]
 -        }
        ]
      }
    ],
-@@ -62,34 +38,10 @@
+@@ -64,36 +38,10 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
 -      ],
 -      "backupNexthops":[
 -        {
--          "ip":"10.0.5.5",
+-          "ip":"10.0.4.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt5-2",
+-          "interfaceName":"eth-rt5-1",
 -          "active":true,
 -          "labels":[
--            16040
+-            16040,
+-            16020
 -          ]
 -        },
 -        {
--          "ip":"10.0.4.5",
+-          "ip":"10.0.5.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt5-1",
+-          "interfaceName":"eth-rt5-2",
 -          "active":true,
 -          "labels":[
--            16040
+-            16040,
+-            16020
 -          ]
 -        }
        ]
      }
    ],
-@@ -108,30 +60,21 @@
+@@ -112,30 +60,21 @@
            "ip":"10.0.1.2",
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
          }
        ]
      }
-@@ -212,34 +155,12 @@
+@@ -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",
 -      ],
 -      "backupNexthops":[
 -        {
--          "ip":"10.0.5.5",
+-          "ip":"10.0.4.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt5-2",
--          "active":true
+-          "interfaceName":"eth-rt5-1",
+-          "active":true,
+-          "labels":[
+-            16040
+-          ]
 -        },
 -        {
--          "ip":"10.0.4.5",
+-          "ip":"10.0.5.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt5-1",
--          "active":true
+-          "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
+         }
+       ]
+     }
index ccfbbeae69a5a29e3ed3cd724d060c716f3d99b3..76d0ebc913a6159e71fc90b77598f1aedbddaf5c 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step3/show_ipv6_route.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt3/step4/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -14,32 +14,10 @@
+--- 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,
 -      "backupNexthops":[
 -        {
 -          "afi":"ipv6",
--          "interfaceName":"eth-rt5-2",
+-          "interfaceName":"eth-rt5-1",
 -          "active":true,
 -          "labels":[
--            16041
+-            16041,
+-            16011
 -          ]
 -        },
 -        {
 -          "afi":"ipv6",
--          "interfaceName":"eth-rt5-1",
+-          "interfaceName":"eth-rt5-2",
 -          "active":true,
 -          "labels":[
--            16041
+-            16041,
+-            16011
 -          ]
 -        }
        ]
      }
    ],
-@@ -58,32 +36,10 @@
+@@ -60,34 +36,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
 -      "backupNexthops":[
 -        {
 -          "afi":"ipv6",
--          "interfaceName":"eth-rt5-2",
+-          "interfaceName":"eth-rt5-1",
 -          "active":true,
 -          "labels":[
--            16041
+-            16041,
+-            16021
 -          ]
 -        },
 -        {
 -          "afi":"ipv6",
--          "interfaceName":"eth-rt5-1",
+-          "interfaceName":"eth-rt5-2",
 -          "active":true,
 -          "labels":[
--            16041
+-            16041,
+-            16021
 -          ]
 -        }
        ]
      }
    ],
-@@ -101,28 +57,19 @@
+@@ -105,28 +57,19 @@
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt5-2",
+           "interfaceName":"eth-sw1",
 -          "active":true,
 -          "labels":[
 -            16041
@@ -79,7 +83,7 @@
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt5-1",
+           "interfaceName":"eth-rt5-2",
 -          "active":true,
 -          "labels":[
 -            16041
@@ -89,7 +93,7 @@
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-sw1",
+           "interfaceName":"eth-rt5-1",
 -          "active":true,
 -          "labels":[
 -            16041
          }
        ]
      }
+@@ -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
+-          ]
+-        }
+       ]
+     }
+   ],
index 64a8689a82dbe2d7fdcf1879bf34d1536ffbe86d..b888c9d273215f0cc180ceb774b400bae60ea05e 100644 (file)
@@ -1,5 +1,5 @@
---- rt3/step3/show_mpls_table.ref      2020-08-31 22:42:48.835561429 -0300
-+++ rt3/step4/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
+--- 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,
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16040,
--        "nexthop":"10.0.5.5"
+-        "nexthop":"10.0.4.5"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16040,
--        "nexthop":"10.0.4.5"
+-        "nexthop":"10.0.5.5"
 +        "nexthop":"10.0.1.1"
        }
      ]
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16041,
--        "interface":"eth-rt5-2"
+-        "interface":"eth-rt5-1"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16041,
--        "interface":"eth-rt5-1"
+-        "interface":"eth-rt5-2"
 +        "interface":"eth-sw1"
        }
      ]
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16040,
--        "nexthop":"10.0.5.5"
+-        "nexthop":"10.0.4.5"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16040,
--        "nexthop":"10.0.4.5"
+-        "nexthop":"10.0.5.5"
 +        "nexthop":"10.0.1.2"
        }
      ]
    },
-@@ -91,71 +43,7 @@
+@@ -91,70 +43,6 @@
          "type":"SR (IS-IS)",
          "outLabel":3,
          "installed":true,
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16041,
--        "interface":"eth-rt5-2"
+-        "interface":"eth-rt5-1"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16041,
--        "interface":"eth-rt5-1"
+-        "interface":"eth-rt5-2"
 -      }
 -    ]
 -  },
 -        "type":"SR (IS-IS)",
 -        "outLabel":16040,
 -        "installed":true,
--        "nexthop":"10.0.1.2"
+-        "nexthop":"10.0.5.5"
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "type":"SR (IS-IS)",
 -        "outLabel":16040,
 -        "installed":true,
--        "nexthop":"10.0.5.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)",
 -        "type":"SR (IS-IS)",
 -        "outLabel":16041,
 -        "installed":true,
--        "interface":"eth-rt5-2"
+         "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"
        }
      ]
    },
index de265cc255205a39b717a11665b151921eacced7..8eac75bec7e4a6117d825e85b48da8d5bc4aabcc 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step4/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step5/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -15,10 +15,34 @@
+--- 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,
 +      ],
 +      "backupNexthops":[
 +        {
-+          "ip":"10.0.5.5",
++          "ip":"10.0.4.5",
 +          "afi":"ipv4",
-+          "interfaceName":"eth-rt5-2",
++          "interfaceName":"eth-rt5-1",
 +          "active":true,
 +          "labels":[
-+            16040
++            16040,
++            16010
 +          ]
 +        },
 +        {
-+          "ip":"10.0.4.5",
++          "ip":"10.0.5.5",
 +          "afi":"ipv4",
-+          "interfaceName":"eth-rt5-1",
++          "interfaceName":"eth-rt5-2",
 +          "active":true,
 +          "labels":[
-+            16040
++            16040,
++            16010
 +          ]
 +        }
        ]
      }
    ],
-@@ -38,10 +62,34 @@
+@@ -38,10 +64,36 @@
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
            "active":true,
 +      ],
 +      "backupNexthops":[
 +        {
-+          "ip":"10.0.5.5",
++          "ip":"10.0.4.5",
 +          "afi":"ipv4",
-+          "interfaceName":"eth-rt5-2",
++          "interfaceName":"eth-rt5-1",
 +          "active":true,
 +          "labels":[
-+            16040
++            16040,
++            16020
 +          ]
 +        },
 +        {
-+          "ip":"10.0.4.5",
++          "ip":"10.0.5.5",
 +          "afi":"ipv4",
-+          "interfaceName":"eth-rt5-1",
++          "interfaceName":"eth-rt5-2",
 +          "active":true,
 +          "labels":[
-+            16040
++            16040,
++            16020
 +          ]
 +        }
        ]
      }
    ],
-@@ -60,21 +108,30 @@
+@@ -60,21 +112,30 @@
            "ip":"10.0.1.2",
            "afi":"ipv4",
            "interfaceName":"eth-sw1",
          }
        ]
      }
-@@ -155,12 +212,34 @@
+@@ -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",
 +      ],
 +      "backupNexthops":[
 +        {
-+          "ip":"10.0.5.5",
++          "ip":"10.0.4.5",
 +          "afi":"ipv4",
-+          "interfaceName":"eth-rt5-2",
-+          "active":true
++          "interfaceName":"eth-rt5-1",
++          "active":true,
++          "labels":[
++            16040
++          ]
 +        },
 +        {
-+          "ip":"10.0.4.5",
++          "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",
-+          "active":true
++          "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
++          ]
          }
        ]
      }
index 947d4271e8e1166af8066c220b6fdfc34ad7ffae..fc55267ad1618da848dc3f37b5e4080a51fd75df 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step4/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step5/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -14,10 +14,32 @@
+--- 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,
 +      "backupNexthops":[
 +        {
 +          "afi":"ipv6",
-+          "interfaceName":"eth-rt5-2",
++          "interfaceName":"eth-rt5-1",
 +          "active":true,
 +          "labels":[
-+            16041
++            16041,
++            16011
 +          ]
 +        },
 +        {
 +          "afi":"ipv6",
-+          "interfaceName":"eth-rt5-1",
++          "interfaceName":"eth-rt5-2",
 +          "active":true,
 +          "labels":[
-+            16041
++            16041,
++            16011
 +          ]
 +        }
        ]
      }
    ],
-@@ -36,10 +58,32 @@
+@@ -36,10 +60,34 @@
            "afi":"ipv6",
            "interfaceName":"eth-sw1",
            "active":true,
 +      "backupNexthops":[
 +        {
 +          "afi":"ipv6",
-+          "interfaceName":"eth-rt5-2",
++          "interfaceName":"eth-rt5-1",
 +          "active":true,
 +          "labels":[
-+            16041
++            16041,
++            16021
 +          ]
 +        },
 +        {
 +          "afi":"ipv6",
-+          "interfaceName":"eth-rt5-1",
++          "interfaceName":"eth-rt5-2",
 +          "active":true,
 +          "labels":[
-+            16041
++            16041,
++            16021
 +          ]
 +        }
        ]
      }
    ],
-@@ -57,19 +101,28 @@
+@@ -57,19 +105,28 @@
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt5-2",
+           "interfaceName":"eth-sw1",
 -          "active":true
 +          "active":true,
 +          "labels":[
@@ -79,7 +83,7 @@
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-rt5-1",
+           "interfaceName":"eth-rt5-2",
 -          "active":true
 +          "active":true,
 +          "labels":[
@@ -89,7 +93,7 @@
          {
            "fib":true,
            "afi":"ipv6",
-           "interfaceName":"eth-sw1",
+           "interfaceName":"eth-rt5-1",
 -          "active":true
 +          "active":true,
 +          "labels":[
          }
        ]
      }
+@@ -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
++          ]
++        }
+       ]
+     }
+   ],
index 3dd237b91bed1f2779bb29d0cf31a27ff1d277e2..4ed491e2416ca87494552ef0c4fd83d0f8e9ce79 100644 (file)
@@ -1,5 +1,5 @@
---- rt3/step4/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step5/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
+--- 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,
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16040,
-+        "nexthop":"10.0.5.5"
++        "nexthop":"10.0.4.5"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16040,
-+        "nexthop":"10.0.4.5"
++        "nexthop":"10.0.5.5"
        }
      ]
    },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16041,
-+        "interface":"eth-rt5-2"
++        "interface":"eth-rt5-1"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16041,
-+        "interface":"eth-rt5-1"
++        "interface":"eth-rt5-2"
        }
      ]
    },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16040,
-+        "nexthop":"10.0.5.5"
++        "nexthop":"10.0.4.5"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16040,
-+        "nexthop":"10.0.4.5"
++        "nexthop":"10.0.5.5"
        }
      ]
    },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16041,
-+        "interface":"eth-rt5-2"
++        "interface":"eth-rt5-1"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16041,
-+        "interface":"eth-rt5-1"
++        "interface":"eth-rt5-2"
 +      }
 +    ]
 +  },
 +        "type":"SR (IS-IS)",
 +        "outLabel":16040,
 +        "installed":true,
-+        "nexthop":"10.0.4.5"
++        "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)",
 +        "type":"SR (IS-IS)",
 +        "outLabel":16041,
 +        "installed":true,
-+        "interface":"eth-rt5-1"
++        "interface":"eth-rt5-2"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16041,
 +        "installed":true,
-+        "interface":"eth-rt5-2"
++        "interface":"eth-rt5-1"
 +      },
 +      {
 +        "type":"SR (IS-IS)",
          "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"
+       }
+     ]
+   },
index 00f0bb031a6770d793b5508e8f99d2581666959b..9273c75352640fa21c093191fa62661c9dea2544 100644 (file)
@@ -1,42 +1,42 @@
---- rt3/step5/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step6/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
+--- 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-2",
+           "interfaceName":"eth-rt5-1",
            "active":true,
            "labels":[
--            16040
-+            30040
+-            16040,
++            30040,
+             16010
            ]
          },
-         {
-@@ -40,7 +40,7 @@
-           "interfaceName":"eth-rt5-1",
+@@ -41,7 +41,7 @@
+           "interfaceName":"eth-rt5-2",
            "active":true,
            "labels":[
--            16040
-+            30040
+-            16040,
++            30040,
+             16010
            ]
          }
-       ]
-@@ -78,7 +78,7 @@
-           "interfaceName":"eth-rt5-2",
+@@ -80,7 +80,7 @@
+           "interfaceName":"eth-rt5-1",
            "active":true,
            "labels":[
--            16040
-+            30040
+-            16040,
++            30040,
+             16020
            ]
          },
-         {
-@@ -87,7 +87,7 @@
-           "interfaceName":"eth-rt5-1",
+@@ -90,7 +90,7 @@
+           "interfaceName":"eth-rt5-2",
            "active":true,
            "labels":[
--            16040
-+            30040
+-            16040,
++            30040,
+             16020
            ]
          }
-       ]
-@@ -120,7 +120,7 @@
+@@ -124,7 +124,7 @@
            "interfaceName":"eth-rt5-1",
            "active":true,
            "labels":[
@@ -45,7 +45,7 @@
            ]
          },
          {
-@@ -130,7 +130,7 @@
+@@ -134,7 +134,7 @@
            "interfaceName":"eth-rt5-2",
            "active":true,
            "labels":[
            ]
          }
        ]
-@@ -186,7 +186,7 @@
-           "interfaceName":"eth-rt5-1",
+@@ -185,7 +185,7 @@
            "active":true,
            "labels":[
+             16040,
+-            16050
++            30050
+           ]
+         }
+       ]
+@@ -211,7 +211,7 @@
+             0
+           ],
+           "labels":[
 -            16060
 +            30060
            ]
          },
          {
-@@ -196,7 +196,7 @@
-           "interfaceName":"eth-rt5-2",
-           "active":true,
+@@ -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
+           ]
+         }
        ]
index 823cd4591fa303734fb594c657f3a2cfe9a114a8..f50be893e476a1261948e7a9298daf393b135af2 100644 (file)
@@ -1,42 +1,42 @@
---- rt3/step5/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step6/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
+--- 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-2",
+           "interfaceName":"eth-rt5-1",
            "active":true,
            "labels":[
--            16041
-+            30041
+-            16041,
++            30041,
+             16011
            ]
          },
-         {
-@@ -37,7 +37,7 @@
-           "interfaceName":"eth-rt5-1",
+@@ -38,7 +38,7 @@
+           "interfaceName":"eth-rt5-2",
            "active":true,
            "labels":[
--            16041
-+            30041
+-            16041,
++            30041,
+             16011
            ]
          }
-       ]
-@@ -73,7 +73,7 @@
-           "interfaceName":"eth-rt5-2",
+@@ -75,7 +75,7 @@
+           "interfaceName":"eth-rt5-1",
            "active":true,
            "labels":[
--            16041
-+            30041
+-            16041,
++            30041,
+             16021
            ]
          },
-         {
-@@ -81,7 +81,7 @@
-           "interfaceName":"eth-rt5-1",
+@@ -84,7 +84,7 @@
+           "interfaceName":"eth-rt5-2",
            "active":true,
            "labels":[
--            16041
-+            30041
+-            16041,
++            30041,
+             16021
            ]
          }
-       ]
-@@ -103,7 +103,7 @@
+@@ -116,7 +116,7 @@
            "interfaceName":"eth-rt5-2",
            "active":true,
            "labels":[
            ]
          },
          {
-@@ -112,7 +112,7 @@
+@@ -125,7 +125,7 @@
            "interfaceName":"eth-rt5-1",
            "active":true,
            "labels":[
 -            16041
 +            30041
            ]
-         },
-         {
-@@ -174,7 +174,7 @@
-           "interfaceName":"eth-rt5-2",
+         }
+       ]
+@@ -173,7 +173,7 @@
            "active":true,
            "labels":[
+             16041,
+-            16051
++            30051
+           ]
+         }
+       ]
+@@ -198,7 +198,7 @@
+             0
+           ],
+           "labels":[
 -            16061
 +            30061
            ]
          },
          {
-@@ -183,7 +183,7 @@
-           "interfaceName":"eth-rt5-1",
-           "active":true,
+@@ -210,7 +210,7 @@
+             0
+           ],
            "labels":[
 -            16061
 +            30061
            ]
          }
-       ]
+       ],
index 1ad228b9c24a6e76bbce8d874a99dfe72ed1f932..b63a728ef101da3637c0f7be25247909242a835d 100644 (file)
@@ -1,18 +1,18 @@
---- rt3/step5/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step6/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
+--- 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.5.5"
+         "nexthop":"10.0.4.5"
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16040,
 +        "outLabel":30040,
-         "nexthop":"10.0.4.5"
+         "nexthop":"10.0.5.5"
        }
      ]
 @@ -45,12 +45,12 @@
          "type":"SR (IS-IS)",
 -        "outLabel":16041,
 +        "outLabel":30041,
-         "interface":"eth-rt5-2"
+         "interface":"eth-rt5-1"
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16041,
 +        "outLabel":30041,
-         "interface":"eth-rt5-1"
+         "interface":"eth-rt5-2"
        }
      ]
 @@ -73,12 +73,12 @@
          "type":"SR (IS-IS)",
 -        "outLabel":16040,
 +        "outLabel":30040,
-         "nexthop":"10.0.5.5"
+         "nexthop":"10.0.4.5"
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16040,
 +        "outLabel":30040,
-         "nexthop":"10.0.4.5"
+         "nexthop":"10.0.5.5"
        }
      ]
 @@ -101,12 +101,12 @@
          "type":"SR (IS-IS)",
 -        "outLabel":16041,
 +        "outLabel":30041,
-         "interface":"eth-rt5-2"
+         "interface":"eth-rt5-1"
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16041,
 +        "outLabel":30041,
-         "interface":"eth-rt5-1"
+         "interface":"eth-rt5-2"
        }
      ]
 @@ -117,13 +117,13 @@
 -        "outLabel":16040,
 +        "outLabel":30040,
          "installed":true,
-         "nexthop":"10.0.4.5"
+         "nexthop":"10.0.5.5"
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16040,
 +        "outLabel":30040,
          "installed":true,
-         "nexthop":"10.0.5.5"
+         "nexthop":"10.0.4.5"
        },
 @@ -141,13 +141,13 @@
      "nexthops":[
 -        "outLabel":16041,
 +        "outLabel":30041,
          "installed":true,
-         "interface":"eth-rt5-1"
+         "interface":"eth-rt5-2"
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16041,
 +        "outLabel":30041,
          "installed":true,
-         "interface":"eth-rt5-2"
+         "interface":"eth-rt5-1"
        },
-@@ -201,13 +201,13 @@
+@@ -227,7 +227,7 @@
      "nexthops":[
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16060,
 +        "outLabel":30060,
          "installed":true,
-         "nexthop":"10.0.4.5"
+         "nexthop":"10.0.5.5",
+         "backupIndex":[
+@@ -236,7 +236,7 @@
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16060,
 +        "outLabel":30060,
          "installed":true,
-         "nexthop":"10.0.5.5"
-       }
-@@ -219,13 +219,13 @@
+         "nexthop":"10.0.4.5",
+         "backupIndex":[
+@@ -258,7 +258,7 @@
      "nexthops":[
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16061,
 +        "outLabel":30061,
          "installed":true,
-         "interface":"eth-rt5-1"
+         "interface":"eth-rt5-2",
+         "backupIndex":[
+@@ -267,7 +267,7 @@
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16061,
 +        "outLabel":30061,
          "installed":true,
-         "interface":"eth-rt5-2"
-       }
+         "interface":"eth-rt5-1",
+         "backupIndex":[
index bee7c568e74f2f9701c614ddb784c96c0ec37453..0ae87afa3bad5b1bf1914ae051ab6e29d8eae2f8 100644 (file)
@@ -1,25 +1,32 @@
---- rt3/step6/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step7/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -151,20 +151,14 @@
-           "ip":"10.0.4.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5-1",
--          "active":true,
+--- 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
--          ]
-+          "active":true
+           ]
          },
          {
-           "fib":true,
-           "ip":"10.0.5.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5-2",
--          "active":true,
+@@ -171,9 +168,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
 -          "labels":[
 -            3
--          ]
-+          "active":true
+           ]
+         }
+       ],
+@@ -184,8 +178,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16040,
+-            30050
++            16040
+           ]
          }
        ]
-     }
index 05b40803043b9df6acc1f02cea8476d3864f0a9f..f392f644c04977f5cde9215e44a2ec2cf374aa55 100644 (file)
@@ -1,24 +1,32 @@
---- rt3/step6/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step7/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -141,19 +141,13 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5-2",
--          "active":true,
+--- 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
--          ]
-+          "active":true
+           ]
          },
          {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5-1",
--          "active":true,
+@@ -160,9 +157,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
 -          "labels":[
 -            3
--          ]
-+          "active":true
+           ]
+         }
+       ],
+@@ -172,8 +166,7 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16041,
+-            30051
++            16041
+           ]
          }
        ]
-     }
index 3fb37faea658b2f14400bdcc3a1a2b7b343b679a..b74eb9579cd3b1d97e587b55161d93fb3fe98bc9 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step6/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step7/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -159,42 +159,6 @@
+--- 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 @@
        }
      ]
    },
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "installed":true,
--        "nexthop":"10.0.4.5"
+-        "nexthop":"10.0.5.5",
+-        "backupIndex":[
+-          0
+-        ]
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "installed":true,
--        "nexthop":"10.0.5.5"
+-        "nexthop":"10.0.4.5",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16040,
+-        "nexthop":"10.0.1.2"
 -      }
 -    ]
 -  },
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "installed":true,
--        "interface":"eth-rt5-1"
+-        "interface":"eth-rt5-2",
+-        "backupIndex":[
+-          0
+-        ]
 -      },
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "installed":true,
--        "interface":"eth-rt5-2"
+-        "interface":"eth-rt5-1",
+-        "backupIndex":[
+-          0
+-        ]
+-      }
+-    ],
+-    "backupNexthops":[
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16041,
+-        "interface":"eth-sw1"
 -      }
 -    ]
 -  },
index c31d25261c70d356cc524c112a762c4482273ada..25b42f282506404624ae2a53459dc6bf3d7e9b57 100644 (file)
@@ -1,25 +1,32 @@
---- rt3/step7/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step8/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -151,14 +151,20 @@
-           "ip":"10.0.4.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5-1",
--          "active":true
-+          "active":true,
+--- 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
-+          ]
+           ]
          },
          {
-           "fib":true,
-           "ip":"10.0.5.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5-2",
--          "active":true
-+          "active":true,
+@@ -168,6 +171,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
 +          "labels":[
 +            3
-+          ]
+           ]
+         }
+       ],
+@@ -178,7 +184,8 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16040
++            16040,
++            30050
+           ]
          }
        ]
-     }
index 759f28d263791726e0db1331e82bb1c0384ba62c..42d9356c8ad791bfc2786e259cef758a5b3aaebf 100644 (file)
@@ -1,24 +1,32 @@
---- rt3/step7/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step8/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -141,13 +141,19 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5-2",
--          "active":true
-+          "active":true,
+--- 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
-+          ]
+           ]
          },
          {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5-1",
--          "active":true
-+          "active":true,
+@@ -157,6 +160,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
 +          "labels":[
 +            3
-+          ]
+           ]
+         }
+       ],
+@@ -166,7 +172,8 @@
+           "interfaceName":"eth-sw1",
+           "active":true,
+           "labels":[
+-            16041
++            16041,
++            30051
+           ]
          }
        ]
-     }
index 0c2c8e2b09f2a4d6d5011d3c645c2a9eff423ade..bd40f954eb781b790aa2ac0c83706ede04e7e744 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step7/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step8/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -159,6 +159,42 @@
+--- 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 @@
        }
      ]
    },
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "installed":true,
-+        "nexthop":"10.0.4.5"
++        "nexthop":"10.0.5.5",
++        "backupIndex":[
++          0
++        ]
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "installed":true,
-+        "nexthop":"10.0.5.5"
++        "nexthop":"10.0.4.5",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16040,
++        "nexthop":"10.0.1.2"
 +      }
 +    ]
 +  },
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "installed":true,
-+        "interface":"eth-rt5-1"
++        "interface":"eth-rt5-2",
++        "backupIndex":[
++          0
++        ]
 +      },
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "installed":true,
-+        "interface":"eth-rt5-2"
++        "interface":"eth-rt5-1",
++        "backupIndex":[
++          0
++        ]
++      }
++    ],
++    "backupNexthops":[
++      {
++        "type":"SR (IS-IS)",
++        "outLabel":16041,
++        "interface":"eth-sw1"
 +      }
 +    ]
 +  },
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..687e84ad40a2ac449221d0682b3f7113c0335a8c 100644 (file)
@@ -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
+           ]
+         }
+       ]
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..4b76be66ac8458df84a086f4ee966f5f30f36308 100644 (file)
@@ -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
+           ]
+         }
+       ]
index b0a4851750d5c7229155830f5ee40a04367bed0c..6f6451e510358332c612403f4722698101ab7ecc 100644 (file)
@@ -1,6 +1,6 @@
---- rt3/step8/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt3/step9/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -159,73 +159,73 @@
+--- 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 @@
        }
      ]
    },
 -        "outLabel":3,
 +        "outLabel":30060,
          "installed":true,
-         "nexthop":"10.0.4.5"
+         "nexthop":"10.0.5.5",
+         "backupIndex":[
+@@ -174,7 +174,7 @@
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":3,
 +        "outLabel":30060,
          "installed":true,
-         "nexthop":"10.0.5.5"
+         "nexthop":"10.0.4.5",
+         "backupIndex":[
+@@ -185,18 +185,18 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16040,
++        "outLabel":3,
+         "nexthop":"10.0.1.2"
        }
      ]
    },
 -        "outLabel":3,
 +        "outLabel":30061,
          "installed":true,
-         "interface":"eth-rt5-1"
+         "interface":"eth-rt5-2",
+         "backupIndex":[
+@@ -205,7 +205,7 @@
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":3,
 +        "outLabel":30061,
          "installed":true,
-         "interface":"eth-rt5-2"
+         "interface":"eth-rt5-1",
+         "backupIndex":[
+@@ -216,18 +216,18 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":16041,
++        "outLabel":3,
+         "interface":"eth-sw1"
        }
      ]
    },
 -        "outLabel":30060,
 +        "outLabel":3,
          "installed":true,
-         "nexthop":"10.0.4.5"
+         "nexthop":"10.0.5.5",
+         "backupIndex":[
+@@ -236,7 +236,7 @@
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":30060,
 +        "outLabel":3,
          "installed":true,
-         "nexthop":"10.0.5.5"
+         "nexthop":"10.0.4.5",
+         "backupIndex":[
+@@ -247,18 +247,18 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":16040,
+         "nexthop":"10.0.1.2"
        }
      ]
    },
 -        "outLabel":30061,
 +        "outLabel":3,
          "installed":true,
-         "interface":"eth-rt5-1"
+         "interface":"eth-rt5-2",
+         "backupIndex":[
+@@ -267,7 +267,7 @@
        },
        {
          "type":"SR (IS-IS)",
 -        "outLabel":30061,
 +        "outLabel":3,
          "installed":true,
-         "interface":"eth-rt5-2"
+         "interface":"eth-rt5-1",
+         "backupIndex":[
+@@ -278,7 +278,7 @@
+     "backupNexthops":[
+       {
+         "type":"SR (IS-IS)",
+-        "outLabel":3,
++        "outLabel":16041,
+         "interface":"eth-sw1"
        }
+     ]
index 3ee587ac4998fe20fc1ade4ce21fdbe7218c073a..168b90a3f6bd12ccc0b40c21a53c7ddfd4c615e2 100644 (file)
@@ -15,6 +15,9 @@
           "afi":"ipv4",
           "interfaceName":"eth-rt2-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16010
           ]
           "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
           ]
           "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
+          ]
+        }
       ]
     }
   ],
           "ip":"10.0.7.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "ip":"10.0.6.5",
           "afi":"ipv4",
           "interfaceName":"eth-rt5",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "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
         }
       ]
         {
           "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
+          ]
         }
       ]
     }
           "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
+          ]
         }
       ]
     }
index 2f6b703d93f251eaae8cfda9b97f23d7bb6f0954..a4442ee0895a4b284004e18554a976bdc45302b7 100644 (file)
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16011
           ]
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16011
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true
+        }
       ]
     }
   ],
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt5",
+          "active":true,
+          "labels":[
+            16031,
+            16021
+          ]
+        }
       ]
     }
   ],
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-2",
+          "interfaceName":"eth-rt2-1",
           "active":true,
           "labels":[
             16031
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt2-1",
+          "interfaceName":"eth-rt2-2",
           "active":true,
           "labels":[
             16031
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt6",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt5",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
index 5433d4f100d7c24df84832835f55ea7367aea9c4..18354e947d2c9e75edc931d255fb7b62f5e0f953 100644 (file)
@@ -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"
       }
     ]
   },
         "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"
       }
     ]
   },
         "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"
       }
     ]
   },
         "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"
       }
     ]
   },
index 09a0eaa424b6953117c07fdb114fab88750cdf8a..7dcdb744ac905fd7a601619fea05d21d601260fe 100644 (file)
---- rt4/step3/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step4/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -14,20 +14,14 @@
-           "ip":"10.0.2.2",
+--- 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,
--          "labels":[
--            16010
--          ]
-+          "active":true
-         },
-         {
-           "fib":true,
-           "ip":"10.0.3.2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16010
+           ]
+@@ -28,21 +25,10 @@
            "afi":"ipv4",
            "interfaceName":"eth-rt2-2",
--          "active":true,
--          "labels":[
--            16010
--          ]
-+          "active":true
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16010
+           ]
          }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+-          "active":true
+-        }
        ]
      }
-@@ -47,20 +41,14 @@
-           "ip":"10.0.2.2",
+   ],
+@@ -62,9 +48,6 @@
            "afi":"ipv4",
            "interfaceName":"eth-rt2-1",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         },
-         {
-           "fib":true,
-           "ip":"10.0.3.2",
+           "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":[
--            3
+-            16030,
+-            16020
 -          ]
-+          "active":true
+-        }
+       ]
+     }
+   ],
+@@ -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
+-        }
        ]
      }
-@@ -80,30 +68,21 @@
+   ],
+@@ -223,27 +169,13 @@
            "ip":"10.0.2.2",
            "afi":"ipv4",
            "interfaceName":"eth-rt2-1",
 -          "active":true,
--          "labels":[
--            16030
+-          "backupIndex":[
+-            0
 -          ]
 +          "active":true
          },
            "afi":"ipv4",
            "interfaceName":"eth-rt2-2",
 -          "active":true,
--          "labels":[
--            16030
+-          "backupIndex":[
+-            0
 -          ]
-+          "active":true
-         },
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.5",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt5",
+           "active":true
+         }
+       ]
+@@ -259,30 +191,13 @@
          {
-           "fib":true,
-           "ip":"10.0.6.5",
+           "ip":"10.0.2.2",
            "afi":"ipv4",
-           "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            16030
+-          "interfaceName":"eth-rt2-1",
+-          "backupIndex":[
+-            0
 -          ]
-+          "active":true
-         }
-       ]
-     }
-@@ -123,24 +102,7 @@
-           "ip":"10.0.6.5",
++          "interfaceName":"eth-rt2-1"
+         },
+         {
+           "ip":"10.0.3.2",
            "afi":"ipv4",
-           "interfaceName":"eth-rt5",
+           "interfaceName":"eth-rt2-2",
 -          "active":true,
 -          "backupIndex":[
 -            0
--          ],
--          "labels":[
--            3
 -          ]
 -        }
 -      ],
 -      "backupNexthops":[
 -        {
--          "ip":"10.0.7.6",
+-          "ip":"10.0.6.5",
 -          "afi":"ipv4",
--          "interfaceName":"eth-rt6",
+-          "interfaceName":"eth-rt5",
 -          "active":true,
 -          "labels":[
--            3
+-            16030
 -          ]
 +          "active":true
          }
        ]
      }
-@@ -160,24 +122,7 @@
-           "ip":"10.0.7.6",
+@@ -298,29 +213,12 @@
+           "ip":"10.0.2.2",
            "afi":"ipv4",
-           "interfaceName":"eth-rt6",
+           "interfaceName":"eth-rt2-1",
 -          "active":true,
 -          "backupIndex":[
 -            0
--          ],
--          "labels":[
--            3
+-          ]
++          "active":true
+         },
+         {
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt2-2",
+-          "backupIndex":[
+-            0
 -          ]
 -        }
 -      ],
 -          "interfaceName":"eth-rt5",
 -          "active":true,
 -          "labels":[
--            3
+-            16030
 -          ]
-+          "active":true
++          "interfaceName":"eth-rt2-2"
          }
        ]
      }
-@@ -266,31 +211,6 @@
+@@ -340,31 +238,6 @@
            "ip":"10.0.6.5",
            "afi":"ipv4",
            "interfaceName":"eth-rt5",
            "active":true
          }
        ]
-@@ -311,31 +231,6 @@
+@@ -385,31 +258,6 @@
            "ip":"10.0.6.5",
            "afi":"ipv4",
            "interfaceName":"eth-rt5",
            "active":true
          }
        ]
-@@ -351,18 +246,7 @@
+@@ -425,18 +273,7 @@
          {
            "ip":"10.0.6.5",
            "afi":"ipv4",
          }
        ]
      }
-@@ -377,18 +261,7 @@
+@@ -451,18 +288,7 @@
          {
            "ip":"10.0.7.6",
            "afi":"ipv4",
index c1f9fa4bbae6ee941bbdab9fb32be11c3a7feffb..b84ceaff1a7aae3630fd2bed6fdefaf6241c769a 100644 (file)
---- rt4/step3/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step4/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -13,19 +13,13 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt2-2",
--          "active":true,
--          "labels":[
--            16011
--          ]
-+          "active":true
-         },
-         {
-           "fib":true,
+--- 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,
--          "labels":[
--            16011
--          ]
-+          "active":true
-         }
-       ]
-     }
-@@ -44,19 +38,13 @@
-           "fib":true,
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16011
+           ]
+@@ -26,20 +23,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt2-2",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         },
-         {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt2-1",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             16011
+           ]
          }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt5",
+-          "active":true
+-        }
        ]
      }
-@@ -75,28 +63,19 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt2-2",
--          "active":true,
--          "labels":[
--            16031
--          ]
-+          "active":true
-         },
-         {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            16031
--          ]
-+          "active":true
-         },
-         {
-           "fib":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
+-            16031,
+-            16021
 -          ]
-+          "active":true
-         }
+-        }
        ]
      }
-@@ -115,23 +94,7 @@
-           "fib":true,
+   ],
+@@ -146,20 +116,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt5",
--          "active":true,
+           "active":true,
 -          "backupIndex":[
 -            0
 -          ],
--          "labels":[
--            3
--          ]
--        }
+           "labels":[
+             3
+           ]
+         }
 -      ],
 -      "backupNexthops":[
 -        {
 -          "afi":"ipv6",
 -          "interfaceName":"eth-rt6",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
+-          "active":true
+-        }
        ]
      }
-@@ -150,23 +113,7 @@
-           "fib":true,
+   ],
+@@ -178,20 +138,10 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt6",
--          "active":true,
+           "active":true,
 -          "backupIndex":[
 -            0
 -          ],
--          "labels":[
--            3
--          ]
--        }
+           "labels":[
+             3
+           ]
+         }
 -      ],
 -      "backupNexthops":[
 -        {
 -          "afi":"ipv6",
 -          "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
+-          "active":true
+-        }
        ]
      }
+   ]
index 710f81708bfccbc3188abea16cae5bb0e9d13c82..70e0108b0dcf1e1ac329bf03fd34674d78280504 100644 (file)
---- rt4/step3/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step4/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -1,210 +1,2 @@
- {
--  "16010":{
--    "inLabel":16010,
--    "installed":true,
--    "nexthops":[
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":16010,
--        "installed":true,
--        "nexthop":"10.0.3.2"
--      },
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":16010,
--        "installed":true,
--        "nexthop":"10.0.2.2"
--      }
--    ]
--  },
--  "16011":{
--    "inLabel":16011,
--    "installed":true,
--    "nexthops":[
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":16011,
--        "installed":true,
--        "interface":"eth-rt2-2"
--      },
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":16011,
--        "installed":true,
--        "interface":"eth-rt2-1"
+--- 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
+-        ]
 -      }
--    ]
--  },
--  "16020":{
--    "inLabel":16020,
--    "installed":true,
--    "nexthops":[
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":3,
--        "installed":true,
--        "nexthop":"10.0.3.2"
--      },
+-    ],
+-    "backupNexthops":[
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
--        "installed":true,
--        "nexthop":"10.0.2.2"
+-        "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
+-        ]
 -      }
--    ]
--  },
--  "16021":{
--    "inLabel":16021,
--    "installed":true,
--    "nexthops":[
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":3,
--        "installed":true,
--        "interface":"eth-rt2-2"
--      },
+-    ],
+-    "backupNexthops":[
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
--        "installed":true,
--        "interface":"eth-rt2-1"
+-        "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
+-        ]
 -      }
--    ]
--  },
--  "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"
--      },
+-    ],
+-    "backupNexthops":[
 -      {
 -        "type":"SR (IS-IS)",
 -        "outLabel":16030,
--        "installed":true,
 -        "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
+-        ]
 -      }
--    ]
--  },
--  "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"
--      },
+-    ],
+-    "backupNexthops":[
 -      {
 -        "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,
++        "interface":"eth-rt2-1"
+       }
+     ]
+   },
+@@ -179,17 +127,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
 -        "nexthop":"10.0.6.5",
 -        "backupIndex":[
 -          0
 -        "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,
++        "nexthop":"10.0.6.5"
+       }
+     ]
+   },
+@@ -201,17 +139,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
 -        "interface":"eth-rt5",
 -        "backupIndex":[
 -          0
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "interface":"eth-rt6"
--      }
--    ]
--  },
--  "16060":{
--    "inLabel":16060,
--    "installed":true,
--    "nexthops":[
--      {
--        "type":"SR (IS-IS)",
--        "outLabel":3,
--        "installed":true,
++        "interface":"eth-rt5"
+       }
+     ]
+   },
+@@ -223,17 +151,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
 -        "nexthop":"10.0.7.6",
 -        "backupIndex":[
 -          0
 -        "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,
++        "nexthop":"10.0.7.6"
+       }
+     ]
+   },
+@@ -245,17 +163,7 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
 -        "interface":"eth-rt6",
 -        "backupIndex":[
 -          0
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "interface":"eth-rt5"
--      }
--    ]
--  }
- }
++        "interface":"eth-rt6"
+       }
+     ]
  }
index e19f6b293c7dd1b2b79c7d55603151d6fdd33c0d..aa319a3232fa8218d7a59aa7ab26f7ef65d81b95 100644 (file)
---- rt4/step4/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step5/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -14,14 +14,20 @@
-           "ip":"10.0.2.2",
+--- 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
-+          "active":true,
-+          "labels":[
-+            16010
-+          ]
-         },
-         {
-           "fib":true,
-           "ip":"10.0.3.2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16010
+           ]
+@@ -25,10 +28,21 @@
            "afi":"ipv4",
            "interfaceName":"eth-rt2-2",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            16010
-+          ]
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16010
+           ]
          }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
++          "active":true
++        }
        ]
      }
-@@ -41,14 +47,20 @@
-           "ip":"10.0.2.2",
+   ],
+@@ -48,6 +62,9 @@
            "afi":"ipv4",
            "interfaceName":"eth-rt2-1",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         },
-         {
-           "fib":true,
-           "ip":"10.0.3.2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+@@ -58,10 +75,25 @@
            "afi":"ipv4",
            "interfaceName":"eth-rt2-2",
--          "active":true
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
 +          "active":true,
 +          "labels":[
-+            3
++            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
++        }
        ]
      }
-@@ -68,21 +80,30 @@
+   ],
+@@ -169,13 +223,27 @@
            "ip":"10.0.2.2",
            "afi":"ipv4",
            "interfaceName":"eth-rt2-1",
 -          "active":true
 +          "active":true,
-+          "labels":[
-+            16030
++          "backupIndex":[
++            0
 +          ]
          },
          {
            "ip":"10.0.3.2",
            "afi":"ipv4",
            "interfaceName":"eth-rt2-2",
--          "active":true
 +          "active":true,
-+          "labels":[
-+            16030
++          "backupIndex":[
++            0
 +          ]
-         },
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.5",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt5",
+           "active":true
+         }
+       ]
+@@ -191,13 +259,30 @@
          {
-           "fib":true,
-           "ip":"10.0.6.5",
+           "ip":"10.0.2.2",
            "afi":"ipv4",
-           "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            16030
+-          "interfaceName":"eth-rt2-1"
++          "interfaceName":"eth-rt2-1",
++          "backupIndex":[
++            0
 +          ]
-         }
-       ]
-     }
-@@ -102,7 +123,24 @@
-           "ip":"10.0.6.5",
+         },
+         {
+           "ip":"10.0.3.2",
            "afi":"ipv4",
-           "interfaceName":"eth-rt5",
+           "interfaceName":"eth-rt2-2",
 -          "active":true
 +          "active":true,
 +          "backupIndex":[
 +            0
-+          ],
-+          "labels":[
-+            3
 +          ]
 +        }
 +      ],
 +      "backupNexthops":[
 +        {
-+          "ip":"10.0.7.6",
++          "ip":"10.0.6.5",
 +          "afi":"ipv4",
-+          "interfaceName":"eth-rt6",
++          "interfaceName":"eth-rt5",
 +          "active":true,
 +          "labels":[
-+            3
++            16030
 +          ]
          }
        ]
      }
-@@ -122,7 +160,24 @@
-           "ip":"10.0.7.6",
+@@ -213,12 +298,29 @@
+           "ip":"10.0.2.2",
            "afi":"ipv4",
-           "interfaceName":"eth-rt6",
+           "interfaceName":"eth-rt2-1",
 -          "active":true
 +          "active":true,
 +          "backupIndex":[
 +            0
-+          ],
-+          "labels":[
-+            3
++          ]
+         },
+         {
+           "ip":"10.0.3.2",
+           "afi":"ipv4",
+-          "interfaceName":"eth-rt2-2"
++          "interfaceName":"eth-rt2-2",
++          "backupIndex":[
++            0
 +          ]
 +        }
 +      ],
 +          "interfaceName":"eth-rt5",
 +          "active":true,
 +          "labels":[
-+            3
++            16030
 +          ]
          }
        ]
      }
-@@ -211,6 +266,31 @@
+@@ -238,6 +340,31 @@
            "ip":"10.0.6.5",
            "afi":"ipv4",
            "interfaceName":"eth-rt5",
            "active":true
          }
        ]
-@@ -231,6 +311,31 @@
+@@ -258,6 +385,31 @@
            "ip":"10.0.6.5",
            "afi":"ipv4",
            "interfaceName":"eth-rt5",
            "active":true
          }
        ]
-@@ -246,7 +351,18 @@
+@@ -273,7 +425,18 @@
          {
            "ip":"10.0.6.5",
            "afi":"ipv4",
          }
        ]
      }
-@@ -261,7 +377,18 @@
+@@ -288,7 +451,18 @@
          {
            "ip":"10.0.7.6",
            "afi":"ipv4",
index 52891943964bfc804ce519ccdbb9171de41f1e97..1bd207854c7433e1826c7fb0e5f0e761939ea822 100644 (file)
---- rt4/step4/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step5/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -13,13 +13,19 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt2-2",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            16011
-+          ]
-         },
-         {
-           "fib":true,
+--- 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
-+          "active":true,
-+          "labels":[
-+            16011
-+          ]
-         }
-       ]
-     }
-@@ -38,13 +44,19 @@
-           "fib":true,
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16011
+           ]
+@@ -23,10 +26,20 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt2-2",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         },
-         {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt2-1",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             16011
+           ]
          }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt5",
++          "active":true
++        }
        ]
      }
-@@ -63,19 +75,28 @@
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt2-2",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            16031
-+          ]
-         },
-         {
-           "fib":true,
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            16031
-+          ]
-         },
-         {
-           "fib":true,
+   ],
+@@ -45,6 +58,9 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt2-1",
--          "active":true
+           "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
++            16031,
++            16021
 +          ]
-         }
++        }
        ]
      }
-@@ -94,7 +115,23 @@
-           "fib":true,
+   ],
+@@ -116,10 +146,20 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
+           "active":true,
 +          "backupIndex":[
 +            0
 +          ],
-+          "labels":[
-+            3
-+          ]
-+        }
+           "labels":[
+             3
+           ]
+         }
 +      ],
 +      "backupNexthops":[
 +        {
 +          "afi":"ipv6",
 +          "interfaceName":"eth-rt6",
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
++          "active":true
++        }
        ]
      }
-@@ -113,7 +150,23 @@
-           "fib":true,
+   ],
+@@ -138,10 +178,20 @@
            "afi":"ipv6",
            "interfaceName":"eth-rt6",
--          "active":true
-+          "active":true,
+           "active":true,
 +          "backupIndex":[
 +            0
 +          ],
-+          "labels":[
-+            3
-+          ]
-+        }
+           "labels":[
+             3
+           ]
+         }
 +      ],
 +      "backupNexthops":[
 +        {
 +          "afi":"ipv6",
 +          "interfaceName":"eth-rt5",
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
++          "active":true
++        }
        ]
      }
+   ]
index 8bcd28aa2dabe0c118645b6cc28c678216d2fba5..664b129a1b9c1fe46d7536ef94405d140ae3d0f1 100644 (file)
---- rt4/step4/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step5/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -1,2 +1,210 @@
- {
-+  "16010":{
-+    "inLabel":16010,
-+    "installed":true,
-+    "nexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":16010,
-+        "installed":true,
-+        "nexthop":"10.0.3.2"
-+      },
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":16010,
-+        "installed":true,
-+        "nexthop":"10.0.2.2"
-+      }
-+    ]
-+  },
-+  "16011":{
-+    "inLabel":16011,
-+    "installed":true,
-+    "nexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":16011,
-+        "installed":true,
-+        "interface":"eth-rt2-2"
-+      },
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":16011,
-+        "installed":true,
-+        "interface":"eth-rt2-1"
+--- 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
++        ]
 +      }
-+    ]
-+  },
-+  "16020":{
-+    "inLabel":16020,
-+    "installed":true,
-+    "nexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":3,
-+        "installed":true,
-+        "nexthop":"10.0.3.2"
-+      },
++    ],
++    "backupNexthops":[
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
-+        "installed":true,
-+        "nexthop":"10.0.2.2"
++        "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
++        ]
 +      }
-+    ]
-+  },
-+  "16021":{
-+    "inLabel":16021,
-+    "installed":true,
-+    "nexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":3,
-+        "installed":true,
-+        "interface":"eth-rt2-2"
-+      },
++    ],
++    "backupNexthops":[
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
-+        "installed":true,
-+        "interface":"eth-rt2-1"
++        "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
++        ]
 +      }
-+    ]
-+  },
-+  "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"
-+      },
++    ],
++    "backupNexthops":[
 +      {
 +        "type":"SR (IS-IS)",
 +        "outLabel":16030,
-+        "installed":true,
 +        "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
++        ]
 +      }
-+    ]
-+  },
-+  "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"
-+      },
++    ],
++    "backupNexthops":[
 +      {
 +        "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,
+       }
+     ]
+   },
+@@ -127,7 +179,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.6.5"
 +        "nexthop":"10.0.6.5",
 +        "backupIndex":[
 +          0
 +        "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,
+       }
+     ]
+   },
+@@ -139,7 +201,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt5"
 +        "interface":"eth-rt5",
 +        "backupIndex":[
 +          0
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "interface":"eth-rt6"
-+      }
-+    ]
-+  },
-+  "16060":{
-+    "inLabel":16060,
-+    "installed":true,
-+    "nexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":3,
-+        "installed":true,
+       }
+     ]
+   },
+@@ -151,7 +223,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "nexthop":"10.0.7.6"
 +        "nexthop":"10.0.7.6",
 +        "backupIndex":[
 +          0
 +        "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,
+       }
+     ]
+   },
+@@ -163,7 +245,17 @@
+         "type":"SR (IS-IS)",
+         "outLabel":3,
+         "installed":true,
+-        "interface":"eth-rt6"
 +        "interface":"eth-rt6",
 +        "backupIndex":[
 +          0
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "interface":"eth-rt5"
-+      }
-+    ]
-+  }
- }
+       }
+     ]
+   }
index 03f31f727317336223e0674a482cf5fb85bf3398..c758b89839c4f06e5ca26fff4b1e090467daf3df 100644 (file)
@@ -1,6 +1,33 @@
---- rt4/step5/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step6/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -102,7 +102,7 @@
+--- 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":[
index 43621e117c169b903b62ac9229cdf1b2e043af64..ca495216ddd66d35844fc61c5cf403ed3d756051 100644 (file)
@@ -1,6 +1,15 @@
---- rt4/step5/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step6/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -86,7 +86,7 @@
+--- 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":[
index 871824bb6a01a323ad77ebba4fb66bb22ce0f899..630e0419cf2a566eee9bcb0d0a2e0f6a23b29f29 100644 (file)
@@ -1,6 +1,24 @@
---- rt4/step5/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step6/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -89,7 +89,7 @@
+--- 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)",
@@ -9,7 +27,7 @@
          "installed":true,
          "nexthop":"10.0.6.5"
        }
-@@ -113,7 +113,7 @@
+@@ -165,7 +165,7 @@
        },
        {
          "type":"SR (IS-IS)",
index 1f1de16c0e9035361b3e605ccdb189875e5f320d..30e0dcf3c0c098ee98ebf9b8f35b2ff70f71d012 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step6/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step7/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -126,9 +126,6 @@
+--- 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
            ]
          }
        ],
-@@ -137,10 +134,7 @@
-           "ip":"10.0.7.6",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt6",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
index 1c2f0f6fef29a262d28b15e9202946ec5c1db830..2606027d7514329b4d0c1c8b2126c2c6302a0778 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step6/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step7/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -118,9 +118,6 @@
+--- 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
            ]
          }
        ],
-@@ -128,10 +125,7 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt6",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
index dfe7aef93a933b9f335468314d0e0aad224556a6..5334cfd04860a5c0dd06baf16142b4167f4d2ea0 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step6/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step7/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -119,50 +119,6 @@
+--- 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 @@
        }
      ]
    },
index e9445650a7779713a54431f987fc336e1ca32568..b393970e423bb59081388897951360c62c80d743 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step7/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step8/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-@@ -126,6 +126,9 @@
+--- 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
            ]
          }
        ],
-@@ -134,7 +137,10 @@
-           "ip":"10.0.7.6",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt6",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
index 0d699ad92e9e87d234df61809895981a258f51cc..8bad2edcf339857371c3f88e6f62323f7825431d 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step7/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step8/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -118,6 +118,9 @@
+--- 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
            ]
          }
        ],
-@@ -125,7 +128,10 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt6",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
index 145d3b1fa1dd432203c934f7209fdce81019aa70..d296dbdcafc70654dc66a99e95164e566a1d60bb 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step7/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step8/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -119,6 +119,50 @@
+--- 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 @@
        }
      ]
    },
index 6ae67bcfbe65d95e8b77736bbd8c466ac7646b70..408cbfb0ba6a110c70f078390aaaee43a3afc6ac 100644 (file)
@@ -1,6 +1,6 @@
---- rt4/step8/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt4/step9/show_mpls_table.ref      2020-08-31 22:42:48.839561398 -0300
-@@ -119,15 +119,15 @@
+--- 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 @@
        }
      ]
    },
@@ -19,7 +19,7 @@
          "backupIndex":[
            0
          ]
-@@ -137,19 +137,19 @@
+@@ -189,19 +189,19 @@
        {
          "type":"SR (IS-IS)",
          "outLabel":3,
@@ -43,7 +43,7 @@
          "backupIndex":[
            0
          ]
-@@ -159,19 +159,19 @@
+@@ -211,19 +211,19 @@
        {
          "type":"SR (IS-IS)",
          "outLabel":3,
@@ -67,7 +67,7 @@
          "backupIndex":[
            0
          ]
-@@ -181,19 +181,19 @@
+@@ -233,19 +233,19 @@
        {
          "type":"SR (IS-IS)",
          "outLabel":3,
@@ -91,7 +91,7 @@
          "backupIndex":[
            0
          ]
-@@ -203,7 +203,7 @@
+@@ -255,7 +255,7 @@
        {
          "type":"SR (IS-IS)",
          "outLabel":3,
index ce320d0b1297be86f7a18e7468492ca1b3dfe1f8..f747065f9c13c8eb2d71718706affc86caa5cf7b 100644 (file)
@@ -15,6 +15,9 @@
           "afi":"ipv4",
           "interfaceName":"eth-rt3-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16010
           ]
           "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
+        }
       ]
     }
   ],
           "afi":"ipv4",
           "interfaceName":"eth-rt3-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             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
+          ]
+        }
       ]
     }
   ],
           "ip":"10.0.8.6",
           "afi":"ipv4",
           "interfaceName":"eth-rt6",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "ip":"10.0.6.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "ip":"10.0.4.3",
           "afi":"ipv4",
           "interfaceName":"eth-rt3-1",
-          "active":true
+          "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
         }
       ]
         {
           "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
+          ]
         }
       ]
     }
           "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
+          ]
         }
       ]
     }
index 5bda17760e27df6815f541db5df81881cc7110c7..6c0a5e0b9b19c5b40fe81ee888589d914e03a140 100644 (file)
@@ -14,6 +14,9 @@
           "afi":"ipv6",
           "interfaceName":"eth-rt3-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16011
           ]
           "afi":"ipv6",
           "interfaceName":"eth-rt3-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             16011
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true
+        }
       ]
     }
   ],
@@ -43,7 +56,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt3-1",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16021
@@ -52,7 +65,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt3-1",
           "active":true,
           "labels":[
             16021
@@ -85,6 +98,9 @@
           "afi":"ipv6",
           "interfaceName":"eth-rt3-1",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
           "afi":"ipv6",
           "interfaceName":"eth-rt3-2",
           "active":true,
+          "backupIndex":[
+            0
+          ],
           "labels":[
             3
           ]
         }
+      ],
+      "backupNexthops":[
+        {
+          "afi":"ipv6",
+          "interfaceName":"eth-rt4",
+          "active":true,
+          "labels":[
+            16021,
+            16031
+          ]
+        }
       ]
     }
   ],
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt6",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt4",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
index 84ba09910caf54d823362f67b7ccdb00461c158d..2b70392adc08c65356c68dadcb2be0911323d633 100644 (file)
@@ -7,13 +7,26 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.5.3"
+        "nexthop":"10.0.5.3",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.4.3"
+        "nexthop":"10.0.4.3",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "nexthop":"10.0.6.4"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt3-2"
+        "interface":"eth-rt3-2",
+        "backupIndex":[
+          0
+        ]
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt3-1"
+        "interface":"eth-rt3-1",
+        "backupIndex":[
+          0
+        ]
+      }
+    ],
+    "backupNexthops":[
+      {
+        "type":"SR (IS-IS)",
+        "outLabel":3,
+        "interface":"eth-rt4"
       }
     ]
   },
         "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"
       }
     ]
   },
         "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"
       }
     ]
   },
index f9f01414c9fae7e9e7d84a6b7ff5851d35cd3fed..6402b51893a0b8fce1e1b237fe594adda020ac57 100644 (file)
@@ -1,15 +1,54 @@
---- rt5/step3/show_ip_route.ref        2020-08-31 22:42:48.839561398 -0300
-+++ rt5/step4/show_ip_route.ref        2020-08-31 22:42:48.843561366 -0300
-@@ -69,7 +69,7 @@
+--- 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":[
--            16020
-+            3
+             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
+-          ]
+-        }
        ]
-@@ -126,9 +126,6 @@
+     }
+   ],
+@@ -158,9 +137,6 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -137,10 +134,7 @@
-           "ip":"10.0.8.6",
+@@ -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-rt6",
+           "interfaceName":"eth-rt3-2",
+-          "active":true,
+-          "backupIndex":[
+-            0
+-          ]
+-        }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "ip":"10.0.6.4",
+-          "afi":"ipv4",
+-          "interfaceName":"eth-rt4",
 -          "active":true,
 -          "labels":[
--            3
+-            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"
          }
        ]
      }
index 3e3c7d8541dd6367ff12276ee818d4d28393012a..7a0135bf04db548f1acac3eb4144b54efa647968 100644 (file)
@@ -1,33 +1,59 @@
---- rt5/step3/show_ipv6_route.ref      2020-08-31 22:42:48.839561398 -0300
-+++ rt5/step4/show_ipv6_route.ref      2020-08-31 22:42:48.843561366 -0300
-@@ -55,7 +55,7 @@
+--- 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":[
+-          "active":true,
+-          "labels":[
 -            16021
-+            3
-           ]
+-          ]
++          "active":true
          },
          {
-@@ -118,9 +118,6 @@
+           "fib":true,
+@@ -98,9 +95,6 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt3-1",
            "active":true,
-           "backupIndex":[
-             0
+-          "backupIndex":[
+-            0
 -          ],
--          "labels":[
--            3
+           "labels":[
+             3
            ]
-         }
-       ],
-@@ -128,10 +125,7 @@
-         {
+@@ -110,24 +104,10 @@
            "afi":"ipv6",
-           "interfaceName":"eth-rt6",
+           "interfaceName":"eth-rt3-2",
+           "active":true,
+-          "backupIndex":[
+-            0
+-          ],
+           "labels":[
+             3
+           ]
+         }
+-      ],
+-      "backupNexthops":[
+-        {
+-          "afi":"ipv6",
+-          "interfaceName":"eth-rt4",
 -          "active":true,
 -          "labels":[
--            3
+-            16021,
+-            16031
 -          ]
-+          "active":true
-         }
+-        }
        ]
      }
+   ],
+@@ -148,9 +128,6 @@
+           "active":true,
+           "backupIndex":[
+             0
+-          ],
+-          "labels":[
+-            3
+           ]
+         }
+       ],
index 21c426e678f35195f238551587f4336542476aae..299dac76402bff79f614058c1ac59d8a2ca9a028 100644 (file)
@@ -1,27 +1,88 @@
---- rt5/step3/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step4/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
-@@ -53,7 +53,7 @@
-       },
-       {
-         "type":"SR (IS-IS)",
+--- 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,
-+        "outLabel":3,
+-        "installed":true,
+-        "nexthop":"10.0.6.4"
+       }
+     ]
+   },
+@@ -100,12 +94,6 @@
+         "outLabel":16021,
          "installed":true,
-         "nexthop":"10.0.6.4"
+         "interface":"eth-rt3-1"
+-      },
+-      {
+-        "type":"SR (IS-IS)",
+-        "outLabel":16021,
+-        "installed":true,
+-        "interface":"eth-rt4"
        }
-@@ -77,7 +77,7 @@
+     ]
+   },
+@@ -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":16021,
-+        "outLabel":3,
+         "outLabel":3,
          "installed":true,
-         "interface":"eth-rt4"
-       }
-@@ -119,50 +119,6 @@
+-        "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,
 -        "type":"SR (IS-IS)",
 -        "outLabel":3,
 -        "interface":"eth-rt6"
--      }
--    ]
--  },
-   "16060":{
-     "inLabel":16060,
-     "installed":true,
++        "interface":"eth-rt3-1"
+       }
+     ]
+   },
index 49253b130f1903e3cf141c64874f78166592be96..31f70b17a3c70030857da6d44e340ae293cfd89d 100644 (file)
@@ -1,15 +1,54 @@
---- rt5/step4/show_ip_route.ref        2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step5/show_ip_route.ref        2020-08-31 22:42:48.843561366 -0300
-@@ -69,7 +69,7 @@
+--- 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
-+            16020
+             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
++          ]
++        }
        ]
-@@ -126,6 +126,9 @@
+     }
+   ],
+@@ -137,6 +158,9 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -134,7 +137,10 @@
-           "ip":"10.0.8.6",
+@@ -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-rt6",
+           "interfaceName":"eth-rt3-2",
 -          "active":true
 +          "active":true,
++          "backupIndex":[
++            0
++          ]
++        }
++      ],
++      "backupNexthops":[
++        {
++          "ip":"10.0.6.4",
++          "afi":"ipv4",
++          "interfaceName":"eth-rt4",
++          "active":true,
 +          "labels":[
-+            3
++            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
 +          ]
          }
        ]
index 2ee7db9e7e1e87884d86be29736e66a9b620bb25..59d9755e183e5a45d2e48d290a37d115d5b402ff 100644 (file)
@@ -1,33 +1,59 @@
---- rt5/step4/show_ipv6_route.ref      2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step5/show_ipv6_route.ref      2020-08-31 22:42:48.843561366 -0300
-@@ -55,7 +55,7 @@
+--- 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,
-           "labels":[
--            3
+-          "active":true
++          "active":true,
++          "labels":[
 +            16021
-           ]
++          ]
          },
          {
-@@ -118,6 +118,9 @@
+           "fib":true,
+@@ -95,6 +98,9 @@
+           "afi":"ipv6",
+           "interfaceName":"eth-rt3-1",
            "active":true,
-           "backupIndex":[
-             0
++          "backupIndex":[
++            0
 +          ],
-+          "labels":[
-+            3
+           "labels":[
+             3
            ]
-         }
-       ],
-@@ -125,7 +128,10 @@
-         {
+@@ -104,10 +110,24 @@
            "afi":"ipv6",
-           "interfaceName":"eth-rt6",
--          "active":true
+           "interfaceName":"eth-rt3-2",
+           "active":true,
++          "backupIndex":[
++            0
++          ],
+           "labels":[
+             3
+           ]
+         }
++      ],
++      "backupNexthops":[
++        {
++          "afi":"ipv6",
++          "interfaceName":"eth-rt4",
 +          "active":true,
 +          "labels":[
-+            3
++            16021,
++            16031
 +          ]
-         }
++        }
        ]
      }
+   ],
+@@ -128,6 +148,9 @@
+           "active":true,
+           "backupIndex":[
+             0
++          ],
++          "labels":[
++            3
+           ]
+         }
+       ],
index 269b8ddc940ce5d71a994af4f0e9022cddc2338f..669c07e3447289a2c9699686897553d51adeea49 100644 (file)
@@ -1,27 +1,89 @@
---- rt5/step4/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step5/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
-@@ -53,7 +53,7 @@
+--- 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":3,
-+        "outLabel":16020,
+         "outLabel":16021,
          "installed":true,
-         "nexthop":"10.0.6.4"
-       }
-@@ -77,7 +77,7 @@
++        "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,
-+        "outLabel":16021,
+         "outLabel":3,
          "installed":true,
-         "interface":"eth-rt4"
-       }
-@@ -119,6 +119,50 @@
+-        "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,
 +        "type":"SR (IS-IS)",
 +        "outLabel":3,
 +        "interface":"eth-rt6"
-+      }
-+    ]
-+  },
-   "16060":{
-     "inLabel":16060,
-     "installed":true,
+       }
+     ]
+   },
index f70ac77e6a9cf139f9dad32554f8aec91e768272..a4f82cbf1056ed9205903310f8ef3c431cfcfacc 100644 (file)
@@ -1,5 +1,5 @@
---- rt5/step5/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
-+++ rt5/step6/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
+--- 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":{
@@ -9,7 +9,7 @@
      "installed":true,
      "nexthops":[
        {
-@@ -17,8 +17,8 @@
+@@ -30,8 +30,8 @@
        }
      ]
    },
@@ -20,7 +20,7 @@
      "installed":true,
      "nexthops":[
        {
-@@ -35,8 +35,8 @@
+@@ -61,56 +61,56 @@
        }
      ]
    },
      "installed":true,
      "nexthops":[
        {
-@@ -59,8 +59,8 @@
+         "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"
        }
      ]
    },
      "installed":true,
      "nexthops":[
        {
-@@ -83,8 +83,8 @@
+         "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"
        }
      ]
    },
@@ -53,7 +89,7 @@
      "installed":true,
      "nexthops":[
        {
-@@ -101,8 +101,8 @@
+@@ -140,8 +140,8 @@
        }
      ]
    },
      "installed":true,
      "nexthops":[
        {
-@@ -119,8 +119,8 @@
+@@ -171,8 +171,8 @@
        }
      ]
    },
      "installed":true,
      "nexthops":[
        {
-@@ -141,8 +141,8 @@
+@@ -193,8 +193,8 @@
        }
      ]
    },
      "installed":true,
      "nexthops":[
        {
-@@ -163,8 +163,8 @@
+@@ -215,8 +215,8 @@
        }
      ]
    },
      "installed":true,
      "nexthops":[
        {
-@@ -185,8 +185,8 @@
+@@ -237,8 +237,8 @@
        }
      ]
    },
index c9615d1e458bf43c63f73c482c4a7650fdec8bc9..5bcef4c2f6df604251fda0ec7fb5320f5e9221a6 100644 (file)
           "ip":"10.0.8.5",
           "afi":"ipv4",
           "interfaceName":"eth-rt5",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "ip":"10.0.7.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "ip":"10.0.8.5",
           "afi":"ipv4",
           "interfaceName":"eth-rt5",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
           "ip":"10.0.7.4",
           "afi":"ipv4",
           "interfaceName":"eth-rt4",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
index b69c1491ec780996839979ce507b207ff9701935..8294b071367228ff8e2d1cdd3c0d460ddf50c4da 100644 (file)
@@ -12,7 +12,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt4",
+          "interfaceName":"eth-rt5",
           "active":true,
           "labels":[
             16011
@@ -21,7 +21,7 @@
         {
           "fib":true,
           "afi":"ipv6",
-          "interfaceName":"eth-rt5",
+          "interfaceName":"eth-rt4",
           "active":true,
           "labels":[
             16011
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt5",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt4",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt5",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
         {
           "afi":"ipv6",
           "interfaceName":"eth-rt4",
-          "active":true,
-          "labels":[
-            3
-          ]
+          "active":true
         }
       ]
     }
index 2aa794124a3169ebc4434c4fef7e2b85b37ac405..33dbf592047f45575986580e3a0db55b5c816ed0 100644 (file)
@@ -7,13 +7,13 @@
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.8.5"
+        "nexthop":"10.0.7.4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16010,
         "installed":true,
-        "nexthop":"10.0.7.4"
+        "nexthop":"10.0.8.5"
       }
     ]
   },
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt5"
+        "interface":"eth-rt4"
       },
       {
         "type":"SR (IS-IS)",
         "outLabel":16011,
         "installed":true,
-        "interface":"eth-rt4"
+        "interface":"eth-rt5"
       }
     ]
   },
index 7e6810d6d31a4f0ad7884e4bd3ed33c616f0c175..04adaefe784b287ba50ca5ccc7efe335408c8d47 100644 (file)
@@ -1,15 +1,18 @@
---- rt6/step3/show_ip_route.ref        2020-08-31 22:42:48.843561366 -0300
-+++ rt6/step4/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-@@ -16,7 +16,7 @@
+--- 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":[
+-          "active":true,
+-          "labels":[
 -            16010
-+            3
-           ]
+-          ]
++          "active":true
          },
          {
-@@ -50,9 +50,6 @@
+           "fib":true,
+@@ -50,9 +47,6 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -61,10 +58,7 @@
-           "ip":"10.0.8.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
-@@ -124,9 +118,6 @@
+@@ -118,9 +112,6 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -135,10 +126,7 @@
-           "ip":"10.0.8.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
index 8c424f60650d2b5268ace9f253c4ff780e042f83..20aa1ec83b0a41684ebcb3c2401a1e033f464339 100644 (file)
@@ -1,15 +1,18 @@
---- rt6/step3/show_ipv6_route.ref      2020-08-31 22:42:48.843561366 -0300
-+++ rt6/step4/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -15,7 +15,7 @@
+--- 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":[
+-          "active":true,
+-          "labels":[
 -            16011
-+            3
-           ]
-         },
-         {
-@@ -47,9 +47,6 @@
+-          ]
++          "active":true
+         }
+       ]
+     }
+@@ -47,9 +44,6 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -57,10 +54,7 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
-@@ -117,9 +111,6 @@
+@@ -111,9 +105,6 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -127,10 +118,7 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
index 2ebbab8a2f6e2a04a47c9bc2a8768ad6e273b9cc..3f24547f6d547f40eb8e6e81c22ee4633f7bcbbd 100644 (file)
@@ -1,70 +1,32 @@
---- rt6/step3/show_mpls_table.ref      2020-08-31 22:42:48.843561366 -0300
-+++ rt6/step4/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -11,7 +11,7 @@
-       },
-       {
+--- 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,
-+        "outLabel":3,
+         "outLabel":16010,
          "installed":true,
-         "nexthop":"10.0.7.4"
-       }
-@@ -29,53 +29,9 @@
-       },
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":16011,
--        "installed":true,
--        "interface":"eth-rt4"
--      }
--    ]
--  },
--  "16020":{
--    "inLabel":16020,
--    "installed":true,
--    "nexthops":[
+-        "nexthop":"10.0.7.4"
+-      },
 -      {
 -        "type":"SR (IS-IS)",
--        "outLabel":16020,
+-        "outLabel":16010,
 -        "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,
+         "nexthop":"10.0.8.5"
+       }
+     ]
+@@ -25,12 +19,6 @@
+         "type":"SR (IS-IS)",
+         "outLabel":16011,
          "installed":true,
--        "interface":"eth-rt4",
--        "backupIndex":[
--          0
--        ]
--      }
--    ],
--    "backupNexthops":[
+-        "interface":"eth-rt4"
+-      },
 -      {
 -        "type":"SR (IS-IS)",
--        "outLabel":3,
--        "interface":"eth-rt5"
-+        "interface":"eth-rt4"
+-        "outLabel":16011,
+-        "installed":true,
+         "interface":"eth-rt5"
        }
      ]
-   },
-@@ -123,50 +79,6 @@
+@@ -123,50 +111,6 @@
        }
      ]
    },
index 5151f715809e7585dc436db827d451dcdae4a69c..9f73a2904e91ae1fab90a92239204c9ab713dcd2 100644 (file)
@@ -1,15 +1,18 @@
---- rt6/step4/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step5/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-@@ -16,7 +16,7 @@
+--- 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,
-           "labels":[
--            3
+-          "active":true
++          "active":true,
++          "labels":[
 +            16010
-           ]
++          ]
          },
          {
-@@ -50,6 +50,9 @@
+           "fib":true,
+@@ -47,6 +50,9 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -58,7 +61,10 @@
-           "ip":"10.0.8.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
-@@ -118,6 +124,9 @@
+@@ -112,6 +118,9 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -126,7 +135,10 @@
-           "ip":"10.0.8.5",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
index 2ddc9f82b62c6b78c76dc2e2c029e3561f924235..c9358d45b2a2cf1fbaa15b75df8565fa9af073fb 100644 (file)
@@ -1,15 +1,18 @@
---- rt6/step4/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step5/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -15,7 +15,7 @@
+--- 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,
-           "labels":[
--            3
+-          "active":true
++          "active":true,
++          "labels":[
 +            16011
-           ]
-         },
-         {
-@@ -47,6 +47,9 @@
++          ]
+         }
+       ]
+     }
+@@ -44,6 +47,9 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -54,7 +57,10 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
-@@ -111,6 +117,9 @@
+@@ -105,6 +111,9 @@
            "active":true,
            "backupIndex":[
              0
            ]
          }
        ],
-@@ -118,7 +127,10 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt5",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
index 18354ea604f662fdfe0081de2cbfc910106c6ed5..c9d67955ef456088c2fff72869809dc06b9b0c77 100644 (file)
@@ -1,73 +1,32 @@
---- rt6/step4/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step5/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -11,7 +11,7 @@
-       },
-       {
+--- 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":3,
-+        "outLabel":16010,
+         "outLabel":16010,
          "installed":true,
-         "nexthop":"10.0.7.4"
-       }
-@@ -29,12 +29,56 @@
-       },
-       {
-         "type":"SR (IS-IS)",
--        "outLabel":3,
-+        "outLabel":16011,
-         "installed":true,
-         "interface":"eth-rt4"
-       }
-     ]
-   },
-+  "16020":{
-+    "inLabel":16020,
-+    "installed":true,
-+    "nexthops":[
++        "nexthop":"10.0.7.4"
++      },
 +      {
 +        "type":"SR (IS-IS)",
-+        "outLabel":16020,
++        "outLabel":16010,
 +        "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":[
+         "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":16021,
++        "outLabel":16011,
 +        "installed":true,
-+        "interface":"eth-rt4",
-+        "backupIndex":[
-+          0
-+        ]
-+      }
-+    ],
-+    "backupNexthops":[
-+      {
-+        "type":"SR (IS-IS)",
-+        "outLabel":3,
-+        "interface":"eth-rt5"
-+      }
-+    ]
-+  },
-   "16030":{
-     "inLabel":16030,
-     "installed":true,
-@@ -79,6 +123,50 @@
+         "interface":"eth-rt5"
+       }
+     ]
+@@ -111,6 +123,50 @@
        }
      ]
    },
index cddb6ab4bc1a7d486b0524c00dd9867d1596231f..527ec74958f3911fe29d7852226629d065bf4e67 100644 (file)
@@ -1,5 +1,5 @@
---- rt6/step5/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step6/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
+--- 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,
@@ -9,7 +9,7 @@
            ]
          }
        ]
-@@ -89,7 +89,7 @@
+@@ -86,7 +86,7 @@
              0
            ],
            "labels":[
index 389d87edc9fd64d75393cf669a97a98deb0408a0..7b8f8022f24534a9eaa3f5250c5b74362ce2a4f2 100644 (file)
@@ -1,15 +1,15 @@
---- rt6/step5/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step6/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -24,7 +24,7 @@
+--- 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
            ]
-         }
-       ]
-@@ -84,7 +84,7 @@
+         },
+         {
+@@ -81,7 +81,7 @@
              0
            ],
            "labels":[
index 8d5385dd0c81c96f5d62aef9552dcf86d23f183a..edd5afeeb80aa61113041086b929a0a63e9878ce 100644 (file)
@@ -1,23 +1,23 @@
---- rt6/step5/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step6/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -5,7 +5,7 @@
-     "nexthops":[
+--- 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 @@
        },
-@@ -23,7 +23,7 @@
-     "nexthops":[
        {
          "type":"SR (IS-IS)",
 -        "outLabel":16011,
 +        "outLabel":30011,
          "installed":true,
          "interface":"eth-rt5"
-       },
+       }
 @@ -85,7 +85,7 @@
      "nexthops":[
        {
index e9b88ce90b659093dd4a79b8d04f5a8710557024..7553dd22e5794ede0967d1b92205550913abecc0 100644 (file)
@@ -1,6 +1,6 @@
---- rt6/step6/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step7/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-@@ -161,9 +161,6 @@
+--- 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
            ]
          }
        ],
-@@ -172,10 +169,7 @@
-           "ip":"10.0.7.4",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt4",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
index a65d3e8e40d25e9c842c233f100e62bfed28a88c..b56890de0fcd53c80964e5bff80007741b5c8e1b 100644 (file)
@@ -1,6 +1,6 @@
---- rt6/step6/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step7/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -152,9 +152,6 @@
+--- 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
            ]
          }
        ],
-@@ -162,10 +159,7 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt4",
--          "active":true,
--          "labels":[
--            3
--          ]
-+          "active":true
-         }
-       ]
-     }
index 0d119554c7b6e0b1ff3ffc6d86328b3e382bb6ff..ff043fb0bf309fe4357f6165b44d61837e12690f 100644 (file)
@@ -1,5 +1,5 @@
---- rt6/step6/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step7/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
+--- 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"
        }
index cb9d758f324963e2ebac1bceac1c4421e830cfd3..d0b25bffa31ce95eef45c633ff947e56fc9f84f5 100644 (file)
@@ -1,6 +1,6 @@
---- rt6/step7/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step8/show_ip_route.ref        2020-08-31 22:42:48.847561334 -0300
-@@ -161,6 +161,9 @@
+--- 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
            ]
          }
        ],
-@@ -169,7 +172,10 @@
-           "ip":"10.0.7.4",
-           "afi":"ipv4",
-           "interfaceName":"eth-rt4",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
index cac719262de8c88b2200c62dba796f222772b8fa..203175510c0f28e496278607c3b4822f362cea70 100644 (file)
@@ -1,6 +1,6 @@
---- rt6/step7/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step8/show_ipv6_route.ref      2020-08-31 22:42:48.847561334 -0300
-@@ -152,6 +152,9 @@
+--- 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
            ]
          }
        ],
-@@ -159,7 +162,10 @@
-         {
-           "afi":"ipv6",
-           "interfaceName":"eth-rt4",
--          "active":true
-+          "active":true,
-+          "labels":[
-+            3
-+          ]
-         }
-       ]
-     }
index 917954b0774184036d17e054b899884b5615fd2a..535f30bf358329bdac5b94d24c52c6b756fdf21e 100644 (file)
@@ -1,5 +1,5 @@
---- rt6/step7/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step8/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
+--- 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"
        }
index 3c9558e56a9d971ad4fc95bd856e3bbb1b17d0c3..b6e5396554a2fb338bb6a45b0ec3f6b6eede229f 100644 (file)
@@ -1,5 +1,5 @@
---- rt6/step8/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
-+++ rt6/step9/show_mpls_table.ref      2020-08-31 22:42:48.847561334 -0300
+--- 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 @@
        }
      ]
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 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
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 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 af243f7ca57f52110ffa8ac1305402be3af6db8e..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);
@@ -586,6 +586,7 @@ static void restart_done(struct daemon *dmn)
                return;
        }
        THREAD_OFF(dmn->t_wakeup);
+
        if (try_connect(dmn) < 0)
                SET_WAKEUP_DOWN(dmn);
 }
@@ -678,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;
@@ -866,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 f02d28800ec6ae452cd2eff7a171c50799b98032..de78758dbb40b2e5cec8ed3002ec3f8512e287a0 100644 (file)
@@ -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 e10b5e7848b68768e100b999e0f24f97ad4bbc7b..820c4b2861a89805e856daa79bd1b97559cd3f89 100644 (file)
@@ -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 06d1a793b5a91df0001c384f987e2335d687b126..c3b39e3750800e1ead3a60c75e6e47093187e1d0 100644 (file)
@@ -1381,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 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 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 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 8fd0c96bd9225159843bdd7a626a6bfc96e8ae08..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;
index 6b6409f8455ab506837d74ea53043f340ec8fe13..ced29e1a25fc1550d8c0292b0ecdaab1ea4b6474 100644 (file)
@@ -170,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 c02156b378d4f50a4951bf0d434e5f6e5ec237eb..3bce62bfa8c2a4c226e553fe8020fd118cabd7d0 100644 (file)
@@ -366,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);
@@ -382,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 a406884187b7d47fa21fb7976510f71d1b8d4c3b..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,34 +372,46 @@ 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");
                }
@@ -361,7 +421,15 @@ void zebra_evpn_es_evi_show_vni(struct vty *vty, bool uj, vni_t vni, int detail)
 
                return;
        }
-       zebra_evpn_es_evi_show_one_evpn(zevpn, vty, json, detail);
+
+       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);
+       }
 }
 
 /* Initialize the ES tables maintained per-L2_VNI */
@@ -689,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)
 {
@@ -696,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",
@@ -716,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)
@@ -775,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
@@ -810,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;
@@ -821,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);
 }
 
 /*****************************************************************************
@@ -895,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);
                }
        }
@@ -919,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 */
@@ -936,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;
@@ -1015,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);
        }
 }
@@ -1163,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);
@@ -1308,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)
 {
@@ -1324,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
         */
@@ -1340,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
         */
@@ -1350,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);
 
@@ -1450,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;
        }
 
@@ -1475,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) {
@@ -1498,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) {
@@ -1525,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) {
@@ -1554,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;
@@ -1579,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)
@@ -1708,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)
 {
@@ -1721,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)
@@ -1746,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);
@@ -1757,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));
 
@@ -1801,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)
@@ -1821,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");
        }
@@ -1843,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)
@@ -1872,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)
@@ -1895,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,
@@ -1992,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
@@ -2029,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
@@ -2095,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;
 
@@ -2122,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();
@@ -2152,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 860dc5b05429f3f127b9d94a772fef81beb28a6f..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);
@@ -802,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
@@ -1283,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);
 
@@ -1790,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;
@@ -1797,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";
@@ -1814,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:");
@@ -1840,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);
@@ -1867,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)) {
@@ -1952,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];
@@ -2006,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");
@@ -2021,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");
@@ -2133,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 e0ad4f1cbed192752a2656a72fd94978744c7ed4..dc4969501991de638fa4fb7ee498435e95592e35 100644 (file)
@@ -331,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)
@@ -348,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 =
@@ -364,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);
@@ -494,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);
@@ -1502,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:
@@ -1560,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,
@@ -2243,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;
@@ -2254,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;
        }
@@ -2273,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;
                }
 
@@ -2300,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",
@@ -2351,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
@@ -2513,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;
 
@@ -2521,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)
@@ -2547,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);
@@ -2570,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)
@@ -2578,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);
        }
 
@@ -2620,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++) {
@@ -2639,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));
                }
        }
@@ -2846,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;
@@ -2910,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);
                }
        }
 
@@ -2957,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);
                }
        }
 
@@ -3007,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);
                }
        }
 
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 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 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 cc6e9c2ad34cb8999cfdc8fa007da466dec7be96..e76ecc85a60cab1c688eed40a22b702146010594 100644 (file)
@@ -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);
                        }
 
@@ -1497,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;
@@ -1509,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.
@@ -1547,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)) {
@@ -1558,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;
 
@@ -1570,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);
        }
 
        /*
@@ -1599,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;
        }
 
@@ -1612,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)");
 
@@ -1647,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) {
@@ -1658,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;
 
@@ -1667,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);
        }
 
        /*
@@ -1687,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);
@@ -1751,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;
@@ -1763,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;
        }
@@ -1789,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));
 
        /*
@@ -1831,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);
        }
@@ -1842,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);
        }
@@ -1883,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 */
@@ -1924,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:
@@ -1954,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);
                }
 
                /*
@@ -2033,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;
@@ -2042,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;
        }
@@ -2064,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
@@ -2081,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;
@@ -2115,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)));
                }
@@ -2152,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);
        }
 
        /*
@@ -2169,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,
@@ -2180,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.
@@ -2198,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.
@@ -2289,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
@@ -2464,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;
        }
@@ -2831,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);
 
@@ -2849,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;
        }
 
@@ -2911,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);
@@ -2969,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))
                                      : "");
 
@@ -3086,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)
@@ -3116,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);
                }
@@ -3316,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)
@@ -3865,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 9c6ed445853bef7887146fb1bac6947503db05de..521f969fcc44ac3518900196e65bc5baa407bd5f 100644 (file)
@@ -480,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);
@@ -506,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);
+               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,
@@ -1200,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));
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 920fdd6baa58bcdb4927efd54adab0c0b00804e5..df0e22b40c0ef5e39a6e2b05699b8eff240426be 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;
 }
@@ -1768,6 +1787,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 +2433,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 +2628,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 +2657,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 +2679,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;
 
@@ -3905,6 +3947,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);
@@ -3961,6 +4004,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 82e871801ab52964dea9e18b135ced9e7456ca1b..4b3b142d4024bb804cee1a903edff68b61343310 100644 (file)
@@ -310,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(
@@ -341,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);
@@ -631,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;
@@ -641,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);
@@ -659,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;
@@ -673,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));
@@ -695,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",
@@ -945,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);
@@ -1270,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);
@@ -1280,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));
@@ -1300,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;
 
@@ -1465,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. */
@@ -1474,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;
                }
 
@@ -1486,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 */
@@ -1913,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",
@@ -3425,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);
@@ -3445,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) {
@@ -3766,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);
        }
@@ -3828,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,
@@ -3836,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));
                }
 
@@ -3887,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;
@@ -4128,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. */
@@ -4212,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. */
@@ -4795,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 */
@@ -4859,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 */
@@ -4966,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 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");