summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--babeld/babel_interface.c7
-rw-r--r--babeld/babel_main.c2
-rw-r--r--babeld/babel_zebra.c19
-rw-r--r--babeld/babel_zebra.h2
-rw-r--r--babeld/babeld.c13
-rw-r--r--babeld/babeld.h2
-rw-r--r--babeld/kernel.c3
-rw-r--r--babeld/message.c107
-rw-r--r--babeld/route.c27
-rw-r--r--babeld/route.h1
-rw-r--r--bfdd/bfd.c22
-rw-r--r--bfdd/ptm_adapter.c32
-rw-r--r--bgpd/bgp_attr.c18
-rw-r--r--bgpd/bgp_bfd.c4
-rw-r--r--bgpd/bgp_ecommunity.c12
-rw-r--r--bgpd/bgp_evpn.c25
-rw-r--r--bgpd/bgp_evpn_mh.c25
-rw-r--r--bgpd/bgp_evpn_private.h2
-rw-r--r--bgpd/bgp_evpn_vty.c8
-rw-r--r--bgpd/bgp_flowspec.c7
-rw-r--r--bgpd/bgp_flowspec_private.h1
-rw-r--r--bgpd/bgp_fsm.c23
-rw-r--r--bgpd/bgp_io.c16
-rw-r--r--bgpd/bgp_io.h1
-rw-r--r--bgpd/bgp_label.c10
-rw-r--r--bgpd/bgp_mac.c3
-rw-r--r--bgpd/bgp_main.c8
-rw-r--r--bgpd/bgp_mplsvpn.c52
-rw-r--r--bgpd/bgp_mplsvpn.h31
-rw-r--r--bgpd/bgp_mplsvpn_snmp.c4
-rw-r--r--bgpd/bgp_nht.c81
-rw-r--r--bgpd/bgp_nht.h9
-rw-r--r--bgpd/bgp_packet.c132
-rw-r--r--bgpd/bgp_pbr.c98
-rw-r--r--bgpd/bgp_pbr.h2
-rw-r--r--bgpd/bgp_route.c106
-rw-r--r--bgpd/bgp_route.h1
-rw-r--r--bgpd/bgp_routemap.c3
-rw-r--r--bgpd/bgp_routemap_nb_config.c6
-rw-r--r--bgpd/bgp_rpki.c5
-rw-r--r--bgpd/bgp_updgrp.c4
-rw-r--r--bgpd/bgp_vty.c22
-rw-r--r--bgpd/bgp_zebra.c232
-rw-r--r--bgpd/bgp_zebra.h3
-rw-r--r--bgpd/bgpd.c45
-rw-r--r--bgpd/bgpd.h16
-rw-r--r--bgpd/rfapi/rfapi.c11
-rw-r--r--bgpd/rfapi/rfapi_backend.h1
-rw-r--r--bgpd/rfapi/rfapi_import.c82
-rw-r--r--bgpd/rfapi/rfapi_import.h3
-rw-r--r--bgpd/rfapi/rfapi_rib.c138
-rw-r--r--bgpd/rfapi/rfapi_rib.h3
-rw-r--r--bgpd/rfapi/vnc_import_bgp.c18
-rw-r--r--configure.ac2
-rw-r--r--doc/developer/mgmtd-dev.rst5
-rw-r--r--doc/figures/datastores.drawio291
-rw-r--r--doc/figures/datastores.svg3
-rw-r--r--doc/user/frr-reload.rst2
-rw-r--r--doc/user/static.rst4
-rw-r--r--eigrpd/eigrp_main.c2
-rw-r--r--eigrpd/eigrp_northbound.c2
-rw-r--r--eigrpd/eigrp_vty.c12
-rw-r--r--eigrpd/eigrp_zebra.c32
-rw-r--r--eigrpd/eigrpd.c1
-rw-r--r--eigrpd/eigrpd.h2
-rw-r--r--isisd/isis_adjacency.c2
-rw-r--r--isisd/isis_affinitymap.c4
-rw-r--r--isisd/isis_affinitymap.h1
-rw-r--r--isisd/isis_bfd.c2
-rw-r--r--isisd/isis_cli.c34
-rw-r--r--isisd/isis_flags.c4
-rw-r--r--isisd/isis_ldp_sync.c7
-rw-r--r--isisd/isis_lsp.c1
-rw-r--r--isisd/isis_main.c4
-rw-r--r--isisd/isis_route.c6
-rw-r--r--isisd/isis_snmp.c62
-rw-r--r--isisd/isis_spf.c2
-rw-r--r--isisd/isis_sr.c4
-rw-r--r--isisd/isis_te.c10
-rw-r--r--isisd/isis_tlvs.c46
-rw-r--r--isisd/isis_zebra.c97
-rw-r--r--isisd/isis_zebra.h2
-rw-r--r--isisd/isisd.c12
-rw-r--r--ldpd/lde.c4
-rw-r--r--ldpd/ldp_snmp.c4
-rw-r--r--ldpd/ldp_vty_exec.c5
-rw-r--r--ldpd/ldp_zebra.c62
-rw-r--r--ldpd/ldpd.c18
-rw-r--r--ldpd/ldpd.h2
-rw-r--r--ldpd/ldpe.c4
-rw-r--r--lib/affinitymap.c9
-rw-r--r--lib/affinitymap.h2
-rw-r--r--lib/darr.h8
-rw-r--r--lib/elf_py.c14
-rw-r--r--lib/filter_cli.c12
-rw-r--r--lib/frr_pthread.h8
-rw-r--r--lib/libfrr.c8
-rw-r--r--lib/link_state.c6
-rw-r--r--lib/linklist.h6
-rw-r--r--lib/northbound.c24
-rw-r--r--lib/northbound.h21
-rw-r--r--lib/northbound_oper.c80
-rw-r--r--lib/printf/vfprintf.c16
-rw-r--r--lib/resolver.c2
-rw-r--r--lib/srv6.h12
-rw-r--r--lib/zclient.c6
-rw-r--r--mgmtd/mgmt_ds.c40
-rw-r--r--mgmtd/mgmt_ds.h12
-rw-r--r--mgmtd/mgmt_fe_adapter.c7
-rw-r--r--mgmtd/mgmt_txn.c38
-rw-r--r--nhrpd/nhrp_peer.c5
-rw-r--r--nhrpd/nhrp_route.c44
-rw-r--r--ospf6d/ospf6_abr.c2
-rw-r--r--ospf6d/ospf6_area.h12
-rw-r--r--ospf6d/ospf6_asbr.c4
-rw-r--r--ospf6d/ospf6_bfd.c4
-rw-r--r--ospf6d/ospf6_main.c6
-rw-r--r--ospf6d/ospf6_snmp.c4
-rw-r--r--ospf6d/ospf6_top.c12
-rw-r--r--ospf6d/ospf6_top.h1
-rw-r--r--ospf6d/ospf6_zebra.c70
-rw-r--r--ospf6d/ospf6_zebra.h4
-rw-r--r--ospf6d/ospf6d.c4
-rw-r--r--ospfclient/ospfclient.c20
-rw-r--r--ospfd/ospf_bfd.c2
-rw-r--r--ospfd/ospf_flood.c8
-rw-r--r--ospfd/ospf_ldp_sync.c14
-rw-r--r--ospfd/ospf_packet.c6
-rw-r--r--ospfd/ospf_te.c12
-rw-r--r--ospfd/ospf_vty.c2
-rw-r--r--ospfd/ospf_zebra.c64
-rw-r--r--ospfd/ospfd.c19
-rw-r--r--ospfd/ospfd.h3
-rw-r--r--pathd/path_cli.c42
-rw-r--r--pathd/path_ted.c14
-rw-r--r--pathd/path_zebra.c20
-rw-r--r--pbrd/pbr_zebra.c36
-rw-r--r--pceplib/pcep_pcc.c48
-rw-r--r--pceplib/pcep_utils_memory.c8
-rw-r--r--pimd/pim6_cmd.c16
-rw-r--r--pimd/pim_cmd.c112
-rw-r--r--pimd/pim_iface.c16
-rw-r--r--pimd/pim_mlag.c10
-rw-r--r--pimd/pim_nht.c1
-rw-r--r--pimd/pim_upstream.c3
-rw-r--r--pimd/pim_zebra.c30
-rw-r--r--pimd/pim_zlookup.c50
-rw-r--r--pimd/pim_zpthread.c4
-rw-r--r--ripd/rip_bfd.c4
-rw-r--r--ripd/rip_main.c1
-rw-r--r--ripd/rip_snmp.c4
-rw-r--r--ripd/rip_zebra.c40
-rw-r--r--ripd/ripd.c10
-rw-r--r--ripngd/ripng_zebra.c36
-rw-r--r--sharpd/sharp_zebra.c90
-rw-r--r--staticd/static_vty.c80
-rw-r--r--staticd/static_zebra.c120
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/isisd/test_common.c8
-rw-r--r--tests/isisd/test_fuzz_isis_tlv.c2
-rw-r--r--tests/lib/northbound/test_oper_data.c3
-rw-r--r--tests/lib/test_darr.c57
-rw-r--r--tests/lib/test_printfrr.c2
-rw-r--r--tests/topotests/all_protocol_startup/test_all_protocol_startup.py41
-rw-r--r--tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py4
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py8
-rw-r--r--tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf1
-rw-r--r--tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py115
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf18
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf14
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf17
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json34
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf14
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf16
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf14
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf16
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf14
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf16
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf14
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf16
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf14
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf97
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json38
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json35
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json38
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json3
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json6
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf41
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf98
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json36
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json6
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json36
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json37
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json3
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf41
-rwxr-xr-xtests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py18
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf9
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf7
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json88
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json48
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json5
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json50
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf8
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py18
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf35
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json59
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json59
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh1
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf12
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf35
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json59
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json59
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh1
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf12
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/bgpd.conf (renamed from tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/bgpd.conf)42
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json64
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json63
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json62
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json63
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf21
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/bgpd.conf (renamed from tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/bgpd.conf)43
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh4
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json64
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json63
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json63
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json63
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf21
-rw-r--r--tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py143
-rw-r--r--tests/topotests/high_ecmp/r1/frr.conf5
-rw-r--r--tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf3
-rw-r--r--tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf3
-rw-r--r--tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf209
-rw-r--r--tests/topotests/high_ecmp/r2/frr.conf5
-rw-r--r--tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf3
-rw-r--r--tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf3
-rw-r--r--tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf208
-rw-r--r--tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py171
-rw-r--r--tests/topotests/lib/bgp.py32
-rw-r--r--tests/topotests/lib/common_config.py12
-rwxr-xr-xtests/topotests/lib/mcast-tester.py34
-rw-r--r--tests/topotests/static_simple/test_static_simple.py20
-rwxr-xr-xtests/topotests/static_srv6_sids/test_static_srv6_sids.py30
-rwxr-xr-xtools/frr-reload.py35
-rwxr-xr-xtools/generate_support_bundle.py26
-rw-r--r--tools/start-stop-daemon.c44
-rw-r--r--vrrpd/vrrp_zebra.c14
-rw-r--r--vtysh/vtysh.c150
-rw-r--r--vtysh/vtysh.h2
-rw-r--r--vtysh/vtysh_config.c28
-rw-r--r--vtysh/vtysh_main.c2
-rw-r--r--yang/frr-bfdd.yang49
-rw-r--r--yang/frr-eigrpd.yang2
-rw-r--r--yang/frr-pathd.yang96
-rw-r--r--yang/frr-zebra.yang240
-rw-r--r--zebra/dplane_fpm_nl.c29
-rw-r--r--zebra/fpm_listener.c209
-rw-r--r--zebra/interface.c22
-rw-r--r--zebra/irdp_packet.c6
-rw-r--r--zebra/kernel_socket.c2
-rw-r--r--zebra/main.c6
-rw-r--r--zebra/rib.h11
-rw-r--r--zebra/rt_netlink.c21
-rw-r--r--zebra/rtadv.c2
-rw-r--r--zebra/zapi_msg.c3
-rw-r--r--zebra/zebra_dplane.c8
-rw-r--r--zebra/zebra_dplane.h3
-rw-r--r--zebra/zebra_fpm_netlink.c2
-rw-r--r--zebra/zebra_nhg.c37
-rw-r--r--zebra/zebra_pbr.c62
-rw-r--r--zebra/zebra_pbr.h5
-rw-r--r--zebra/zebra_rib.c168
-rw-r--r--zebra/zebra_snmp.c8
-rw-r--r--zebra/zebra_srv6.c58
-rw-r--r--zebra/zebra_srv6_vty.c5
-rw-r--r--zebra/zebra_vty.c17
-rw-r--r--zebra/zserv.c6
317 files changed, 6077 insertions, 2347 deletions
diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c
index c99dadd083..4653b96db4 100644
--- a/babeld/babel_interface.c
+++ b/babeld/babel_interface.c
@@ -755,8 +755,10 @@ babel_interface_close_all(void)
}
/* Disable babel redistribution */
for (type = 0; type < ZEBRA_ROUTE_MAX; type++) {
- zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type, 0, VRF_DEFAULT);
- zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP6, type, 0, VRF_DEFAULT);
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, babel_zclient, AFI_IP, type, 0,
+ VRF_DEFAULT);
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, babel_zclient, AFI_IP6, type, 0,
+ VRF_DEFAULT);
}
}
@@ -974,6 +976,7 @@ DEFUN (show_babel_route,
{
struct route_stream *routes = NULL;
struct xroute_stream *xroutes = NULL;
+
routes = route_stream(0);
if(routes) {
while(1) {
diff --git a/babeld/babel_main.c b/babeld/babel_main.c
index ddc75f7182..77658eb57d 100644
--- a/babeld/babel_main.c
+++ b/babeld/babel_main.c
@@ -19,6 +19,7 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
#include "memory.h"
#include "libfrr.h"
#include "lib_errors.h"
+#include "plist.h"
#include "babel_main.h"
#include "babeld.h"
@@ -313,6 +314,7 @@ babel_exit_properly(void)
debugf(BABEL_DEBUG_COMMON, "Done.");
vrf_terminate();
+ prefix_list_reset();
frr_fini();
exit(0);
diff --git a/babeld/babel_zebra.c b/babeld/babel_zebra.c
index bead9f27ef..54f0f79aa0 100644
--- a/babeld/babel_zebra.c
+++ b/babeld/babel_zebra.c
@@ -19,7 +19,7 @@ void babelz_zebra_init(void);
/* we must use a pointer because of zclient.c's functions (new, free). */
-struct zclient *zclient;
+struct zclient *babel_zclient;
/* Debug types */
static const struct {
@@ -94,9 +94,10 @@ DEFUN (babel_redistribute_type,
}
if (!negate)
- zclient_redistribute (ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type, 0, VRF_DEFAULT);
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, babel_zclient, afi, type, 0, VRF_DEFAULT);
else {
- zclient_redistribute (ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type, 0, VRF_DEFAULT);
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, babel_zclient, afi, type, 0,
+ VRF_DEFAULT);
/* perhaps should we remove xroutes having the same type... */
}
return CMD_SUCCESS;
@@ -230,11 +231,11 @@ static zclient_handler *const babel_handlers[] = {
void babelz_zebra_init(void)
{
- zclient = zclient_new(master, &zclient_options_default, babel_handlers,
- array_size(babel_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
+ babel_zclient = zclient_new(master, &zclient_options_default, babel_handlers,
+ array_size(babel_handlers));
+ zclient_init(babel_zclient, ZEBRA_ROUTE_BABEL, 0, &babeld_privs);
- zclient->zebra_connected = babel_zebra_connected;
+ babel_zclient->zebra_connected = babel_zebra_connected;
install_element(BABEL_NODE, &babel_redistribute_type_cmd);
install_element(ENABLE_NODE, &debug_babel_cmd);
@@ -248,6 +249,6 @@ void babelz_zebra_init(void)
void
babel_zebra_close_connexion(void)
{
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(babel_zclient);
+ zclient_free(babel_zclient);
}
diff --git a/babeld/babel_zebra.h b/babeld/babel_zebra.h
index 7f960d3961..0455bad7e1 100644
--- a/babeld/babel_zebra.h
+++ b/babeld/babel_zebra.h
@@ -8,7 +8,7 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
#include "vty.h"
-extern struct zclient *zclient;
+extern struct zclient *babel_zclient;
void babelz_zebra_init(void);
void babel_zebra_close_connexion(void);
diff --git a/babeld/babeld.c b/babeld/babeld.c
index 4e68f05df4..a9ad97509a 100644
--- a/babeld/babeld.c
+++ b/babeld/babeld.c
@@ -108,8 +108,8 @@ babel_config_write (struct vty *vty)
/* list redistributed protocols */
for (afi = AFI_IP; afi <= AFI_IP6; afi++) {
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (i != zclient->redist_default &&
- vrf_bitmap_check(&zclient->redist[afi][i], VRF_DEFAULT)) {
+ if (i != babel_zclient->redist_default &&
+ vrf_bitmap_check(&babel_zclient->redist[afi][i], VRF_DEFAULT)) {
vty_out(vty, " redistribute %s %s\n",
(afi == AFI_IP) ? "ipv4" : "ipv6",
zebra_route_string(i));
@@ -183,6 +183,10 @@ static void babel_read_protocol(struct event *thread)
flog_err_sys(EC_LIB_SOCKET, "recv: %s", safe_strerror(errno));
}
} else {
+ if(ntohs(sin6.sin6_port) != BABEL_PORT) {
+ return;
+ }
+
FOR_ALL_INTERFACES(vrf, ifp) {
if(!if_up(ifp))
continue;
@@ -212,7 +216,8 @@ static void babel_init_routing_process(struct event *thread)
babel_main_loop(thread);/* this function self-add to the t_update thread */
}
-/* fill "myid" with an unique id (only if myid != {0}). */
+/* fill "myid" with an unique id (only if myid != {0} and myid != {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}). */
static void
babel_get_myid(void)
{
@@ -222,7 +227,7 @@ babel_get_myid(void)
int i;
/* if we already have an id (from state file), we return. */
- if (memcmp(myid, zeroes, 8) != 0) {
+ if (memcmp(myid, zeroes, 8) != 0 && memcmp(myid, ones, 8) != 0) {
return;
}
diff --git a/babeld/babeld.h b/babeld/babeld.h
index 17a0381d2c..f4ee09a761 100644
--- a/babeld/babeld.h
+++ b/babeld/babeld.h
@@ -21,6 +21,8 @@ Copyright 2011 by Matthieu Boutier and Juliusz Chroboczek
#undef MAX
#undef MIN
+#define BABEL_PORT 6696
+
#define MAX(x,y) ((x)<=(y)?(y):(x))
#define MIN(x,y) ((x)<=(y)?(x):(y))
diff --git a/babeld/kernel.c b/babeld/kernel.c
index 4957b04e77..ec562a9e93 100644
--- a/babeld/kernel.c
+++ b/babeld/kernel.c
@@ -176,8 +176,7 @@ zebra_route(int add, int family, const unsigned char *pref, unsigned short plen,
debugf(BABEL_DEBUG_ROUTE, "%s route (%s) to zebra",
add ? "adding" : "removing",
(family == AF_INET) ? "ipv4" : "ipv6");
- return zclient_route_send (add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
- zclient, &api);
+ return zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, babel_zclient, &api);
}
int
diff --git a/babeld/message.c b/babeld/message.c
index c45daa2425..cc751426ba 100644
--- a/babeld/message.c
+++ b/babeld/message.c
@@ -27,6 +27,7 @@ int split_horizon = 1;
unsigned short myseqno = 0;
#define UNICAST_BUFSIZE 1024
+#define RESERVED 0
static int unicast_buffered = 0;
static unsigned char *unicast_buffer = NULL;
struct neighbour *unicast_neighbour = NULL;
@@ -52,7 +53,17 @@ static const unsigned char tlv_min_length[MESSAGE_MAX + 1] =
static bool
known_ae(int ae)
{
- return ae <= 4;
+ return ae <= 3;
+}
+
+static inline bool
+is_all_zero(const unsigned char *data, int len) {
+ for (int j = 0; j < len; j++) {
+ if (data[j] != 0) {
+ return false;
+ }
+ }
+ return true;
}
/* Parse a network prefix, encoded in the somewhat baroque compressed
@@ -151,7 +162,11 @@ static bool parse_update_subtlv(const unsigned char *a, int alen,
"Received Mandatory bit set but this FRR version is not prepared to handle it at this point");
return true;
} else if (type == SUBTLV_PADN) {
- /* Nothing. */
+ if (!is_all_zero(a + i + 2, len)) {
+ debugf(BABEL_DEBUG_COMMON,
+ "Received pad%d with non zero MBZ field.",
+ len);
+ }
} else if (type == SUBTLV_DIVERSITY) {
if (len > DIVERSITY_HOPS) {
flog_err(
@@ -214,7 +229,11 @@ parse_hello_subtlv(const unsigned char *a, int alen,
"Received subtlv with Mandatory bit, this version of FRR is not prepared to handle this currently");
return -2;
} else if (type == SUBTLV_PADN) {
- /* Nothing to do. */
+ if (!is_all_zero(a + i + 2, len)) {
+ debugf(BABEL_DEBUG_COMMON,
+ "Received pad%d with non zero MBZ field.",
+ len);
+ }
} else if (type == SUBTLV_TIMESTAMP) {
if (len >= 4) {
DO_NTOHL(*hello_send_us, a + i + 2);
@@ -261,7 +280,11 @@ parse_ihu_subtlv(const unsigned char *a, int alen,
}
if(type == SUBTLV_PADN) {
- /* Nothing to do. */
+ if (!is_all_zero(a + i + 2, len)) {
+ debugf(BABEL_DEBUG_COMMON,
+ "Received pad%d with non zero MBZ field.",
+ len);
+ }
} else if(type == SUBTLV_TIMESTAMP) {
if(len >= 8) {
DO_NTOHL(*hello_send_us, a + i + 2);
@@ -290,7 +313,7 @@ parse_request_subtlv(int ae, const unsigned char *a, int alen,
int have_src_prefix = 0;
while(i < alen) {
- type = a[0];
+ type = a[i];
if(type == SUBTLV_PAD1) {
i++;
continue;
@@ -441,6 +464,14 @@ parse_packet(const unsigned char *from, struct interface *ifp,
return;
}
+ if (v4mapped(from)) {
+ memcpy(v4_nh, from, 16);
+ have_v4_nh = 1;
+ } else {
+ memcpy(v6_nh, from, 16);
+ have_v6_nh = 1;
+ }
+
i = 0;
while(i < bodylen) {
message = packet + 4 + i;
@@ -454,12 +485,23 @@ parse_packet(const unsigned char *from, struct interface *ifp,
len = message[1];
if(type == MESSAGE_PADN) {
+ if (!is_all_zero(message + 2, len)) {
+ debugf(BABEL_DEBUG_COMMON,
+ "Received pad%d with non zero MBZ field.",
+ len);
+ }
debugf(BABEL_DEBUG_COMMON,"Received pad%d from %s on %s.",
len, format_address(from), ifp->name);
} else if(type == MESSAGE_ACK_REQ) {
- unsigned short nonce, interval;
+ unsigned short nonce, interval, Reserved;
+ DO_NTOHS(Reserved, message + 2);
DO_NTOHS(nonce, message + 4);
DO_NTOHS(interval, message + 6);
+ if (Reserved != RESERVED) {
+ debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) with non zero Reserved from %s on %s.",
+ nonce, interval, format_address(from), ifp->name);
+ goto done;
+ }
debugf(BABEL_DEBUG_COMMON,"Received ack-req (%04X %d) from %s on %s.",
nonce, interval, format_address(from), ifp->name);
send_ack(neigh, nonce, interval);
@@ -520,8 +562,15 @@ parse_packet(const unsigned char *from, struct interface *ifp,
}
} else if(type == MESSAGE_IHU) {
unsigned short txcost, interval;
+ unsigned char Reserved;
unsigned char address[16];
int rc;
+ Reserved = message[3];
+ if (Reserved != RESERVED) {
+ debugf(BABEL_DEBUG_COMMON,"Received ihu with non zero Reserved from %s on %s.",
+ format_address(from), ifp->name);
+ goto done;
+ }
DO_NTOHS(txcost, message + 4);
DO_NTOHS(interval, message + 6);
rc = network_address(message[2], message + 8, len - 6, address);
@@ -583,6 +632,20 @@ parse_packet(const unsigned char *from, struct interface *ifp,
int rc, parsed_len;
bool ignore_update = false;
+ // Basic sanity check on length
+ if (len < 10) {
+ if (len < 2 || (message[3] & 0x80)) {
+ have_v4_prefix = have_v6_prefix = 0;
+ }
+ goto fail;
+ }
+
+ if(!known_ae(message[2])) {
+ debugf(BABEL_DEBUG_COMMON,"Received update with unknown AE %d. Ignoring.",
+ message[2]);
+ goto done;
+ }
+
DO_NTOHS(interval, message + 6);
DO_NTOHS(seqno, message + 8);
DO_NTOHS(metric, message + 10);
@@ -621,7 +684,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
}
have_router_id = 1;
}
- if(!have_router_id && message[2] != 0) {
+ if(metric < INFINITY && !have_router_id && message[2] != 0) {
flog_err(EC_BABEL_PACKET,
"Received prefix with no router id.");
goto fail;
@@ -633,9 +696,15 @@ parse_packet(const unsigned char *from, struct interface *ifp,
format_address(from), ifp->name);
if(message[2] == 0) {
- if(metric < 0xFFFF) {
+ if(metric < INFINITY) {
flog_err(EC_BABEL_PACKET,
- "Received wildcard update with finite metric.");
+ "Received wildcard update with finite metric.");
+ goto done;
+ }
+ // Add check for Plen and Omitted
+ if(message[4] != 0 || message[5] != 0) {
+ flog_err(EC_BABEL_PACKET,
+ "Received wildcard retraction with non-zero Plen or Omitted.");
goto done;
}
retract_neighbour_routes(neigh);
@@ -737,8 +806,14 @@ parse_packet(const unsigned char *from, struct interface *ifp,
send_update(neigh->ifp, 0, prefix, plen);
}
} else if(type == MESSAGE_MH_REQUEST) {
- unsigned char prefix[16], plen;
+ unsigned char prefix[16], plen, Reserved;
unsigned short seqno;
+ Reserved = message[7];
+ if (Reserved != RESERVED) {
+ debugf(BABEL_DEBUG_COMMON,"Received request with non zero Reserved from %s on %s.",
+ format_address(from), ifp->name);
+ goto done;
+ }
int rc;
DO_NTOHS(seqno, message + 4);
rc = network_prefix(message[2], message[3], 0,
@@ -750,6 +825,10 @@ parse_packet(const unsigned char *from, struct interface *ifp,
format_prefix(prefix, plen),
format_address(from), ifp->name,
format_eui64(message + 8), seqno);
+ if(message[6] == 0) {
+ debugf(BABEL_DEBUG_COMMON, "Received request with invalid hop count 0");
+ goto done;
+ }
handle_request(neigh, prefix, plen, message[6], seqno, message + 8);
} else {
debugf(BABEL_DEBUG_COMMON,"Received unknown packet type %d from %s on %s.",
@@ -1921,8 +2000,14 @@ handle_request(struct neighbour *neigh, const unsigned char *prefix,
/* We were about to forward a request to its requestor. Try to
find a different neighbour to forward the request to. */
struct babel_route *other_route;
+ /* First try feasible routes as required by RFC */
+ other_route = find_best_route(prefix, plen, 1, neigh);
- other_route = find_best_route(prefix, plen, 0, neigh);
+ if(!other_route || route_metric(other_route) >= INFINITY) {
+ /* If no feasible route found, try non-feasible routes */
+ other_route = find_best_route(prefix, plen, 0, neigh);
+ }
+
if(other_route && route_metric(other_route) < INFINITY)
successor = other_route->neigh;
}
diff --git a/babeld/route.c b/babeld/route.c
index 466f41383c..eefc5c94df 100644
--- a/babeld/route.c
+++ b/babeld/route.c
@@ -1078,17 +1078,26 @@ route_lost(struct source *src, unsigned oldmetric)
new_route = find_best_route(src->prefix, src->plen, 1, NULL);
if(new_route) {
consider_route(new_route);
- } else if(oldmetric < INFINITY) {
- /* Avoid creating a blackhole. */
- send_update_resend(NULL, src->prefix, src->plen);
- /* If the route was usable enough, try to get an alternate one.
- If it was not, we could be dealing with oscillations around
- the value of INFINITY. */
- if(oldmetric <= INFINITY / 2)
+ } else {
+ struct babel_route *unfeasible = find_best_route(src->prefix, src->plen, 0, NULL);
+
+ if(unfeasible && !route_expired(unfeasible)) {
+ /* MUST send seqno request when we have unexpired unfeasible routes */
send_request_resend(NULL, src->prefix, src->plen,
- src->metric >= INFINITY ?
- src->seqno : seqno_plus(src->seqno, 1),
+ seqno_plus(src->seqno, 1),
src->id);
+ } else if(oldmetric < INFINITY) {
+ /* Avoid creating a blackhole. */
+ send_update_resend(NULL, src->prefix, src->plen);
+ /* If the route was usable enough, try to get an alternate one.
+ If it was not, we could be dealing with oscillations around
+ the value of INFINITY. */
+ if(oldmetric <= INFINITY / 2)
+ send_request_resend(NULL, src->prefix, src->plen,
+ src->metric >= INFINITY ?
+ src->seqno : seqno_plus(src->seqno, 1),
+ src->id);
+ }
}
}
diff --git a/babeld/route.h b/babeld/route.h
index 89427b8415..ec050fd87b 100644
--- a/babeld/route.h
+++ b/babeld/route.h
@@ -38,7 +38,6 @@ struct babel_route {
struct route_stream;
-extern struct babel_route **routes;
extern int kernel_metric;
extern enum babel_diversity diversity_kind;
extern int diversity_factor;
diff --git a/bfdd/bfd.c b/bfdd/bfd.c
index 8d5306aaaf..e538aa64c2 100644
--- a/bfdd/bfd.c
+++ b/bfdd/bfd.c
@@ -755,26 +755,7 @@ void ptm_sbfd_echo_sess_dn(struct bfd_session *bfd, uint8_t diag)
static struct bfd_session *bfd_find_disc(struct sockaddr_any *sa,
uint32_t ldisc)
{
- struct bfd_session *bs;
-
- bs = bfd_id_lookup(ldisc);
- if (bs == NULL)
- return NULL;
-
- switch (bs->key.family) {
- case AF_INET:
- if (memcmp(&sa->sa_sin.sin_addr, &bs->key.peer,
- sizeof(sa->sa_sin.sin_addr)))
- return NULL;
- break;
- case AF_INET6:
- if (memcmp(&sa->sa_sin6.sin6_addr, &bs->key.peer,
- sizeof(sa->sa_sin6.sin6_addr)))
- return NULL;
- break;
- }
-
- return bs;
+ return bfd_id_lookup(ldisc);
}
struct bfd_session *ptm_bfd_sess_find(struct bfd_pkt *cp,
@@ -1564,6 +1545,7 @@ void bfd_set_shutdown(struct bfd_session *bs, bool shutdown)
return;
SET_FLAG(bs->flags, BFD_SESS_FLAG_SHUTDOWN);
+ bs->local_diag = BD_ADMIN_DOWN;
/* Handle data plane shutdown case. */
if (bs->bdc) {
diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c
index 74f2d39878..9728046fba 100644
--- a/bfdd/ptm_adapter.c
+++ b/bfdd/ptm_adapter.c
@@ -36,7 +36,7 @@ struct ptm_client {
TAILQ_HEAD(pcqueue, ptm_client);
static struct pcqueue pcqueue;
-static struct zclient *zclient;
+static struct zclient *bfd_zclient;
/*
@@ -209,7 +209,7 @@ int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state)
*
* q(64), l(32), w(16), c(8)
*/
- msg = zclient->obuf;
+ msg = bfd_zclient->obuf;
stream_reset(msg);
/* TODO: VRF handling */
@@ -264,7 +264,7 @@ int ptm_bfd_notify(struct bfd_session *bs, uint8_t notify_state)
/* Write packet size. */
stream_putw_at(msg, 0, stream_get_endp(msg));
- return zclient_send_message(zclient);
+ return zclient_send_message(bfd_zclient);
}
static void _ptm_msg_read_address(struct stream *msg, struct sockaddr_any *sa)
@@ -600,7 +600,7 @@ stream_failure:
static int bfdd_replay(ZAPI_CALLBACK_ARGS)
{
- struct stream *msg = zclient->ibuf;
+ struct stream *msg = bfd_zclient->ibuf;
uint32_t rcmd;
STREAM_GETL(msg, rcmd);
@@ -653,7 +653,7 @@ static void bfdd_zebra_connected(struct zclient *zc)
zclient_create_header(msg, ZEBRA_INTERFACE_ADD, VRF_DEFAULT);
/* Send requests. */
- zclient_send_message(zclient);
+ zclient_send_message(zc);
}
static void bfdd_sessions_enable_interface(struct interface *ifp)
@@ -837,32 +837,32 @@ void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv)
{
hook_register_prio(if_real, 0, bfd_ifp_create);
hook_register_prio(if_unreal, 0, bfd_ifp_destroy);
- zclient = zclient_new(master, &zclient_options_default, bfd_handlers,
- array_size(bfd_handlers));
- assert(zclient != NULL);
- zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv);
+ bfd_zclient = zclient_new(master, &zclient_options_default, bfd_handlers,
+ array_size(bfd_handlers));
+ assert(bfd_zclient != NULL);
+ zclient_init(bfd_zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv);
/* Send replay request on zebra connect. */
- zclient->zebra_connected = bfdd_zebra_connected;
+ bfd_zclient->zebra_connected = bfdd_zebra_connected;
}
void bfdd_zclient_register(vrf_id_t vrf_id)
{
- if (!zclient || zclient->sock < 0)
+ if (!bfd_zclient || bfd_zclient->sock < 0)
return;
- zclient_send_reg_requests(zclient, vrf_id);
+ zclient_send_reg_requests(bfd_zclient, vrf_id);
}
void bfdd_zclient_unregister(vrf_id_t vrf_id)
{
- if (!zclient || zclient->sock < 0)
+ if (!bfd_zclient || bfd_zclient->sock < 0)
return;
- zclient_send_dereg_requests(zclient, vrf_id);
+ zclient_send_dereg_requests(bfd_zclient, vrf_id);
}
void bfdd_zclient_stop(void)
{
- zclient_stop(zclient);
+ zclient_stop(bfd_zclient);
/* Clean-up and free ptm clients data memory. */
pc_free_all();
@@ -870,7 +870,7 @@ void bfdd_zclient_stop(void)
void bfdd_zclient_terminate(void)
{
- zclient_free(zclient);
+ zclient_free(bfd_zclient);
}
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index 9f8f1f6c69..b4adf47eb0 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -1444,11 +1444,11 @@ bgp_attr_malformed(struct bgp_attr_parser_args *args, uint8_t subcode,
uint8_t *notify_datap = (length > 0 ? args->startp : NULL);
if (bgp_debug_update(peer, NULL, NULL, 1)) {
- char attr_str[BUFSIZ] = {0};
+ char str[BUFSIZ] = { 0 };
- bgp_dump_attr(attr, attr_str, sizeof(attr_str));
+ bgp_dump_attr(attr, str, sizeof(str));
- zlog_debug("%s: attributes: %s", __func__, attr_str);
+ zlog_debug("%s: attributes: %s", __func__, str);
}
/* Only relax error handling for eBGP peers */
@@ -2043,11 +2043,11 @@ static int bgp_attr_aggregator(struct bgp_attr_parser_args *args)
peer->host, aspath_print(attr->aspath));
if (bgp_debug_update(peer, NULL, NULL, 1)) {
- char attr_str[BUFSIZ] = {0};
+ char str[BUFSIZ] = { 0 };
- bgp_dump_attr(attr, attr_str, sizeof(attr_str));
+ bgp_dump_attr(attr, str, sizeof(str));
- zlog_debug("%s: attributes: %s", __func__, attr_str);
+ zlog_debug("%s: attributes: %s", __func__, str);
}
} else {
SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR));
@@ -2094,11 +2094,11 @@ bgp_attr_as4_aggregator(struct bgp_attr_parser_args *args,
peer->host, aspath_print(attr->aspath));
if (bgp_debug_update(peer, NULL, NULL, 1)) {
- char attr_str[BUFSIZ] = {0};
+ char str[BUFSIZ] = { 0 };
- bgp_dump_attr(attr, attr_str, sizeof(attr_str));
+ bgp_dump_attr(attr, str, sizeof(str));
- zlog_debug("%s: attributes: %s", __func__, attr_str);
+ zlog_debug("%s: attributes: %s", __func__, str);
}
} else {
SET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS4_AGGREGATOR));
diff --git a/bgpd/bgp_bfd.c b/bgpd/bgp_bfd.c
index 5437b67f34..cef1192c10 100644
--- a/bgpd/bgp_bfd.c
+++ b/bgpd/bgp_bfd.c
@@ -30,7 +30,7 @@
DEFINE_MTYPE_STATIC(BGPD, BFD_CONFIG, "BFD configuration data");
-extern struct zclient *zclient;
+extern struct zclient *bgp_zclient;
static void bfd_session_status_update(struct bfd_session_params *bsp,
const struct bfd_session_status *bss,
@@ -651,7 +651,7 @@ DEFUN(no_neighbor_bfd_profile, no_neighbor_bfd_profile_cmd,
void bgp_bfd_init(struct event_loop *tm)
{
/* Initialize BFD client functions */
- bfd_protocol_integration_init(zclient, tm);
+ bfd_protocol_integration_init(bgp_zclient, tm);
/* "neighbor bfd" commands. */
install_element(BGP_NODE, &neighbor_bfd_cmd);
diff --git a/bgpd/bgp_ecommunity.c b/bgpd/bgp_ecommunity.c
index dcdf2ba25d..95c78cc49d 100644
--- a/bgpd/bgp_ecommunity.c
+++ b/bgpd/bgp_ecommunity.c
@@ -1441,14 +1441,14 @@ static char *_ecommunity_ecom2str(struct ecommunity *ecom, int format, int filte
snprintf(encbuf, sizeof(encbuf), "FS:action %s",
action);
} else if (sub_type == ECOMMUNITY_TRAFFIC_RATE) {
- union traffic_rate data;
+ union traffic_rate rate;
- data.rate_byte[3] = *(pnt+2);
- data.rate_byte[2] = *(pnt+3);
- data.rate_byte[1] = *(pnt+4);
- data.rate_byte[0] = *(pnt+5);
+ rate.rate_byte[3] = *(pnt + 2);
+ rate.rate_byte[2] = *(pnt + 3);
+ rate.rate_byte[1] = *(pnt + 4);
+ rate.rate_byte[0] = *(pnt + 5);
snprintf(encbuf, sizeof(encbuf), "FS:rate %f",
- data.rate_float);
+ rate.rate_float);
} else if (sub_type == ECOMMUNITY_TRAFFIC_MARKING) {
snprintf(encbuf, sizeof(encbuf),
"FS:marking %u", *(pnt + 5));
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 488f635b81..0ebef2ecfe 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -905,7 +905,7 @@ static enum zclient_send_status bgp_zebra_send_remote_macip(
bool esi_valid;
/* Check socket. */
- if (!zclient || zclient->sock < 0) {
+ if (!bgp_zclient || bgp_zclient->sock < 0) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: No zclient or zclient->sock exists",
__func__);
@@ -923,7 +923,7 @@ static enum zclient_send_status bgp_zebra_send_remote_macip(
if (!esi)
esi = zero_esi;
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(
@@ -984,7 +984,7 @@ static enum zclient_send_status bgp_zebra_send_remote_macip(
frrtrace(5, frr_bgp, evpn_mac_ip_zsend, add, vpn, p, remote_vtep_ip,
esi);
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
/*
@@ -998,7 +998,7 @@ bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
struct stream *s;
/* Check socket. */
- if (!zclient || zclient->sock < 0) {
+ if (!bgp_zclient || bgp_zclient->sock < 0) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: No zclient or zclient->sock exists",
__func__);
@@ -1014,7 +1014,7 @@ bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
return ZCLIENT_SEND_SUCCESS;
}
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(
@@ -1041,7 +1041,7 @@ bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
frrtrace(3, frr_bgp, evpn_bum_vtep_zsend, add, vpn, p);
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
/*
@@ -2062,8 +2062,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
bgp_path_info_add(dest, tmp_pi);
} else {
tmp_pi = local_pi;
- if (attrhash_cmp(tmp_pi->attr, attr)
- && !CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED))
+ if (!CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED) && attrhash_cmp(tmp_pi->attr, attr))
route_change = 0;
else {
/*
@@ -3154,8 +3153,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
pi = bgp_create_evpn_bgp_path_info(parent_pi, dest, &attr);
new_pi = true;
} else {
- if (attrhash_cmp(pi->attr, &attr)
- && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
+ if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) && attrhash_cmp(pi->attr, &attr)) {
bgp_dest_unlock_node(dest);
return 0;
}
@@ -3184,8 +3182,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
/* Gateway IP nexthop should be resolved */
if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
- if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi,
- NULL, 0, NULL))
+ if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi, NULL, 0, NULL, NULL))
bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
else {
if (BGP_DEBUG(nht, NHT)) {
@@ -3278,8 +3275,8 @@ static int install_evpn_route_entry_in_vni_common(
* install_evpn_route_entry_in_vni_mac() or
* install_evpn_route_entry_in_vni_ip()
*/
- if (attrhash_cmp(pi->attr, parent_pi->attr) &&
- !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED))
+ if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) &&
+ attrhash_cmp(pi->attr, parent_pi->attr))
return 0;
/* The attribute has changed. */
/* Add (or update) attribute to hash. */
diff --git a/bgpd/bgp_evpn_mh.c b/bgpd/bgp_evpn_mh.c
index 0ef3740d88..70040f83b9 100644
--- a/bgpd/bgp_evpn_mh.c
+++ b/bgpd/bgp_evpn_mh.c
@@ -212,8 +212,8 @@ static int bgp_evpn_es_route_install(struct bgp *bgp,
bgp_dest_lock_node((struct bgp_dest *)parent_pi->net);
bgp_path_info_add(dest, pi);
} else {
- if (attrhash_cmp(pi->attr, parent_pi->attr)
- && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)) {
+ if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) &&
+ attrhash_cmp(pi->attr, parent_pi->attr)) {
bgp_dest_unlock_node(dest);
return 0;
}
@@ -421,8 +421,7 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
bgp_path_info_add(dest, tmp_pi);
} else {
tmp_pi = local_pi;
- if (attrhash_cmp(tmp_pi->attr, attr)
- && !CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED))
+ if (!CHECK_FLAG(tmp_pi->flags, BGP_PATH_REMOVED) && attrhash_cmp(tmp_pi->attr, attr))
*route_changed = 0;
else {
/* The attribute has changed.
@@ -1388,7 +1387,7 @@ bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep,
uint32_t flags = 0;
/* Check socket. */
- if (!zclient || zclient->sock < 0) {
+ if (!bgp_zclient || bgp_zclient->sock < 0) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: No zclient or zclient->sock exists",
__func__);
@@ -1406,7 +1405,7 @@ bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep,
if (CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ESR))
SET_FLAG(flags, ZAPI_ES_VTEP_FLAG_ESR_RXED);
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s,
@@ -1428,7 +1427,7 @@ bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep,
frrtrace(3, frr_bgp, evpn_mh_vtep_zsend, add, es, es_vtep);
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
static enum zclient_send_status bgp_evpn_es_vtep_re_eval_active(
@@ -2877,7 +2876,7 @@ static void bgp_evpn_l3nhg_zebra_add_v4_or_v6(struct bgp_evpn_es_vrf *es_vrf,
if (!api_nhg.nexthop_num)
return;
- zclient_nhg_send(zclient, ZEBRA_NHG_ADD, &api_nhg);
+ zclient_nhg_send(bgp_zclient, ZEBRA_NHG_ADD, &api_nhg);
}
static bool bgp_evpn_l3nhg_zebra_ok(struct bgp_evpn_es_vrf *es_vrf)
@@ -2886,7 +2885,7 @@ static bool bgp_evpn_l3nhg_zebra_ok(struct bgp_evpn_es_vrf *es_vrf)
return false;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return false;
return true;
@@ -2921,7 +2920,7 @@ static void bgp_evpn_l3nhg_zebra_del_v4_or_v6(struct bgp_evpn_es_vrf *es_vrf,
frrtrace(4, frr_bgp, evpn_mh_nhg_zsend, false, v4_nhg, api_nhg.id,
es_vrf);
- zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg);
+ zclient_nhg_send(bgp_zclient, ZEBRA_NHG_DEL, &api_nhg);
}
static void bgp_evpn_l3nhg_zebra_del(struct bgp_evpn_es_vrf *es_vrf)
@@ -4477,7 +4476,7 @@ static void bgp_evpn_nh_zebra_update_send(struct bgp_evpn_nh *nh, bool add)
struct bgp *bgp_vrf = nh->bgp_vrf;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return;
/* Don't try to register if Zebra doesn't know of this instance. */
@@ -4488,7 +4487,7 @@ static void bgp_evpn_nh_zebra_update_send(struct bgp_evpn_nh *nh, bool add)
return;
}
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(
@@ -4513,7 +4512,7 @@ static void bgp_evpn_nh_zebra_update_send(struct bgp_evpn_nh *nh, bool add)
frrtrace(2, frr_bgp, evpn_mh_nh_rmac_zsend, add, nh);
- zclient_send_message(zclient);
+ zclient_send_message(bgp_zclient);
}
static void bgp_evpn_nh_zebra_update(struct bgp_evpn_nh *nh, bool add)
diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h
index 568d3d45ee..51d32b5003 100644
--- a/bgpd/bgp_evpn_private.h
+++ b/bgpd/bgp_evpn_private.h
@@ -673,8 +673,6 @@ static inline bool bgp_evpn_is_path_local(struct bgp *bgp,
&& pi->sub_type == BGP_ROUTE_STATIC);
}
-extern struct zclient *zclient;
-
extern void bgp_evpn_install_uninstall_default_route(struct bgp *bgp_vrf,
afi_t afi, safi_t safi,
bool add);
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 571cca22fd..bfd8fd7c22 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -1462,22 +1462,22 @@ static int bgp_show_ethernet_vpn(struct vty *vty, struct prefix_rd *prd,
output_count++;
if (use_json && json_array) {
- const struct prefix *p =
+ const struct prefix *pfx =
bgp_dest_get_prefix(rm);
json_prefix_info = json_object_new_object();
json_object_string_addf(json_prefix_info,
- "prefix", "%pFX", p);
+ "prefix", "%pFX", pfx);
json_object_int_add(json_prefix_info,
- "prefixLen", p->prefixlen);
+ "prefixLen", pfx->prefixlen);
json_object_object_add(json_prefix_info,
"paths", json_array);
json_object_object_addf(json_nroute,
json_prefix_info,
- "%pFX", p);
+ "%pFX", pfx);
json_array = NULL;
}
}
diff --git a/bgpd/bgp_flowspec.c b/bgpd/bgp_flowspec.c
index bd04970fd5..6f1780665d 100644
--- a/bgpd/bgp_flowspec.c
+++ b/bgpd/bgp_flowspec.c
@@ -105,13 +105,6 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
if (!attr)
withdraw = true;
- if (packet->length >= FLOWSPEC_NLRI_SIZELIMIT_EXTENDED) {
- flog_err(EC_BGP_FLOWSPEC_PACKET,
- "BGP flowspec nlri length maximum reached (%u)",
- packet->length);
- return BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT;
- }
-
for (; pnt < lim; pnt += psize) {
/* Clear prefix structure. */
memset(&p, 0, sizeof(p));
diff --git a/bgpd/bgp_flowspec_private.h b/bgpd/bgp_flowspec_private.h
index 049cb6df77..fa611bd372 100644
--- a/bgpd/bgp_flowspec_private.h
+++ b/bgpd/bgp_flowspec_private.h
@@ -7,7 +7,6 @@
#define _FRR_BGP_FLOWSPEC_PRIVATE_H
#define FLOWSPEC_NLRI_SIZELIMIT 240
-#define FLOWSPEC_NLRI_SIZELIMIT_EXTENDED 4095
/* Flowspec raffic action bit*/
#define FLOWSPEC_TRAFFIC_ACTION_TERMINAL 1
diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c
index 478f8c9136..f5d62828a1 100644
--- a/bgpd/bgp_fsm.c
+++ b/bgpd/bgp_fsm.c
@@ -94,10 +94,8 @@ int bgp_peer_reg_with_nht(struct peer *peer)
connected = 1;
return bgp_find_or_add_nexthop(peer->bgp, peer->bgp,
- family2afi(
- peer->connection->su.sa.sa_family),
- SAFI_UNICAST, NULL, peer, connected,
- NULL);
+ family2afi(peer->connection->su.sa.sa_family), SAFI_UNICAST,
+ NULL, peer, connected, NULL, NULL);
}
static void peer_xfer_stats(struct peer *peer_dst, struct peer *peer_src)
@@ -184,7 +182,11 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
EVENT_OFF(keeper->t_delayopen);
EVENT_OFF(keeper->t_connect_check_r);
EVENT_OFF(keeper->t_connect_check_w);
- EVENT_OFF(keeper->t_process_packet);
+
+ frr_with_mutex (&bm->peer_connection_mtx) {
+ if (peer_connection_fifo_member(&bm->connection_fifo, keeper))
+ peer_connection_fifo_del(&bm->connection_fifo, keeper);
+ }
/*
* At this point in time, it is possible that there are packets pending
@@ -305,8 +307,13 @@ static struct peer *peer_xfer_conn(struct peer *from_peer)
bgp_reads_on(keeper);
bgp_writes_on(keeper);
- event_add_event(bm->master, bgp_process_packet, keeper, 0,
- &keeper->t_process_packet);
+
+ frr_with_mutex (&bm->peer_connection_mtx) {
+ if (!peer_connection_fifo_member(&bm->connection_fifo, keeper)) {
+ peer_connection_fifo_add_tail(&bm->connection_fifo, keeper);
+ }
+ }
+ event_add_event(bm->master, bgp_process_packet, NULL, 0, &bm->e_process_packet);
return (peer);
}
@@ -1260,7 +1267,7 @@ void bgp_fsm_change_status(struct peer_connection *connection,
/* Transition into Clearing or Deleted must /always/ clear all routes..
* (and must do so before actually changing into Deleted..
*/
- if (status >= Clearing && (peer->established || peer == bgp->peer_self)) {
+ if (status >= Clearing && (peer->established || peer != bgp->peer_self)) {
bgp_clear_route_all(peer);
/* If no route was queued for the clear-node processing,
diff --git a/bgpd/bgp_io.c b/bgpd/bgp_io.c
index 729a8fe299..dac915a73d 100644
--- a/bgpd/bgp_io.c
+++ b/bgpd/bgp_io.c
@@ -99,7 +99,11 @@ void bgp_reads_off(struct peer_connection *connection)
assert(fpt->running);
event_cancel_async(fpt->master, &connection->t_read, NULL);
- EVENT_OFF(connection->t_process_packet);
+
+ frr_with_mutex (&bm->peer_connection_mtx) {
+ if (peer_connection_fifo_member(&bm->connection_fifo, connection))
+ peer_connection_fifo_del(&bm->connection_fifo, connection);
+ }
UNSET_FLAG(connection->thread_flags, PEER_THREAD_READS_ON);
}
@@ -292,9 +296,13 @@ done:
event_add_read(fpt->master, bgp_process_reads, connection,
connection->fd, &connection->t_read);
- if (added_pkt)
- event_add_event(bm->master, bgp_process_packet, connection, 0,
- &connection->t_process_packet);
+ if (added_pkt) {
+ frr_with_mutex (&bm->peer_connection_mtx) {
+ if (!peer_connection_fifo_member(&bm->connection_fifo, connection))
+ peer_connection_fifo_add_tail(&bm->connection_fifo, connection);
+ }
+ event_add_event(bm->master, bgp_process_packet, NULL, 0, &bm->e_process_packet);
+ }
}
/*
diff --git a/bgpd/bgp_io.h b/bgpd/bgp_io.h
index 8d481129e5..278980fde6 100644
--- a/bgpd/bgp_io.h
+++ b/bgpd/bgp_io.h
@@ -10,6 +10,7 @@
#define BGP_WRITE_PACKET_MAX 64U
#define BGP_READ_PACKET_MAX 10U
+#define BGP_PACKET_PROCESS_LIMIT 100
#include "bgpd/bgpd.h"
#include "frr_pthread.h"
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 8ed9584b0a..94f0659e44 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -26,7 +26,7 @@
#include "bgpd/bgp_debug.h"
#include "bgpd/bgp_errors.h"
-extern struct zclient *zclient;
+extern struct zclient *bgp_zclient;
/* MPLS Labels hash routines. */
@@ -157,7 +157,7 @@ int bgp_parse_fec_update(void)
afi_t afi;
safi_t safi;
- s = zclient->ibuf;
+ s = bgp_zclient->ibuf;
memset(&p, 0, sizeof(p));
p.family = stream_getw(s);
@@ -249,7 +249,7 @@ static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg,
p = bgp_dest_get_prefix(dest);
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return;
if (BGP_DEBUG(labelpool, LABELPOOL))
@@ -258,7 +258,7 @@ static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg,
/* If the route node has a local_label assigned or the
* path node has an MPLS SR label index allowing zebra to
* derive the label, proceed with registration. */
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
command = (reg) ? ZEBRA_FEC_REGISTER : ZEBRA_FEC_UNREGISTER;
zclient_create_header(s, command, VRF_DEFAULT);
@@ -288,7 +288,7 @@ static void bgp_send_fec_register_label_msg(struct bgp_dest *dest, bool reg,
if (reg)
stream_putw_at(s, flags_pos, flags);
- zclient_send_message(zclient);
+ zclient_send_message(bgp_zclient);
}
/**
diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c
index 86d6281ed1..d88e746143 100644
--- a/bgpd/bgp_mac.c
+++ b/bgpd/bgp_mac.c
@@ -219,6 +219,9 @@ static void bgp_mac_rescan_evpn_table(struct bgp *bgp, struct ethaddr *macaddr)
if (!peer_established(peer->connection))
continue;
+ if (!peer->afc[afi][safi])
+ continue;
+
if (bgp_debug_update(peer, NULL, NULL, 1))
zlog_debug(
"Processing EVPN MAC interface change on peer %s %s",
diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c
index 9dbef791b0..1dbac2b864 100644
--- a/bgpd/bgp_main.c
+++ b/bgpd/bgp_main.c
@@ -161,6 +161,14 @@ __attribute__((__noreturn__)) void sigint(void)
bgp_exit(0);
+ /*
+ * This is being done after bgp_exit because items may be removed
+ * from the connection_fifo
+ */
+ peer_connection_fifo_fini(&bm->connection_fifo);
+ EVENT_OFF(bm->e_process_packet);
+ pthread_mutex_destroy(&bm->peer_connection_mtx);
+
exit(0);
}
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index d1d4c5af68..782d29a7f5 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -46,7 +46,7 @@ DEFINE_MTYPE_STATIC(BGPD, MPLSVPN_NH_LABEL_BIND_CACHE,
/*
* Definitions and external declarations.
*/
-extern struct zclient *zclient;
+extern struct zclient *bgp_zclient;
extern int argv_find_and_parse_vpnvx(struct cmd_token **argv, int argc,
int *index, afi_t *afi)
@@ -317,7 +317,7 @@ void vpn_leak_zebra_vrf_label_update(struct bgp *bgp, afi_t afi)
if (label == BGP_PREVENT_VRF_2_VRF_LEAK)
label = MPLS_LABEL_NONE;
- zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
+ zclient_send_vrf_label(bgp_zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
}
@@ -344,7 +344,7 @@ void vpn_leak_zebra_vrf_label_withdraw(struct bgp *bgp, afi_t afi)
bgp->name_pretty, bgp->vrf_id);
}
- zclient_send_vrf_label(zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
+ zclient_send_vrf_label(bgp_zclient, bgp->vrf_id, afi, label, ZEBRA_LSP_BGP);
bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent = label;
}
@@ -397,11 +397,13 @@ void vpn_leak_zebra_vrf_sid_update_per_af(struct bgp *bgp, afi_t afi)
ctx.argument_len =
bgp->vpn_policy[afi]
.tovpn_sid_locator->argument_bits_length;
+ if (CHECK_FLAG(bgp->vpn_policy[afi].tovpn_sid_locator->flags, SRV6_LOCATOR_USID))
+ SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID);
}
ctx.table = vrf->data.l.table_id;
act = afi == AFI_IP ? ZEBRA_SEG6_LOCAL_ACTION_END_DT4
: ZEBRA_SEG6_LOCAL_ACTION_END_DT6;
- zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
+ zclient_send_localsid(bgp_zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
*tovpn_sid_ls = *tovpn_sid;
@@ -454,10 +456,12 @@ void vpn_leak_zebra_vrf_sid_update_per_vrf(struct bgp *bgp)
ctx.node_len = bgp->tovpn_sid_locator->node_bits_length;
ctx.function_len = bgp->tovpn_sid_locator->function_bits_length;
ctx.argument_len = bgp->tovpn_sid_locator->argument_bits_length;
+ if (CHECK_FLAG(bgp->tovpn_sid_locator->flags, SRV6_LOCATOR_USID))
+ SET_SRV6_FLV_OP(ctx.flv.flv_ops, ZEBRA_SEG6_LOCAL_FLV_OP_NEXT_CSID);
}
ctx.table = vrf->data.l.table_id;
act = ZEBRA_SEG6_LOCAL_ACTION_END_DT46;
- zclient_send_localsid(zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
+ zclient_send_localsid(bgp_zclient, tovpn_sid, bgp->vrf_id, act, &ctx);
tovpn_sid_ls = XCALLOC(MTYPE_BGP_SRV6_SID, sizeof(struct in6_addr));
*tovpn_sid_ls = *tovpn_sid;
@@ -519,7 +523,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_af(struct bgp *bgp, afi_t afi)
bgp->vpn_policy[afi]
.tovpn_sid_locator->argument_bits_length;
}
- zclient_send_localsid(zclient,
+ zclient_send_localsid(bgp_zclient,
bgp->vpn_policy[afi].tovpn_zebra_vrf_sid_last_sent,
bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC,
&seg6localctx);
@@ -564,7 +568,7 @@ void vpn_leak_zebra_vrf_sid_withdraw_per_vrf(struct bgp *bgp)
seg6localctx.argument_len =
bgp->tovpn_sid_locator->argument_bits_length;
}
- zclient_send_localsid(zclient, bgp->tovpn_zebra_vrf_sid_last_sent,
+ zclient_send_localsid(bgp_zclient, bgp->tovpn_zebra_vrf_sid_last_sent,
bgp->vrf_id, ZEBRA_SEG6_LOCAL_ACTION_UNSPEC,
&seg6localctx);
XFREE(MTYPE_BGP_SRV6_SID, bgp->tovpn_zebra_vrf_sid_last_sent);
@@ -1088,10 +1092,8 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
/* the route is defined with the "network <prefix>" command */
if (CHECK_FLAG(bgp_nexthop->flags, BGP_FLAG_IMPORT_CHECK))
- nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop,
- afi, SAFI_UNICAST,
- bpi_ultimate, NULL,
- 0, p);
+ nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi, SAFI_UNICAST,
+ bpi_ultimate, NULL, 0, p, bpi_ultimate);
else
/* if "no bgp network import-check" is set,
* then mark the nexthop as valid.
@@ -1105,18 +1107,22 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,
* TBD do we need to do anything about the
* 'connected' parameter?
*/
- nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi,
- safi, bpi, NULL, 0, p);
+ /* VPN paths: the new bpi may be altered like
+ * with 'nexthop vpn export' command. Use the bpi_ultimate
+ * to find the original nexthop
+ */
+ nh_valid = bgp_find_or_add_nexthop(to_bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p,
+ bpi_ultimate);
/*
* If you are using SRv6 VPN instead of MPLS, it need to check
* the SID allocation. If the sid is not allocated, the rib
* will be invalid.
+ * If the SID per VRF is not available, also consider the rib as
+ * invalid.
*/
- if (to_bgp->srv6_enabled &&
- (!new_attr->srv6_l3vpn && !new_attr->srv6_vpn)) {
- nh_valid = false;
- }
+ if (to_bgp->srv6_enabled && nh_valid)
+ nh_valid = is_pi_srv6_valid(bpi, bgp_nexthop, afi, safi);
if (debug)
zlog_debug("%s: %pFX nexthop is %svalid (in %s)", __func__, p,
@@ -1207,8 +1213,8 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,
return NULL;
}
- if (attrhash_cmp(bpi->attr, new_attr) && labelssame &&
- !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) &&
+ if (labelssame && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) &&
+ attrhash_cmp(bpi->attr, new_attr) &&
leak_update_nexthop_valid(to_bgp, bn, new_attr, afi, safi, source_bpi, bpi,
bgp_orig, p,
debug) == !!CHECK_FLAG(bpi->flags, BGP_PATH_VALID)) {
@@ -1594,8 +1600,8 @@ vpn_leak_from_vrf_get_per_nexthop_label(afi_t afi, struct bgp_path_info *pi,
bgp_nexthop = from_bgp;
nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
- nh_valid = bgp_find_or_add_nexthop(from_bgp, bgp_nexthop, nh_afi,
- SAFI_UNICAST, pi, NULL, 0, NULL);
+ nh_valid = bgp_find_or_add_nexthop(from_bgp, bgp_nexthop, nh_afi, SAFI_UNICAST, pi, NULL, 0,
+ NULL, NULL);
if (!nh_valid && is_bgp_static_route &&
!CHECK_FLAG(from_bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
@@ -2337,8 +2343,8 @@ static void vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp, /* to */
break;
}
- if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi,
- path_vpn, bpi, src_vrf, p, debug))
+ if (bpi && leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, path_vpn, bpi,
+ src_vrf, p, debug))
SET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);
else
UNSET_FLAG(static_attr.nh_flags, BGP_ATTR_NH_VALID);
diff --git a/bgpd/bgp_mplsvpn.h b/bgpd/bgp_mplsvpn.h
index 56dd33f9b1..75c0264987 100644
--- a/bgpd/bgp_mplsvpn.h
+++ b/bgpd/bgp_mplsvpn.h
@@ -342,6 +342,37 @@ static inline bool is_pi_family_vpn(struct bgp_path_info *pi)
is_pi_family_matching(pi, AFI_IP6, SAFI_MPLS_VPN));
}
+/*
+ * If you are using SRv6 VPN instead of MPLS, it need to check
+ * the SID allocation. If the sid is not allocated, the rib
+ * will be invalid.
+ * If the SID per VRF is not available, also consider the rib as
+ * invalid.
+ */
+static inline bool is_pi_srv6_valid(struct bgp_path_info *pi, struct bgp *bgp_nexthop, afi_t afi,
+ safi_t safi)
+{
+ if (!pi->attr->srv6_l3vpn && !pi->attr->srv6_vpn)
+ return false;
+
+ /* imported paths from VPN: srv6 enabled and nht reachability
+ * are enough to know if that path is valid
+ */
+ if (safi == SAFI_UNICAST)
+ return true;
+
+ if (bgp_nexthop->vpn_policy[afi].tovpn_sid == NULL && bgp_nexthop->tovpn_sid == NULL)
+ return false;
+
+ if (bgp_nexthop->tovpn_sid_index == 0 &&
+ !CHECK_FLAG(bgp_nexthop->vrf_flags, BGP_VRF_TOVPN_SID_AUTO) &&
+ bgp_nexthop->vpn_policy[afi].tovpn_sid_index == 0 &&
+ !CHECK_FLAG(bgp_nexthop->vpn_policy[afi].flags, BGP_VPN_POLICY_TOVPN_SID_AUTO))
+ return false;
+
+ return true;
+}
+
extern void vpn_policy_routemap_event(const char *rmap_name);
extern vrf_id_t get_first_vrf_for_redirect_with_rt(struct ecommunity *eckey);
diff --git a/bgpd/bgp_mplsvpn_snmp.c b/bgpd/bgp_mplsvpn_snmp.c
index 93d9f67245..4a696fdcbf 100644
--- a/bgpd/bgp_mplsvpn_snmp.c
+++ b/bgpd/bgp_mplsvpn_snmp.c
@@ -1460,8 +1460,6 @@ static struct bgp_path_info *bgpL3vpnRte_lookup(struct variable *v, oid name[],
pi = bgp_lookup_route_next(l3vpn_bgp, dest, &prefix, policy,
&nexthop);
if (pi) {
- uint8_t vrf_name_len =
- strnlen((*l3vpn_bgp)->name, VRF_NAMSIZ);
const struct prefix *p = bgp_dest_get_prefix(*dest);
uint8_t oid_index;
bool v4 = (p->family == AF_INET);
@@ -1469,6 +1467,8 @@ static struct bgp_path_info *bgpL3vpnRte_lookup(struct variable *v, oid name[],
: sizeof(struct in6_addr);
struct attr *attr = pi->attr;
+ vrf_name_len = strnlen((*l3vpn_bgp)->name, VRF_NAMSIZ);
+
/* copy the index parameters */
oid_copy_str(&name[namelen], (*l3vpn_bgp)->name,
vrf_name_len);
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c
index bd27562134..330af64379 100644
--- a/bgpd/bgp_nht.c
+++ b/bgpd/bgp_nht.c
@@ -34,11 +34,12 @@
#include "bgpd/bgp_mplsvpn.h"
#include "bgpd/bgp_ecommunity.h"
-extern struct zclient *zclient;
+extern struct zclient *bgp_zclient;
static void register_zebra_rnh(struct bgp_nexthop_cache *bnc);
static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc);
-static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p);
+static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p,
+ struct bgp *bgp_nexthop, struct bgp_path_info *pi_source);
static void bgp_nht_ifp_initial(struct event *thread);
DEFINE_HOOK(bgp_nht_path_update, (struct bgp *bgp, struct bgp_path_info *pi, bool valid),
@@ -297,10 +298,9 @@ void bgp_unlink_nexthop_by_peer(struct peer *peer)
* A route and its nexthop might belong to different VRFs. Therefore,
* we need both the bgp_route and bgp_nexthop pointers.
*/
-int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
- afi_t afi, safi_t safi, struct bgp_path_info *pi,
- struct peer *peer, int connected,
- const struct prefix *orig_prefix)
+int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, afi_t afi, safi_t safi,
+ struct bgp_path_info *pi, struct peer *peer, int connected,
+ const struct prefix *orig_prefix, struct bgp_path_info *source_pi)
{
struct bgp_nexthop_cache_head *tree = NULL;
struct bgp_nexthop_cache *bnc;
@@ -330,7 +330,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
/* This will return true if the global IPv6 NH is a link local
* addr */
- if (!make_prefix(afi, pi, &p))
+ if (!make_prefix(afi, pi, &p, bgp_nexthop, source_pi))
return 1;
/*
@@ -667,7 +667,7 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,
nexthop->vrf_id);
if (ifp)
zclient_send_interface_radv_req(
- zclient, nexthop->vrf_id, ifp,
+ bgp_zclient, nexthop->vrf_id, ifp,
true,
BGP_UNNUM_DEFAULT_RA_INTERVAL);
}
@@ -994,7 +994,8 @@ void bgp_cleanup_nexthops(struct bgp *bgp)
* make_prefix - make a prefix structure from the path (essentially
* path's node.
*/
-static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
+static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p,
+ struct bgp *bgp_nexthop, struct bgp_path_info *source_pi)
{
int is_bgp_static = ((pi->type == ZEBRA_ROUTE_BGP)
@@ -1004,8 +1005,19 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
struct bgp_dest *net = pi->net;
const struct prefix *p_orig = bgp_dest_get_prefix(net);
struct in_addr ipv4;
- struct peer *peer = pi->peer;
- struct attr *attr = pi->attr;
+ struct peer *peer;
+ struct attr *attr;
+ bool local_sid = false;
+ struct bgp *bgp = bgp_get_default();
+ struct prefix_ipv6 tmp_prefix;
+
+ if (source_pi) {
+ attr = source_pi->attr;
+ peer = source_pi->peer;
+ } else {
+ peer = pi->peer;
+ attr = pi->attr;
+ }
if (p_orig->family == AF_FLOWSPEC) {
if (!peer)
@@ -1035,37 +1047,50 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
break;
case AFI_IP6:
p->family = AF_INET6;
- if (attr->srv6_l3vpn) {
+ if (bgp && bgp->srv6_locator && bgp->srv6_enabled && pi->attr->srv6_l3vpn) {
+ tmp_prefix.family = AF_INET6;
+ tmp_prefix.prefixlen = IPV6_MAX_BITLEN;
+ tmp_prefix.prefix = pi->attr->srv6_l3vpn->sid;
+ if (bgp_nexthop->vpn_policy[afi].tovpn_sid_locator &&
+ bgp_nexthop->vpn_policy[afi].tovpn_sid)
+ local_sid = prefix_match(&bgp_nexthop->vpn_policy[afi]
+ .tovpn_sid_locator->prefix,
+ &tmp_prefix);
+ else if (bgp_nexthop->tovpn_sid_locator && bgp_nexthop->tovpn_sid)
+ local_sid = prefix_match(&bgp_nexthop->tovpn_sid_locator->prefix,
+ &tmp_prefix);
+ }
+ if (local_sid == false && pi->attr->srv6_l3vpn) {
p->prefixlen = IPV6_MAX_BITLEN;
- if (attr->srv6_l3vpn->transposition_len != 0 &&
+ if (pi->attr->srv6_l3vpn->transposition_len != 0 &&
BGP_PATH_INFO_NUM_LABELS(pi)) {
- IPV6_ADDR_COPY(&p->u.prefix6, &attr->srv6_l3vpn->sid);
+ IPV6_ADDR_COPY(&p->u.prefix6, &pi->attr->srv6_l3vpn->sid);
transpose_sid(&p->u.prefix6,
decode_label(&pi->extra->labels->label[0]),
- attr->srv6_l3vpn->transposition_offset,
- attr->srv6_l3vpn->transposition_len);
+ pi->attr->srv6_l3vpn->transposition_offset,
+ pi->attr->srv6_l3vpn->transposition_len);
} else
- IPV6_ADDR_COPY(&(p->u.prefix6), &(attr->srv6_l3vpn->sid));
+ IPV6_ADDR_COPY(&(p->u.prefix6), &(pi->attr->srv6_l3vpn->sid));
} else if (is_bgp_static) {
p->u.prefix6 = p_orig->u.prefix6;
p->prefixlen = p_orig->prefixlen;
- } else {
+ } else if (attr) {
/* If we receive MP_REACH nexthop with ::(LL)
* or LL(LL), use LL address as nexthop cache.
*/
- if (attr && attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
+ if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
(IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global) ||
IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)))
p->u.prefix6 = attr->mp_nexthop_local;
/* If we receive MR_REACH with (GA)::(LL)
* then check for route-map to choose GA or LL
*/
- else if (attr && attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
+ else if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
if (CHECK_FLAG(attr->nh_flags, BGP_ATTR_NH_MP_PREFER_GLOBAL))
p->u.prefix6 = attr->mp_nexthop_global;
else
p->u.prefix6 = attr->mp_nexthop_local;
- } else if (attr && attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL &&
+ } else if (attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL &&
IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
/* If we receive MP_REACH with GUA as LL, we should
* check if we have Link-Local Next Hop capability also.
@@ -1106,11 +1131,11 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
*/
static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
{
- bool exact_match = false;
+ bool match_p = false;
bool resolve_via_default = false;
int ret;
- if (!zclient)
+ if (!bgp_zclient)
return;
/* Don't try to register if Zebra doesn't know of this instance. */
@@ -1130,7 +1155,7 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
}
if (command == ZEBRA_NEXTHOP_REGISTER) {
if (CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED))
- exact_match = true;
+ match_p = true;
if (CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE_EXACT_MATCH))
resolve_via_default = true;
}
@@ -1140,8 +1165,8 @@ static void sendmsg_zebra_rnh(struct bgp_nexthop_cache *bnc, int command)
zserv_command_string(command), &bnc->prefix,
bnc->bgp->name_pretty);
- ret = zclient_send_rnh(zclient, command, &bnc->prefix, SAFI_UNICAST,
- exact_match, resolve_via_default,
+ ret = zclient_send_rnh(bgp_zclient, command, &bnc->prefix, SAFI_UNICAST,
+ match_p, resolve_via_default,
bnc->bgp->vrf_id);
if (ret == ZCLIENT_SEND_FAILURE) {
flog_warn(EC_BGP_ZEBRA_SEND,
@@ -1568,7 +1593,7 @@ void bgp_nht_reg_enhe_cap_intfs(struct peer *peer)
if (!ifp)
continue;
- zclient_send_interface_radv_req(zclient,
+ zclient_send_interface_radv_req(bgp_zclient,
nhop->vrf_id,
ifp, true,
BGP_UNNUM_DEFAULT_RA_INTERVAL);
@@ -1618,7 +1643,7 @@ void bgp_nht_dereg_enhe_cap_intfs(struct peer *peer)
if (!ifp)
continue;
- zclient_send_interface_radv_req(zclient, nhop->vrf_id, ifp, 0,
+ zclient_send_interface_radv_req(bgp_zclient, nhop->vrf_id, ifp, 0,
0);
}
}
diff --git a/bgpd/bgp_nht.h b/bgpd/bgp_nht.h
index 345089ac5a..76536d6ebf 100644
--- a/bgpd/bgp_nht.h
+++ b/bgpd/bgp_nht.h
@@ -25,11 +25,10 @@ extern void bgp_nexthop_update(struct vrf *vrf, struct prefix *match,
* peer - The BGP peer associated with this NHT
* connected - True if NH MUST be a connected route
*/
-extern int bgp_find_or_add_nexthop(struct bgp *bgp_route,
- struct bgp *bgp_nexthop, afi_t a,
- safi_t safi, struct bgp_path_info *p,
- struct peer *peer, int connected,
- const struct prefix *orig_prefix);
+extern int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop, afi_t a,
+ safi_t safi, struct bgp_path_info *p, struct peer *peer,
+ int connected, const struct prefix *orig_prefix,
+ struct bgp_path_info *source_pi);
/**
* bgp_unlink_nexthop() - Unlink the nexthop object from the path structure.
diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c
index 4c2eb03f3a..16e94d9fe2 100644
--- a/bgpd/bgp_packet.c
+++ b/bgpd/bgp_packet.c
@@ -3148,8 +3148,6 @@ static void bgp_dynamic_capability_paths_limit(uint8_t *pnt, int action,
SET_FLAG(peer->cap, PEER_CAP_PATHS_LIMIT_RCV);
while (data + CAPABILITY_CODE_PATHS_LIMIT_LEN <= end) {
- afi_t afi;
- safi_t safi;
iana_afi_t pkt_afi;
iana_safi_t pkt_safi;
uint16_t paths_limit = 0;
@@ -3508,8 +3506,6 @@ static void bgp_dynamic_capability_llgr(uint8_t *pnt, int action,
SET_FLAG(peer->cap, PEER_CAP_LLGR_RCV);
while (data + BGP_CAP_LLGR_MIN_PACKET_LEN <= end) {
- afi_t afi;
- safi_t safi;
iana_afi_t pkt_afi;
iana_safi_t pkt_safi;
struct graceful_restart_af graf;
@@ -3616,8 +3612,6 @@ static void bgp_dynamic_capability_graceful_restart(uint8_t *pnt, int action,
while (data + GRACEFUL_RESTART_CAPABILITY_PER_AFI_SAFI_SIZE <=
end) {
- afi_t afi;
- safi_t safi;
iana_afi_t pkt_afi;
iana_safi_t pkt_safi;
struct graceful_restart_af graf;
@@ -3974,6 +3968,18 @@ int bgp_capability_receive(struct peer_connection *connection,
* would not, making event flow difficult to understand. Please think twice
* before hacking this.
*
+ * packet_processing is now a FIFO of connections that need to be handled
+ * This loop has a maximum run of 100(BGP_PACKET_PROCESS_LIMIT) packets,
+ * but each individual connection can only handle the quanta value as
+ * specified in bgp_vty.c. If the connection still has work to do, place it
+ * back on the back of the queue for more work. Do note that event_should_yield
+ * is also being called to figure out if processing should stop and work
+ * picked up after other items can run. This was added *After* withdrawals
+ * started being processed at scale and this function was taking cpu for 40+ seconds
+ * On my machine we are getting 2-3 packets before a yield should happen in the
+ * update case. Withdrawal is 1 packet being processed(note this is a very very
+ * fast computer) before other items should be run.
+ *
* Thread type: EVENT_EVENT
* @param thread
* @return 0
@@ -3986,30 +3992,53 @@ void bgp_process_packet(struct event *thread)
uint32_t rpkt_quanta_old; // how many packets to read
int fsm_update_result; // return code of bgp_event_update()
int mprc; // message processing return code
+ uint32_t processed = 0, curr_connection_processed = 0;
+ bool more_work = false;
+ size_t count;
+ uint32_t total_packets_to_process;
+
+ frr_with_mutex (&bm->peer_connection_mtx)
+ connection = peer_connection_fifo_pop(&bm->connection_fifo);
+
+ if (!connection)
+ goto done;
- connection = EVENT_ARG(thread);
+ total_packets_to_process = BGP_PACKET_PROCESS_LIMIT;
peer = connection->peer;
rpkt_quanta_old = atomic_load_explicit(&peer->bgp->rpkt_quanta,
memory_order_relaxed);
+
fsm_update_result = 0;
- /* Guard against scheduled events that occur after peer deletion. */
- if (connection->status == Deleted || connection->status == Clearing)
- return;
+ while ((processed < total_packets_to_process) && connection) {
+ /* Guard against scheduled events that occur after peer deletion. */
+ if (connection->status == Deleted || connection->status == Clearing) {
+ frr_with_mutex (&bm->peer_connection_mtx)
+ connection = peer_connection_fifo_pop(&bm->connection_fifo);
+
+ if (connection)
+ peer = connection->peer;
- unsigned int processed = 0;
+ continue;
+ }
- while (processed < rpkt_quanta_old) {
uint8_t type = 0;
bgp_size_t size;
char notify_data_length[2];
- frr_with_mutex (&connection->io_mtx) {
+ frr_with_mutex (&connection->io_mtx)
peer->curr = stream_fifo_pop(connection->ibuf);
- }
- if (peer->curr == NULL) // no packets to process, hmm...
- return;
+ if (peer->curr == NULL) {
+ frr_with_mutex (&bm->peer_connection_mtx)
+ connection = peer_connection_fifo_pop(&bm->connection_fifo);
+
+
+ if (connection)
+ peer = connection->peer;
+
+ continue;
+ }
/* skip the marker and copy the packet length */
stream_forward_getp(peer->curr, BGP_MARKER_SIZE);
@@ -4113,32 +4142,81 @@ void bgp_process_packet(struct event *thread)
stream_free(peer->curr);
peer->curr = NULL;
processed++;
+ curr_connection_processed++;
/* Update FSM */
if (mprc != BGP_PACKET_NOOP)
fsm_update_result = bgp_event_update(connection, mprc);
- else
- continue;
/*
* If peer was deleted, do not process any more packets. This
* is usually due to executing BGP_Stop or a stub deletion.
*/
- if (fsm_update_result == FSM_PEER_TRANSFERRED
- || fsm_update_result == FSM_PEER_STOPPED)
- break;
+ if (fsm_update_result == FSM_PEER_TRANSFERRED ||
+ fsm_update_result == FSM_PEER_STOPPED) {
+ frr_with_mutex (&bm->peer_connection_mtx)
+ connection = peer_connection_fifo_pop(&bm->connection_fifo);
+
+ if (connection)
+ peer = connection->peer;
+
+ continue;
+ }
+
+ bool yield = event_should_yield(thread);
+ if (curr_connection_processed >= rpkt_quanta_old || yield) {
+ curr_connection_processed = 0;
+ frr_with_mutex (&bm->peer_connection_mtx) {
+ if (!peer_connection_fifo_member(&bm->connection_fifo, connection))
+ peer_connection_fifo_add_tail(&bm->connection_fifo,
+ connection);
+ if (!yield)
+ connection = peer_connection_fifo_pop(&bm->connection_fifo);
+ else
+ connection = NULL;
+ }
+ if (connection)
+ peer = connection->peer;
+
+ continue;
+ }
+
+ frr_with_mutex (&connection->io_mtx) {
+ if (connection->ibuf->count > 0)
+ more_work = true;
+ else
+ more_work = false;
+ }
+
+ if (!more_work) {
+ frr_with_mutex (&bm->peer_connection_mtx)
+ connection = peer_connection_fifo_pop(&bm->connection_fifo);
+
+ if (connection)
+ peer = connection->peer;
+ }
}
- if (fsm_update_result != FSM_PEER_TRANSFERRED
- && fsm_update_result != FSM_PEER_STOPPED) {
+ if (connection) {
frr_with_mutex (&connection->io_mtx) {
- // more work to do, come back later
if (connection->ibuf->count > 0)
- event_add_event(bm->master, bgp_process_packet,
- connection, 0,
- &connection->t_process_packet);
+ more_work = true;
+ else
+ more_work = false;
+ }
+ frr_with_mutex (&bm->peer_connection_mtx) {
+ if (more_work &&
+ !peer_connection_fifo_member(&bm->connection_fifo, connection))
+ peer_connection_fifo_add_tail(&bm->connection_fifo, connection);
}
}
+
+done:
+ frr_with_mutex (&bm->peer_connection_mtx)
+ count = peer_connection_fifo_count(&bm->connection_fifo);
+
+ if (count)
+ event_add_event(bm->master, bgp_process_packet, NULL, 0, &bm->e_process_packet);
}
/* Send EOR when routes are processed by selection deferral timer */
diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c
index b85a8e2254..2b13715da3 100644
--- a/bgpd/bgp_pbr.c
+++ b/bgpd/bgp_pbr.c
@@ -279,6 +279,13 @@ static void bgp_pbr_policyroute_add_to_zebra_unit(struct bgp *bgp,
static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add);
+static void bgp_pbr_val_mask_free(void *arg)
+{
+ struct bgp_pbr_val_mask *pbr_val_mask = arg;
+
+ XFREE(MTYPE_PBR_VALMASK, pbr_val_mask);
+}
+
static bool bgp_pbr_extract_enumerate_unary_opposite(
uint8_t unary_operator,
struct bgp_pbr_val_mask *and_valmask,
@@ -442,7 +449,7 @@ static bool bgp_pbr_extract(struct bgp_pbr_match_val list[],
struct bgp_pbr_range_port *range)
{
int i = 0;
- bool exact_match = false;
+ bool match_p = false;
if (range)
memset(range, 0, sizeof(struct bgp_pbr_range_port));
@@ -457,9 +464,9 @@ static bool bgp_pbr_extract(struct bgp_pbr_match_val list[],
OPERATOR_COMPARE_EQUAL_TO)) {
if (range)
range->min_port = list[i].value;
- exact_match = true;
+ match_p = true;
}
- if (exact_match && i > 0)
+ if (match_p && i > 0)
return false;
if (list[i].compare_operator ==
(OPERATOR_COMPARE_GREATER_THAN +
@@ -965,7 +972,12 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p,
return 0;
}
-static void bgp_pbr_match_entry_free(void *arg)
+static void bgp_pbr_match_entry_free(struct bgp_pbr_match_entry *bpme)
+{
+ XFREE(MTYPE_PBR_MATCH_ENTRY, bpme);
+}
+
+static void bgp_pbr_match_entry_hash_free(void *arg)
{
struct bgp_pbr_match_entry *bpme;
@@ -976,16 +988,21 @@ static void bgp_pbr_match_entry_free(void *arg)
bpme->installed = false;
bpme->backpointer = NULL;
}
- XFREE(MTYPE_PBR_MATCH_ENTRY, bpme);
+ bgp_pbr_match_entry_free(bpme);
+}
+
+static void bgp_pbr_match_free(struct bgp_pbr_match *bpm)
+{
+ XFREE(MTYPE_PBR_MATCH, bpm);
}
-static void bgp_pbr_match_free(void *arg)
+static void bgp_pbr_match_hash_free(void *arg)
{
struct bgp_pbr_match *bpm;
bpm = (struct bgp_pbr_match *)arg;
- hash_clean(bpm->entry_hash, bgp_pbr_match_entry_free);
+ hash_clean(bpm->entry_hash, bgp_pbr_match_entry_hash_free);
if (hashcount(bpm->entry_hash) == 0) {
/* delete iptable entry first */
@@ -1004,7 +1021,7 @@ static void bgp_pbr_match_free(void *arg)
}
hash_clean_and_free(&bpm->entry_hash, NULL);
- XFREE(MTYPE_PBR_MATCH, bpm);
+ bgp_pbr_match_free(bpm);
}
static void *bgp_pbr_match_alloc_intern(void *arg)
@@ -1019,7 +1036,12 @@ static void *bgp_pbr_match_alloc_intern(void *arg)
return new;
}
-static void bgp_pbr_rule_free(void *arg)
+static void bgp_pbr_rule_free(struct bgp_pbr_rule *pbr)
+{
+ XFREE(MTYPE_PBR_RULE, pbr);
+}
+
+static void bgp_pbr_rule_hash_free(void *arg)
{
struct bgp_pbr_rule *bpr;
@@ -1032,7 +1054,7 @@ static void bgp_pbr_rule_free(void *arg)
bpr->action->refcnt--;
bpr->action = NULL;
}
- XFREE(MTYPE_PBR_RULE, bpr);
+ bgp_pbr_rule_free(bpr);
}
static void *bgp_pbr_rule_alloc_intern(void *arg)
@@ -1372,8 +1394,8 @@ struct bgp_pbr_match *bgp_pbr_match_iptable_lookup(vrf_id_t vrf_id,
void bgp_pbr_cleanup(struct bgp *bgp)
{
- hash_clean_and_free(&bgp->pbr_match_hash, bgp_pbr_match_free);
- hash_clean_and_free(&bgp->pbr_rule_hash, bgp_pbr_rule_free);
+ hash_clean_and_free(&bgp->pbr_match_hash, bgp_pbr_match_hash_free);
+ hash_clean_and_free(&bgp->pbr_rule_hash, bgp_pbr_rule_hash_free);
hash_clean_and_free(&bgp->pbr_action_hash, bgp_pbr_action_free);
if (bgp->bgp_pbr_cfg == NULL)
@@ -1656,6 +1678,8 @@ static void bgp_pbr_flush_iprule(struct bgp *bgp, struct bgp_pbr_action *bpa,
}
}
hash_release(bgp->pbr_rule_hash, bpr);
+ bgp_pbr_rule_free(bpr);
+
bgp_pbr_bpa_remove(bpa);
}
@@ -1685,6 +1709,7 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
}
}
hash_release(bpm->entry_hash, bpme);
+ bgp_pbr_match_entry_free(bpme);
if (hashcount(bpm->entry_hash) == 0) {
/* delete iptable entry first */
/* then delete ipset match */
@@ -1700,6 +1725,7 @@ static void bgp_pbr_flush_entry(struct bgp *bgp, struct bgp_pbr_action *bpa,
bpm->action = NULL;
}
hash_release(bgp->pbr_match_hash, bpm);
+ bgp_pbr_match_free(bpm);
/* XXX release pbr_match_action if not used
* note that drop does not need to call send_pbr_action
*/
@@ -2111,17 +2137,6 @@ static void bgp_pbr_policyroute_remove_from_zebra(
bgp, path, bpf, bpof, FLOWSPEC_ICMP_TYPE);
else
bgp_pbr_policyroute_remove_from_zebra_unit(bgp, path, bpf);
- /* flush bpof */
- if (bpof->tcpflags)
- list_delete_all_node(bpof->tcpflags);
- if (bpof->dscp)
- list_delete_all_node(bpof->dscp);
- if (bpof->flowlabel)
- list_delete_all_node(bpof->flowlabel);
- if (bpof->pkt_len)
- list_delete_all_node(bpof->pkt_len);
- if (bpof->fragment)
- list_delete_all_node(bpof->fragment);
}
static void bgp_pbr_dump_entry(struct bgp_pbr_filter *bpf, bool add)
@@ -2606,19 +2621,6 @@ static void bgp_pbr_policyroute_add_to_zebra(struct bgp *bgp,
bgp, path, bpf, bpof, nh, rate, FLOWSPEC_ICMP_TYPE);
else
bgp_pbr_policyroute_add_to_zebra_unit(bgp, path, bpf, nh, rate);
- /* flush bpof */
- if (bpof->tcpflags)
- list_delete_all_node(bpof->tcpflags);
- if (bpof->dscp)
- list_delete_all_node(bpof->dscp);
- if (bpof->pkt_len)
- list_delete_all_node(bpof->pkt_len);
- if (bpof->fragment)
- list_delete_all_node(bpof->fragment);
- if (bpof->icmp_type)
- list_delete_all_node(bpof->icmp_type);
- if (bpof->icmp_code)
- list_delete_all_node(bpof->icmp_code);
}
static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
@@ -2684,6 +2686,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
srcp = &range;
else {
bpof.icmp_type = list_new();
+ bpof.icmp_type->del = bgp_pbr_val_mask_free;
bgp_pbr_extract_enumerate(api->icmp_type,
api->match_icmp_type_num,
OPERATOR_UNARY_OR,
@@ -2699,6 +2702,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
dstp = &range_icmp_code;
else {
bpof.icmp_code = list_new();
+ bpof.icmp_code->del = bgp_pbr_val_mask_free;
bgp_pbr_extract_enumerate(api->icmp_code,
api->match_icmp_code_num,
OPERATOR_UNARY_OR,
@@ -2719,6 +2723,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
FLOWSPEC_TCP_FLAGS);
} else if (kind_enum == OPERATOR_UNARY_OR) {
bpof.tcpflags = list_new();
+ bpof.tcpflags->del = bgp_pbr_val_mask_free;
bgp_pbr_extract_enumerate(api->tcpflags,
api->match_tcpflags_num,
OPERATOR_UNARY_OR,
@@ -2736,6 +2741,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
bpf.pkt_len = &pkt_len;
else {
bpof.pkt_len = list_new();
+ bpof.pkt_len->del = bgp_pbr_val_mask_free;
bgp_pbr_extract_enumerate(api->packet_length,
api->match_packet_length_num,
OPERATOR_UNARY_OR,
@@ -2745,12 +2751,14 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
}
if (api->match_dscp_num >= 1) {
bpof.dscp = list_new();
+ bpof.dscp->del = bgp_pbr_val_mask_free;
bgp_pbr_extract_enumerate(api->dscp, api->match_dscp_num,
OPERATOR_UNARY_OR,
bpof.dscp, FLOWSPEC_DSCP);
}
if (api->match_fragment_num) {
bpof.fragment = list_new();
+ bpof.fragment->del = bgp_pbr_val_mask_free;
bgp_pbr_extract_enumerate(api->fragment,
api->match_fragment_num,
OPERATOR_UNARY_OR,
@@ -2766,7 +2774,7 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
bpf.family = afi2family(api->afi);
if (!add) {
bgp_pbr_policyroute_remove_from_zebra(bgp, path, &bpf, &bpof);
- return;
+ goto flush_bpof;
}
/* no action for add = true */
for (i = 0; i < api->action_num; i++) {
@@ -2844,6 +2852,22 @@ static void bgp_pbr_handle_entry(struct bgp *bgp, struct bgp_path_info *path,
if (continue_loop == 0)
break;
}
+
+flush_bpof:
+ if (bpof.tcpflags)
+ list_delete(&bpof.tcpflags);
+ if (bpof.dscp)
+ list_delete(&bpof.dscp);
+ if (bpof.flowlabel)
+ list_delete(&bpof.flowlabel);
+ if (bpof.pkt_len)
+ list_delete(&bpof.pkt_len);
+ if (bpof.fragment)
+ list_delete(&bpof.fragment);
+ if (bpof.icmp_type)
+ list_delete(&bpof.icmp_type);
+ if (bpof.icmp_code)
+ list_delete(&bpof.icmp_code);
}
void bgp_pbr_update_entry(struct bgp *bgp, const struct prefix *p,
diff --git a/bgpd/bgp_pbr.h b/bgpd/bgp_pbr.h
index cb16c4dc2e..c8116506a7 100644
--- a/bgpd/bgp_pbr.h
+++ b/bgpd/bgp_pbr.h
@@ -151,8 +151,6 @@ struct bgp_pbr_config {
bool pbr_interface_any_ipv6;
};
-extern struct bgp_pbr_config *bgp_pbr_cfg;
-
struct bgp_pbr_rule {
uint32_t flags;
struct prefix src;
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index 003a9a4d4d..fd860c9236 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -4201,12 +4201,30 @@ static wq_item_status meta_queue_process(struct work_queue *dummy, void *data)
{
struct meta_queue *mq = data;
uint32_t i;
+ uint32_t peers_on_fifo;
+ static uint32_t total_runs = 0;
+
+ total_runs++;
+
+ frr_with_mutex (&bm->peer_connection_mtx)
+ peers_on_fifo = peer_connection_fifo_count(&bm->connection_fifo);
+
+ /*
+ * If the number of peers on the fifo is greater than 10
+ * let's yield this run of the MetaQ to allow the packet processing to make
+ * progress against the incoming packets. But we should also
+ * attempt to allow this to run occassionally. Let's run
+ * something every 10 attempts to process the work queue.
+ */
+ if (peers_on_fifo > 10 && total_runs % 10 != 0)
+ return WQ_QUEUE_BLOCKED;
for (i = 0; i < MQ_SIZE; i++)
if (process_subq(mq->subq[i], i)) {
mq->size--;
break;
}
+
return mq->size ? WQ_REQUEUE : WQ_SUCCESS;
}
@@ -4323,9 +4341,14 @@ static void early_meta_queue_free(struct meta_queue *mq, struct bgp_dest_queue *
struct bgp_dest *dest;
while (!STAILQ_EMPTY(l)) {
+ struct bgp_table *table;
+
dest = STAILQ_FIRST(l);
STAILQ_REMOVE_HEAD(l, pq);
STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
+
+ table = bgp_dest_table(dest);
+ bgp_table_unlock(table);
mq->size--;
}
}
@@ -4336,9 +4359,14 @@ static void other_meta_queue_free(struct meta_queue *mq, struct bgp_dest_queue *
struct bgp_dest *dest;
while (!STAILQ_EMPTY(l)) {
+ struct bgp_table *table;
+
dest = STAILQ_FIRST(l);
STAILQ_REMOVE_HEAD(l, pq);
STAILQ_NEXT(dest, pq) = NULL; /* complete unlink */
+
+ table = bgp_dest_table(dest);
+ bgp_table_unlock(table);
mq->size--;
}
}
@@ -4909,6 +4937,7 @@ bgp_update_nexthop_reachability_check(struct bgp *bgp, struct peer *peer, struct
{
bool connected;
afi_t nh_afi;
+ struct bgp_path_info *bpi_ultimate = NULL;
if (((afi == AFI_IP || afi == AFI_IP6) &&
(safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST ||
@@ -4924,13 +4953,16 @@ bgp_update_nexthop_reachability_check(struct bgp *bgp, struct peer *peer, struct
struct bgp *bgp_nexthop = bgp;
- if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig)
+ if (pi->extra && pi->extra->vrfleak && pi->extra->vrfleak->bgp_orig) {
bgp_nexthop = pi->extra->vrfleak->bgp_orig;
+ if (pi->sub_type == BGP_ROUTE_IMPORTED)
+ bpi_ultimate = bgp_get_imported_bpi_ultimate(pi);
+ }
nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr);
if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, safi, pi, NULL, connected,
- bgp_nht_param_prefix) ||
+ bgp_nht_param_prefix, bpi_ultimate) ||
CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD)) {
if (accept_own)
bgp_path_info_set_flag(dest, pi, BGP_PATH_ACCEPT_OWN);
@@ -6793,6 +6825,16 @@ static int clear_batch_rib_helper(struct bgp_clearing_info *cinfo)
*/
UNSET_FLAG(cinfo->flags, BGP_CLEARING_INFO_FLAG_RESUME);
}
+
+ /* Return immediately, otherwise the 'ret' state will be overwritten
+ * by next afi/safi. Also resume state stored for current afi/safi
+ * in walk_batch_table_helper, will be overwritten. This may cause to
+ * skip the nets to be walked again, so they won't be marked for deletion
+ * from BGP table
+ */
+ if (ret != 0)
+ return ret;
+
safi = SAFI_UNICAST;
}
return ret;
@@ -7304,8 +7346,8 @@ static void bgp_nexthop_reachability_check(afi_t afi, safi_t safi,
/* Nexthop reachability check. */
if (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST) {
if (CHECK_FLAG(bgp->flags, BGP_FLAG_IMPORT_CHECK)) {
- if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi,
- bpi, NULL, 0, p))
+ if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, safi, bpi, NULL, 0, p,
+ NULL))
bgp_path_info_set_flag(dest, bpi,
BGP_PATH_VALID);
else {
@@ -7477,9 +7519,9 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
break;
if (pi) {
- if (attrhash_cmp(pi->attr, attr_new)
- && !CHECK_FLAG(pi->flags, BGP_PATH_REMOVED)
- && !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS)) {
+ if (!CHECK_FLAG(pi->flags, BGP_PATH_REMOVED) &&
+ !CHECK_FLAG(bgp->flags, BGP_FLAG_FORCE_STATIC_PROCESS) &&
+ attrhash_cmp(pi->attr, attr_new)) {
bgp_dest_unlock_node(dest);
bgp_attr_unintern(&attr_new);
aspath_unintern(&attr.aspath);
@@ -7973,6 +8015,8 @@ void bgp_static_delete(struct bgp *bgp)
rm = bgp_dest_unlock_node(rm);
assert(rm);
}
+
+ bgp_table_unlock(table);
} else {
bgp_static = bgp_dest_get_bgp_static_info(dest);
bgp_static_withdraw(bgp,
@@ -9731,8 +9775,8 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
if (bpi) {
/* Ensure the (source route) type is updated. */
bpi->type = type;
- if (attrhash_cmp(bpi->attr, new_attr)
- && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
+ if (!CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) &&
+ attrhash_cmp(bpi->attr, new_attr)) {
bgp_attr_unintern(&new_attr);
aspath_unintern(&attr.aspath);
bgp_dest_unlock_node(bn);
@@ -12002,8 +12046,6 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
/* Line 7 display Originator, Cluster-id */
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID)) ||
CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
- char buf[BUFSIZ] = {0};
-
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_ORIGINATOR_ID))) {
if (json_paths)
json_object_string_addf(json_path,
@@ -12015,9 +12057,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
}
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST))) {
- struct cluster_list *cluster =
- bgp_attr_get_cluster(attr);
- int i;
+ struct cluster_list *cluster = bgp_attr_get_cluster(attr);
if (json_paths) {
json_cluster_list = json_object_new_object();
@@ -13297,8 +13337,6 @@ static int bgp_show_route_in_table(struct vty *vty, struct bgp *bgp, struct bgp_
return CMD_WARNING;
}
- match.family = afi2family(afi);
-
if (use_json)
json = json_object_new_object();
@@ -13547,7 +13585,7 @@ DEFUN (show_ip_bgp_large_community_list,
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
int idx = 0;
- bool exact_match = 0;
+ bool match_p = 0;
struct bgp *bgp = NULL;
bool uj = use_json(argc, argv);
@@ -13564,10 +13602,10 @@ DEFUN (show_ip_bgp_large_community_list,
const char *clist_number_or_name = argv[++idx]->arg;
if (++idx < argc && strmatch(argv[idx]->text, "exact-match"))
- exact_match = 1;
+ match_p = 1;
return bgp_show_lcommunity_list(vty, bgp, clist_number_or_name,
- exact_match, afi, safi, uj);
+ match_p, afi, safi, uj);
}
DEFUN (show_ip_bgp_large_community,
show_ip_bgp_large_community_cmd,
@@ -13586,7 +13624,7 @@ DEFUN (show_ip_bgp_large_community,
afi_t afi = AFI_IP6;
safi_t safi = SAFI_UNICAST;
int idx = 0;
- bool exact_match = 0;
+ bool match_p = false;
struct bgp *bgp = NULL;
bool uj = use_json(argc, argv);
uint16_t show_flags = 0;
@@ -13604,10 +13642,10 @@ DEFUN (show_ip_bgp_large_community,
if (argv_find(argv, argc, "AA:BB:CC", &idx)) {
if (argv_find(argv, argc, "exact-match", &idx)) {
argc--;
- exact_match = 1;
+ match_p = true;
}
return bgp_show_lcommunity(vty, bgp, argc, argv,
- exact_match, afi, safi, uj);
+ match_p, afi, safi, uj);
} else
return bgp_show(vty, bgp, afi, safi,
bgp_show_type_lcommunity_all, NULL, show_flags,
@@ -13878,7 +13916,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
void *output_arg = NULL;
struct bgp *bgp = NULL;
int idx = 0;
- int exact_match = 0;
+ int match_p = 0;
char *community = NULL;
bool first = true;
uint16_t show_flags = 0;
@@ -13943,7 +13981,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
community = maybecomm;
if (argv_find(argv, argc, "exact-match", &idx))
- exact_match = 1;
+ match_p = 1;
if (!community)
sh_type = bgp_show_type_community_all;
@@ -13954,7 +13992,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
struct community_list *list;
if (argv_find(argv, argc, "exact-match", &idx))
- exact_match = 1;
+ match_p = 1;
list = community_list_lookup(bgp_clist, clist_number_or_name, 0,
COMMUNITY_LIST_MASTER);
@@ -13964,7 +14002,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
return CMD_WARNING;
}
- if (exact_match)
+ if (match_p)
sh_type = bgp_show_type_community_list_exact;
else
sh_type = bgp_show_type_community_list;
@@ -14074,7 +14112,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
/* show bgp: AFI_IP6, show ip bgp: AFI_IP */
if (community)
return bgp_show_community(vty, bgp, community,
- exact_match, afi, safi,
+ match_p, afi, safi,
show_flags);
else
return bgp_show(vty, bgp, afi, safi, sh_type,
@@ -14119,7 +14157,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
if (community)
bgp_show_community(
vty, abgp, community,
- exact_match, afi, safi,
+ match_p, afi, safi,
show_flags);
else
bgp_show(vty, abgp, afi, safi,
@@ -14167,7 +14205,7 @@ DEFPY(show_ip_bgp, show_ip_bgp_cmd,
if (community)
bgp_show_community(
vty, abgp, community,
- exact_match, afi, safi,
+ match_p, afi, safi,
show_flags);
else
bgp_show(vty, abgp, afi, safi,
@@ -15437,15 +15475,15 @@ show_adj_route(struct vty *vty, struct peer *peer, struct bgp_table *table,
json_net =
json_object_new_object();
- struct bgp_path_info bpi;
+ struct bgp_path_info pathi;
struct bgp_dest buildit = *dest;
struct bgp_dest *pass_in;
if (route_filtered ||
ret == RMAP_DENY) {
- bpi.attr = &attr;
- bpi.peer = peer;
- buildit.info = &bpi;
+ pathi.attr = &attr;
+ pathi.peer = peer;
+ buildit.info = &pathi;
pass_in = &buildit;
} else
@@ -16709,8 +16747,6 @@ static int bgp_clear_damp_route(struct vty *vty, const char *view_name,
return CMD_WARNING;
}
- match.family = afi2family(afi);
-
if ((safi == SAFI_MPLS_VPN) || (safi == SAFI_ENCAP)
|| (safi == SAFI_EVPN)) {
for (dest = bgp_table_top(bgp->rib[AFI_IP][safi]); dest;
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index 5c10a865d1..af8c111043 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -88,7 +88,6 @@ enum bgp_show_adj_route_type {
#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE4_SIZE -9
#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE5_SIZE -10
#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_IPV6_NOT_SUPPORTED -11
-#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_NLRI_SIZELIMIT -12
#define BGP_NLRI_PARSE_ERROR_FLOWSPEC_BAD_FORMAT -13
#define BGP_NLRI_PARSE_ERROR_ADDRESS_FAMILY -14
#define BGP_NLRI_PARSE_ERROR_EVPN_TYPE1_SIZE -15
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index c7c8f157ca..15ad921ad0 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -2615,6 +2615,9 @@ route_set_aspath_exclude(void *rule, const struct prefix *dummy, void *object)
path->attr->aspath =
aspath_filter_exclude_acl(new_path,
ase->exclude_aspath_acl);
+ else
+ aspath_free(new_path);
+
return RMAP_OKAY;
}
diff --git a/bgpd/bgp_routemap_nb_config.c b/bgpd/bgp_routemap_nb_config.c
index 5f5274c5e1..cf189a6aaf 100644
--- a/bgpd/bgp_routemap_nb_config.c
+++ b/bgpd/bgp_routemap_nb_config.c
@@ -1355,7 +1355,7 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish(
{
struct routemap_hook_context *rhc;
const char *value;
- bool exact_match = false;
+ bool match_p = false;
bool any = false;
char *argstr;
const char *condition;
@@ -1367,13 +1367,13 @@ lib_route_map_entry_match_condition_rmap_match_condition_comm_list_finish(
value = yang_dnode_get_string(args->dnode, "comm-list-name");
if (yang_dnode_exists(args->dnode, "comm-list-name-exact-match"))
- exact_match = yang_dnode_get_bool(
+ match_p = yang_dnode_get_bool(
args->dnode, "./comm-list-name-exact-match");
if (yang_dnode_exists(args->dnode, "comm-list-name-any"))
any = yang_dnode_get_bool(args->dnode, "comm-list-name-any");
- if (exact_match) {
+ if (match_p) {
argstr = XMALLOC(MTYPE_ROUTE_MAP_COMPILED,
strlen(value) + strlen("exact-match") + 2);
diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c
index 04a709b350..aefb58094b 100644
--- a/bgpd/bgp_rpki.c
+++ b/bgpd/bgp_rpki.c
@@ -529,7 +529,10 @@ static struct rtr_mgr_group *get_groups(struct list *cache_list)
inline bool is_synchronized(struct rpki_vrf *rpki_vrf)
{
- return rpki_vrf->rtr_is_synced;
+ if (is_running(rpki_vrf))
+ return rpki_vrf->rtr_is_synced;
+ else
+ return false;
}
inline bool is_running(struct rpki_vrf *rpki_vrf)
diff --git a/bgpd/bgp_updgrp.c b/bgpd/bgp_updgrp.c
index 04e6a83552..d880c7b399 100644
--- a/bgpd/bgp_updgrp.c
+++ b/bgpd/bgp_updgrp.c
@@ -967,10 +967,10 @@ static int update_group_show_walkcb(struct update_group *updgrp, void *arg)
if (ctx->uj) {
json_peers = json_object_new_array();
SUBGRP_FOREACH_PEER (subgrp, paf) {
- json_object *peer =
+ json_object *jpeer =
json_object_new_string(
paf->peer->host);
- json_object_array_add(json_peers, peer);
+ json_object_array_add(json_peers, jpeer);
}
json_object_object_add(json_subgrp, "peers",
json_peers);
diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c
index 66a2fe7997..1df8b4ffe2 100644
--- a/bgpd/bgp_vty.c
+++ b/bgpd/bgp_vty.c
@@ -11080,7 +11080,6 @@ static int bgp_clear_prefix(struct vty *vty, const char *view_name,
return CMD_WARNING;
}
- match.family = afi2family(afi);
rib = bgp->rib[afi][safi];
if (safi == SAFI_MPLS_VPN) {
@@ -11504,7 +11503,7 @@ DEFPY (show_bgp_vrfs,
json_vrfs = json_object_new_object();
for (ALL_LIST_ELEMENTS_RO(inst, node, bgp)) {
- const char *name;
+ const char *bname;
/* Skip Views. */
if (bgp->inst_type == BGP_INSTANCE_TYPE_VIEW)
@@ -11523,18 +11522,18 @@ DEFPY (show_bgp_vrfs,
json_vrf = json_object_new_object();
if (bgp->inst_type == BGP_INSTANCE_TYPE_DEFAULT) {
- name = VRF_DEFAULT_NAME;
+ bname = VRF_DEFAULT_NAME;
type = "DFLT";
} else {
- name = bgp->name;
+ bname = bgp->name;
type = "VRF";
}
- show_bgp_vrfs_detail_common(vty, bgp, json_vrf, name, type,
+ show_bgp_vrfs_detail_common(vty, bgp, json_vrf, bname, type,
false);
if (uj)
- json_object_object_add(json_vrfs, name, json_vrf);
+ json_object_object_add(json_vrfs, bname, json_vrf);
}
if (uj) {
@@ -14089,9 +14088,14 @@ static void bgp_show_peer_afi(struct vty *vty, struct peer *p, afi_t afi,
? "Advertise"
: "Withdraw");
- /* Receive prefix count */
- vty_out(vty, " %u accepted prefixes\n",
- p->pcount[afi][safi]);
+ /* Receive and sent prefix count, if available */
+ paf = peer_af_find(p, afi, safi);
+ if (paf && PAF_SUBGRP(paf))
+ vty_out(vty, " %u accepted, %u sent prefixes\n",
+ p->pcount[afi][safi], PAF_SUBGRP(paf)->scount);
+ else
+ vty_out(vty, " %u accepted prefixes\n",
+ p->pcount[afi][safi]);
/* maximum-prefix-out */
if (CHECK_FLAG(p->af_flags[afi][safi],
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index b953da57ce..6a874d53b6 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -56,8 +56,8 @@
#include "bgpd/bgp_lcommunity.h"
/* All information about zebra. */
-struct zclient *zclient = NULL;
-struct zclient *zclient_sync;
+struct zclient *bgp_zclient = NULL;
+struct zclient *bgp_zclient_sync;
static bool bgp_zebra_label_manager_connect(void);
/* hook to indicate vrf status change for SNMP */
@@ -69,7 +69,7 @@ DEFINE_MTYPE_STATIC(BGPD, BGP_IF_INFO, "BGP interface context");
/* Can we install into zebra? */
static inline bool bgp_install_info_to_zebra(struct bgp *bgp)
{
- if (zclient->sock <= 0)
+ if (bgp_zclient->sock <= 0)
return false;
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
@@ -1010,15 +1010,15 @@ struct bgp *bgp_tm_bgp;
static void bgp_zebra_tm_connect(struct event *t)
{
- struct zclient *zclient;
+ struct zclient *zc;
int delay = 10, ret = 0;
- zclient = EVENT_ARG(t);
- if (bgp_tm_status_connected && zclient->sock > 0)
+ zc = EVENT_ARG(t);
+ if (bgp_tm_status_connected && zc->sock > 0)
delay = 60;
else {
bgp_tm_status_connected = false;
- ret = tm_table_manager_connect(zclient);
+ ret = tm_table_manager_connect(zc);
}
if (ret < 0) {
zlog_err("Error connecting to table manager!");
@@ -1031,7 +1031,7 @@ static void bgp_zebra_tm_connect(struct event *t)
}
bgp_tm_status_connected = true;
if (!bgp_tm_chunk_obtained) {
- if (bgp_zebra_get_table_range(zclient, bgp_tm_chunk_size,
+ if (bgp_zebra_get_table_range(zc, bgp_tm_chunk_size,
&bgp_tm_min,
&bgp_tm_max) >= 0) {
bgp_tm_chunk_obtained = true;
@@ -1040,7 +1040,7 @@ static void bgp_zebra_tm_connect(struct event *t)
}
}
}
- event_add_timer(bm->master, bgp_zebra_tm_connect, zclient, delay,
+ event_add_timer(bm->master, bgp_zebra_tm_connect, zc, delay,
&bgp_tm_thread_connect);
}
@@ -1071,7 +1071,7 @@ void bgp_zebra_init_tm_connect(struct bgp *bgp)
bgp_tm_min = bgp_tm_max = 0;
bgp_tm_chunk_size = BGP_FLOWSPEC_TABLE_CHUNK;
bgp_tm_bgp = bgp;
- event_add_timer(bm->master, bgp_zebra_tm_connect, zclient_sync, delay,
+ event_add_timer(bm->master, bgp_zebra_tm_connect, bgp_zclient_sync, delay,
&bgp_tm_thread_connect);
}
@@ -1650,7 +1650,7 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
__func__, p, (allow_recursion ? "" : "NOT "));
}
- return zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ return zclient_route_send(ZEBRA_ROUTE_ADD, bgp_zclient, &api);
}
@@ -1747,7 +1747,7 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest,
zlog_debug("Tx route delete %s (table id %u) %pFX",
bgp->name_pretty, api.tableid, &api.prefix);
- return zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ return zclient_route_send(ZEBRA_ROUTE_DELETE, bgp_zclient, &api);
}
/*
@@ -2071,19 +2071,19 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
.table_id = instance,
.vrf_id = bgp->vrf_id,
};
- if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) !=
- NULL)
+ if (redist_lookup_table_direct(&bgp_zclient->mi_redist[afi][type],
+ &table) != NULL)
return CMD_WARNING;
- redist_add_table_direct(&zclient->mi_redist[afi][type], &table);
+ redist_add_table_direct(&bgp_zclient->mi_redist[afi][type], &table);
} else {
- if (redist_check_instance(&zclient->mi_redist[afi][type], instance))
+ if (redist_check_instance(&bgp_zclient->mi_redist[afi][type], instance))
return CMD_WARNING;
- redist_add_instance(&zclient->mi_redist[afi][type], instance);
+ redist_add_instance(&bgp_zclient->mi_redist[afi][type], instance);
}
} else {
- if (vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id))
+ if (vrf_bitmap_check(&bgp_zclient->redist[afi][type], bgp->vrf_id))
return CMD_WARNING;
#ifdef ENABLE_BGP_VNC
@@ -2093,7 +2093,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
}
#endif
- vrf_bitmap_set(&zclient->redist[afi][type], bgp->vrf_id);
+ vrf_bitmap_set(&bgp_zclient->redist[afi][type], bgp->vrf_id);
}
/*
@@ -2111,7 +2111,7 @@ int bgp_redistribute_set(struct bgp *bgp, afi_t afi, int type,
instance);
/* Send distribute add message to zebra. */
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, bgp_zclient, afi, type,
instance, bgp->vrf_id);
return CMD_SUCCESS;
@@ -2132,9 +2132,9 @@ int bgp_redistribute_resend(struct bgp *bgp, afi_t afi, int type,
instance);
/* Send distribute add message to zebra. */
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi, type,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, bgp_zclient, afi, type,
instance, bgp->vrf_id);
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, bgp_zclient, afi, type,
instance, bgp->vrf_id);
return 0;
@@ -2214,21 +2214,21 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,
.table_id = instance,
.vrf_id = bgp->vrf_id,
};
- if (redist_lookup_table_direct(&zclient->mi_redist[afi][type], &table) ==
+ if (redist_lookup_table_direct(&bgp_zclient->mi_redist[afi][type], &table) ==
NULL)
return CMD_WARNING;
- redist_del_table_direct(&zclient->mi_redist[afi][type], &table);
+ redist_del_table_direct(&bgp_zclient->mi_redist[afi][type], &table);
} else {
- if (!redist_check_instance(&zclient->mi_redist[afi][type], instance))
+ if (!redist_check_instance(&bgp_zclient->mi_redist[afi][type], instance))
return CMD_WARNING;
- redist_del_instance(&zclient->mi_redist[afi][type], instance);
+ redist_del_instance(&bgp_zclient->mi_redist[afi][type], instance);
}
} else {
- if (!vrf_bitmap_check(&zclient->redist[afi][type], bgp->vrf_id))
+ if (!vrf_bitmap_check(&bgp_zclient->redist[afi][type], bgp->vrf_id))
return CMD_WARNING;
- vrf_bitmap_unset(&zclient->redist[afi][type], bgp->vrf_id);
+ vrf_bitmap_unset(&bgp_zclient->redist[afi][type], bgp->vrf_id);
}
if (bgp_install_info_to_zebra(bgp)) {
@@ -2237,7 +2237,7 @@ int bgp_redistribute_unreg(struct bgp *bgp, afi_t afi, int type,
zlog_debug("Tx redistribute del %s afi %d %s %d",
bgp->name_pretty, afi,
zebra_route_string(type), instance);
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, bgp_zclient, afi,
type, instance, bgp->vrf_id);
}
@@ -2325,7 +2325,7 @@ void bgp_redistribute_redo(struct bgp *bgp)
void bgp_zclient_reset(void)
{
- zclient_reset(zclient);
+ zclient_reset(bgp_zclient);
}
/* Register this instance with Zebra. Invoked upon connect (for
@@ -2335,14 +2335,14 @@ void bgp_zclient_reset(void)
void bgp_zebra_instance_register(struct bgp *bgp)
{
/* Don't try to register if we're not connected to Zebra */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return;
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Registering %s", bgp->name_pretty);
/* Register for router-id, interfaces, redistributed routes. */
- zclient_send_reg_requests(zclient, bgp->vrf_id);
+ zclient_send_reg_requests(bgp_zclient, bgp->vrf_id);
/* For EVPN instance, register to learn about VNIs, if appropriate. */
if (bgp->advertise_all_vni)
@@ -2364,7 +2364,7 @@ void bgp_zebra_instance_register(struct bgp *bgp)
void bgp_zebra_instance_deregister(struct bgp *bgp)
{
/* Don't try to deregister if we're not connected to Zebra */
- if (zclient->sock < 0)
+ if (bgp_zclient->sock < 0)
return;
if (BGP_DEBUG(zebra, ZEBRA))
@@ -2375,7 +2375,7 @@ void bgp_zebra_instance_deregister(struct bgp *bgp)
bgp_zebra_advertise_all_vni(bgp, 0);
/* Deregister for router-id, interfaces, redistributed routes. */
- zclient_send_dereg_requests(zclient, bgp->vrf_id);
+ zclient_send_dereg_requests(bgp_zclient, bgp->vrf_id);
}
void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
@@ -2386,7 +2386,7 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
return;
/* Don't try to initiate if we're not connected to Zebra */
- if (zclient->sock < 0)
+ if (bgp_zclient->sock < 0)
return;
if (BGP_DEBUG(zebra, ZEBRA))
@@ -2398,7 +2398,7 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
* If we don't have an ifp pointer, call function to find the
* ifps for a numbered enhe peer to turn RAs on.
*/
- peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
+ peer->ifp ? zclient_send_interface_radv_req(bgp_zclient, bgp->vrf_id,
peer->ifp, 1, ra_interval)
: bgp_nht_reg_enhe_cap_intfs(peer);
}
@@ -2406,7 +2406,7 @@ void bgp_zebra_initiate_radv(struct bgp *bgp, struct peer *peer)
void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
{
/* Don't try to terminate if we're not connected to Zebra */
- if (zclient->sock < 0)
+ if (bgp_zclient->sock < 0)
return;
if (BGP_DEBUG(zebra, ZEBRA))
@@ -2418,7 +2418,7 @@ void bgp_zebra_terminate_radv(struct bgp *bgp, struct peer *peer)
* If we don't have an ifp pointer, call function to find the
* ifps for a numbered enhe peer to turn RAs off.
*/
- peer->ifp ? zclient_send_interface_radv_req(zclient, bgp->vrf_id,
+ peer->ifp ? zclient_send_interface_radv_req(bgp_zclient, bgp->vrf_id,
peer->ifp, 0, 0)
: bgp_nht_dereg_enhe_cap_intfs(peer);
}
@@ -2428,7 +2428,7 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni)
struct stream *s = NULL;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return 0;
/* Don't try to register if Zebra doesn't know of this instance. */
@@ -2440,7 +2440,7 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni)
return 0;
}
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_ADVERTISE_SUBNET, bgp->vrf_id);
@@ -2448,7 +2448,7 @@ int bgp_zebra_advertise_subnet(struct bgp *bgp, int advertise, vni_t vni)
stream_put3(s, vni);
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni)
@@ -2456,14 +2456,14 @@ int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni)
struct stream *s = NULL;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return 0;
/* Don't try to register if Zebra doesn't know of this instance. */
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
return 0;
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_ADVERTISE_SVI_MACIP, bgp->vrf_id);
@@ -2471,7 +2471,7 @@ int bgp_zebra_advertise_svi_macip(struct bgp *bgp, int advertise, vni_t vni)
stream_putl(s, vni);
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
@@ -2479,7 +2479,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
struct stream *s = NULL;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return 0;
/* Don't try to register if Zebra doesn't know of this instance. */
@@ -2491,7 +2491,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
return 0;
}
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_ADVERTISE_DEFAULT_GW, bgp->vrf_id);
@@ -2499,7 +2499,7 @@ int bgp_zebra_advertise_gw_macip(struct bgp *bgp, int advertise, vni_t vni)
stream_putl(s, vni);
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
@@ -2508,7 +2508,7 @@ int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
struct stream *s;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return 0;
/* Don't try to register if Zebra doesn't know of this instance. */
@@ -2520,14 +2520,14 @@ int bgp_zebra_vxlan_flood_control(struct bgp *bgp,
return 0;
}
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_VXLAN_FLOOD_CONTROL, bgp->vrf_id);
stream_putc(s, flood_ctrl);
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
@@ -2535,14 +2535,14 @@ int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
struct stream *s;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return 0;
/* Don't try to register if Zebra doesn't know of this instance. */
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp))
return 0;
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_ADVERTISE_ALL_VNI, bgp->vrf_id);
@@ -2553,7 +2553,7 @@ int bgp_zebra_advertise_all_vni(struct bgp *bgp, int advertise)
stream_putc(s, bgp->vxlan_flood_ctrl);
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
int bgp_zebra_dup_addr_detection(struct bgp *bgp)
@@ -2561,7 +2561,7 @@ int bgp_zebra_dup_addr_detection(struct bgp *bgp)
struct stream *s;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!bgp_zclient || bgp_zclient->sock < 0)
return 0;
/* Don't try to register if Zebra doesn't know of this instance. */
@@ -2578,7 +2578,7 @@ int bgp_zebra_dup_addr_detection(struct bgp *bgp)
"enable" : "disable",
bgp->evpn_info->dad_freeze_time);
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_DUPLICATE_ADDR_DETECTION,
bgp->vrf_id);
@@ -2589,7 +2589,7 @@ int bgp_zebra_dup_addr_detection(struct bgp *bgp)
stream_putl(s, bgp->evpn_info->dad_freeze_time);
stream_putw_at(s, 0, stream_get_endp(s));
- return zclient_send_message(zclient);
+ return zclient_send_message(bgp_zclient);
}
static int rule_notify_owner(ZAPI_CALLBACK_ARGS)
@@ -3965,7 +3965,7 @@ void bgp_if_init(void)
static bool bgp_zebra_label_manager_ready(void)
{
- return (zclient_sync->sock > 0);
+ return (bgp_zclient_sync->sock > 0);
}
static void bgp_start_label_manager(struct event *start)
@@ -3979,29 +3979,29 @@ static void bgp_start_label_manager(struct event *start)
static bool bgp_zebra_label_manager_connect(void)
{
/* Connect to label manager. */
- if (zclient_socket_connect(zclient_sync) < 0) {
+ if (zclient_socket_connect(bgp_zclient_sync) < 0) {
zlog_warn("%s: failed connecting synchronous zclient!",
__func__);
return false;
}
/* make socket non-blocking */
- set_nonblocking(zclient_sync->sock);
+ set_nonblocking(bgp_zclient_sync->sock);
/* Send hello to notify zebra this is a synchronous client */
- if (zclient_send_hello(zclient_sync) == ZCLIENT_SEND_FAILURE) {
+ if (zclient_send_hello(bgp_zclient_sync) == ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: failed sending hello for synchronous zclient!",
__func__);
- close(zclient_sync->sock);
- zclient_sync->sock = -1;
+ close(bgp_zclient_sync->sock);
+ bgp_zclient_sync->sock = -1;
return false;
}
/* Connect to label manager */
- if (lm_label_manager_connect(zclient_sync, 0) != 0) {
+ if (lm_label_manager_connect(bgp_zclient_sync, 0) != 0) {
zlog_warn("%s: failed connecting to label manager!", __func__);
- if (zclient_sync->sock > 0) {
- close(zclient_sync->sock);
- zclient_sync->sock = -1;
+ if (bgp_zclient_sync->sock > 0) {
+ close(bgp_zclient_sync->sock);
+ bgp_zclient_sync->sock = -1;
}
return false;
}
@@ -4030,22 +4030,22 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance)
hook_register_prio(if_unreal, 0, bgp_ifp_destroy);
/* Set default values. */
- zclient = zclient_new(master, &zclient_options_default, bgp_handlers,
- array_size(bgp_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
- zclient->zebra_buffer_write_ready = bgp_zebra_buffer_write_ready;
- zclient->zebra_connected = bgp_zebra_connected;
- zclient->zebra_capabilities = bgp_zebra_capabilities;
- zclient->nexthop_update = bgp_nexthop_update;
- zclient->instance = instance;
+ bgp_zclient = zclient_new(master, &zclient_options_default, bgp_handlers,
+ array_size(bgp_handlers));
+ zclient_init(bgp_zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs);
+ bgp_zclient->zebra_buffer_write_ready = bgp_zebra_buffer_write_ready;
+ bgp_zclient->zebra_connected = bgp_zebra_connected;
+ bgp_zclient->zebra_capabilities = bgp_zebra_capabilities;
+ bgp_zclient->nexthop_update = bgp_nexthop_update;
+ bgp_zclient->instance = instance;
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
- zclient_sync->sock = -1;
- zclient_sync->redist_default = ZEBRA_ROUTE_BGP;
- zclient_sync->instance = instance;
- zclient_sync->session_id = 1;
- zclient_sync->privs = &bgpd_privs;
+ bgp_zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
+ bgp_zclient_sync->sock = -1;
+ bgp_zclient_sync->redist_default = ZEBRA_ROUTE_BGP;
+ bgp_zclient_sync->instance = instance;
+ bgp_zclient_sync->session_id = 1;
+ bgp_zclient_sync->privs = &bgpd_privs;
if (!bgp_zebra_label_manager_ready())
event_add_timer(master, bgp_start_label_manager, NULL, 1,
@@ -4054,17 +4054,17 @@ void bgp_zebra_init(struct event_loop *master, unsigned short instance)
void bgp_zebra_destroy(void)
{
- if (zclient == NULL)
+ if (bgp_zclient == NULL)
return;
- zclient_stop(zclient);
- zclient_free(zclient);
- zclient = NULL;
+ zclient_stop(bgp_zclient);
+ zclient_free(bgp_zclient);
+ bgp_zclient = NULL;
- if (zclient_sync == NULL)
+ if (bgp_zclient_sync == NULL)
return;
- zclient_stop(zclient_sync);
- zclient_free(zclient_sync);
- zclient_sync = NULL;
+ zclient_stop(bgp_zclient_sync);
+ zclient_free(bgp_zclient_sync);
+ bgp_zclient_sync = NULL;
}
int bgp_zebra_num_connects(void)
@@ -4090,7 +4090,7 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra,
zlog_debug("%s: table %d fwmark %d %d", __func__,
pbra->table_id, pbra->fwmark, install);
}
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s,
@@ -4099,7 +4099,7 @@ void bgp_send_pbr_rule_action(struct bgp_pbr_action *pbra,
bgp_encode_pbr_rule_action(s, pbra, pbr);
- if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE)
+ if ((zclient_send_message(bgp_zclient) != ZCLIENT_SEND_FAILURE)
&& install) {
if (!pbr)
pbra->install_in_progress = true;
@@ -4118,7 +4118,7 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
zlog_debug("%s: name %s type %d %d, ID %u", __func__,
pbrim->ipset_name, pbrim->type, install,
pbrim->unique);
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s,
@@ -4131,7 +4131,7 @@ void bgp_send_pbr_ipset_match(struct bgp_pbr_match *pbrim, bool install)
bgp_encode_pbr_ipset_match(s, pbrim);
stream_putw_at(s, 0, stream_get_endp(s));
- if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
+ if ((zclient_send_message(bgp_zclient) != ZCLIENT_SEND_FAILURE) && install)
pbrim->install_in_progress = true;
}
@@ -4146,7 +4146,7 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
zlog_debug("%s: name %s %d %d, ID %u", __func__,
pbrime->backpointer->ipset_name, pbrime->unique,
install, pbrime->unique);
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s,
@@ -4159,7 +4159,7 @@ void bgp_send_pbr_ipset_entry_match(struct bgp_pbr_match_entry *pbrime,
bgp_encode_pbr_ipset_entry_match(s, pbrime);
stream_putw_at(s, 0, stream_get_endp(s));
- if ((zclient_send_message(zclient) != ZCLIENT_SEND_FAILURE) && install)
+ if ((zclient_send_message(bgp_zclient) != ZCLIENT_SEND_FAILURE) && install)
pbrime->install_in_progress = true;
}
@@ -4218,7 +4218,7 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
zlog_debug("%s: name %s type %d mark %d %d, ID %u", __func__,
pbm->ipset_name, pbm->type, pba->fwmark, install,
pbm->unique2);
- s = zclient->obuf;
+ s = bgp_zclient->obuf;
stream_reset(s);
zclient_create_header(s,
@@ -4232,7 +4232,7 @@ void bgp_send_pbr_iptable(struct bgp_pbr_action *pba,
if (nb_interface)
bgp_encode_pbr_interface_list(pba->bgp, s, pbm->family);
stream_putw_at(s, 0, stream_get_endp(s));
- ret = zclient_send_message(zclient);
+ ret = zclient_send_message(bgp_zclient);
if (install) {
if (ret != ZCLIENT_SEND_FAILURE)
pba->refcnt++;
@@ -4319,7 +4319,7 @@ void bgp_zebra_announce_default(struct bgp *bgp, struct nexthop *nh,
}
zclient_route_send(announce ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
- zclient, &api);
+ bgp_zclient, &api);
}
/* Send capabilities to RIB */
@@ -4332,7 +4332,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
zlog_debug("%s: Sending %sable for %s", __func__,
disable ? "dis" : "en", bgp->name_pretty);
- if (zclient == NULL) {
+ if (bgp_zclient == NULL) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s zclient invalid", __func__,
bgp->name_pretty);
@@ -4340,7 +4340,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
}
/* Check if the client is connected */
- if ((zclient->sock < 0) || (zclient->t_connect)) {
+ if ((bgp_zclient->sock < 0) || (bgp_zclient->t_connect)) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s client not connected", __func__,
bgp->name_pretty);
@@ -4365,7 +4365,7 @@ int bgp_zebra_send_capabilities(struct bgp *bgp, bool disable)
api.vrf_id = bgp->vrf_id;
}
- if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
+ if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, bgp_zclient, &api)
== ZCLIENT_SEND_FAILURE) {
zlog_err("%s(%d): Error sending GR capability to zebra",
bgp->name_pretty, bgp->vrf_id);
@@ -4394,7 +4394,7 @@ int bgp_zebra_update(struct bgp *bgp, afi_t afi, safi_t safi,
bgp->name_pretty, afi, safi,
zserv_gr_client_cap_string(type));
- if (zclient == NULL) {
+ if (bgp_zclient == NULL) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s zclient == NULL, invalid", __func__,
bgp->name_pretty);
@@ -4402,7 +4402,7 @@ int bgp_zebra_update(struct bgp *bgp, afi_t afi, safi_t safi,
}
/* Check if the client is connected */
- if ((zclient->sock < 0) || (zclient->t_connect)) {
+ if ((bgp_zclient->sock < 0) || (bgp_zclient->t_connect)) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s client not connected", __func__,
bgp->name_pretty);
@@ -4414,7 +4414,7 @@ int bgp_zebra_update(struct bgp *bgp, afi_t afi, safi_t safi,
api.vrf_id = bgp->vrf_id;
api.cap = type;
- if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
+ if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, bgp_zclient, &api)
== ZCLIENT_SEND_FAILURE) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s error sending capability", __func__,
@@ -4434,14 +4434,14 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
zlog_debug("%s: %s Timer Update to %u", __func__,
bgp->name_pretty, bgp->rib_stale_time);
- if (zclient == NULL) {
+ if (bgp_zclient == NULL) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("zclient invalid");
return BGP_GR_FAILURE;
}
/* Check if the client is connected */
- if ((zclient->sock < 0) || (zclient->t_connect)) {
+ if ((bgp_zclient->sock < 0) || (bgp_zclient->t_connect)) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s client not connected", __func__,
bgp->name_pretty);
@@ -4452,7 +4452,7 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
api.cap = ZEBRA_CLIENT_RIB_STALE_TIME;
api.stale_removal_time = bgp->rib_stale_time;
api.vrf_id = bgp->vrf_id;
- if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient, &api)
+ if (zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, bgp_zclient, &api)
== ZCLIENT_SEND_FAILURE) {
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("%s: %s error sending capability", __func__,
@@ -4465,12 +4465,12 @@ int bgp_zebra_stale_timer_update(struct bgp *bgp)
int bgp_zebra_srv6_manager_get_locator_chunk(const char *name)
{
- return srv6_manager_get_locator_chunk(zclient, name);
+ return srv6_manager_get_locator_chunk(bgp_zclient, name);
}
int bgp_zebra_srv6_manager_release_locator_chunk(const char *name)
{
- return srv6_manager_release_locator_chunk(zclient, name);
+ return srv6_manager_release_locator_chunk(bgp_zclient, name);
}
/**
@@ -4488,7 +4488,7 @@ int bgp_zebra_srv6_manager_get_locator(const char *name)
* Send the Get Locator request to the SRv6 Manager and return the
* result
*/
- return srv6_manager_get_locator(zclient, name);
+ return srv6_manager_get_locator(bgp_zclient, name);
}
/**
@@ -4520,7 +4520,7 @@ bool bgp_zebra_request_srv6_sid(const struct srv6_sid_ctx *ctx,
* Send the Get SRv6 SID request to the SRv6 Manager and check the
* result
*/
- ret = srv6_manager_get_sid(zclient, ctx, sid_value, locator_name,
+ ret = srv6_manager_get_sid(bgp_zclient, ctx, sid_value, locator_name,
sid_func);
if (ret < 0) {
zlog_warn("%s: error getting SRv6 SID!", __func__);
@@ -4549,7 +4549,7 @@ void bgp_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx)
* Send the Release SRv6 SID request to the SRv6 Manager and check the
* result
*/
- ret = srv6_manager_release_sid(zclient, ctx);
+ ret = srv6_manager_release_sid(bgp_zclient, ctx);
if (ret < 0) {
zlog_warn("%s: error releasing SRv6 SID!", __func__);
return;
@@ -4592,7 +4592,7 @@ void bgp_zebra_send_nexthop_label(int cmd, mpls_label_t label,
znh->labels[i] = out_labels[i];
}
/* vrf_id is DEFAULT_VRF */
- zebra_send_mpls_labels(zclient, cmd, &zl);
+ zebra_send_mpls_labels(bgp_zclient, cmd, &zl);
}
bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size,
@@ -4601,10 +4601,10 @@ bool bgp_zebra_request_label_range(uint32_t base, uint32_t chunk_size,
int ret;
uint32_t start, end;
- if (!zclient_sync || !bgp_zebra_label_manager_ready())
+ if (!bgp_zclient_sync || !bgp_zebra_label_manager_ready())
return false;
- ret = lm_get_label_chunk(zclient_sync, 0, base, chunk_size, &start,
+ ret = lm_get_label_chunk(bgp_zclient_sync, 0, base, chunk_size, &start,
&end);
if (ret < 0) {
zlog_warn("%s: error getting label range!", __func__);
@@ -4633,10 +4633,10 @@ void bgp_zebra_release_label_range(uint32_t start, uint32_t end)
{
int ret;
- if (!zclient_sync || !bgp_zebra_label_manager_ready())
+ if (!bgp_zclient_sync || !bgp_zebra_label_manager_ready())
return;
- ret = lm_release_label_chunk(zclient_sync, start, end);
+ ret = lm_release_label_chunk(bgp_zclient_sync, start, end);
if (ret < 0)
zlog_warn("%s: error releasing label range!", __func__);
}
diff --git a/bgpd/bgp_zebra.h b/bgpd/bgp_zebra.h
index 7e9d57cb85..fa5b9fc91b 100644
--- a/bgpd/bgp_zebra.h
+++ b/bgpd/bgp_zebra.h
@@ -8,6 +8,9 @@
#include "vxlan.h"
+/* The global zapi session handle */
+extern struct zclient *bgp_zclient;
+
/* Macro to update bgp_original based on bpg_path_info */
#define BGP_ORIGINAL_UPDATE(_bgp_orig, _mpinfo, _bgp) \
((_mpinfo->extra && _mpinfo->extra->vrfleak && \
diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c
index 77150786ce..83f8057736 100644
--- a/bgpd/bgpd.c
+++ b/bgpd/bgpd.c
@@ -121,7 +121,7 @@ unsigned int bgp_suppress_fib_count;
static void bgp_if_finish(struct bgp *bgp);
static void peer_drop_dynamic_neighbor(struct peer *peer);
-extern struct zclient *zclient;
+extern struct zclient *bgp_zclient;
/* handle main socket creation or deletion */
static int bgp_check_main_socket(bool create, struct bgp *bgp)
@@ -447,9 +447,9 @@ void bm_wait_for_fib_set(bool set)
send_msg = true;
}
- if (send_msg && zclient)
+ if (send_msg && bgp_zclient)
zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST,
- zclient, set);
+ bgp_zclient, set);
/*
* If this is configed at a time when peers are already set
@@ -507,9 +507,9 @@ void bgp_suppress_fib_pending_set(struct bgp *bgp, bool set)
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("Sending ZEBRA_ROUTE_NOTIFY_REQUEST");
- if (zclient)
+ if (bgp_zclient)
zebra_route_notify_send(ZEBRA_ROUTE_NOTIFY_REQUEST,
- zclient, set);
+ bgp_zclient, set);
}
/*
@@ -3589,7 +3589,8 @@ peer_init:
bgp->vpn_policy[afi].tovpn_zebra_vrf_label_last_sent =
MPLS_LABEL_NONE;
- bgp->vpn_policy[afi].import_vrf = list_new();
+ if (!bgp->vpn_policy[afi].import_vrf)
+ bgp->vpn_policy[afi].import_vrf = list_new();
bgp->vpn_policy[afi].import_vrf->del =
bgp_vrf_string_name_delete;
if (!hidden) {
@@ -3607,7 +3608,7 @@ peer_init:
bgp_mplsvpn_nh_label_bind_cache_init(&bgp->mplsvpn_nh_label_bind);
- if (name)
+ if (name && !bgp->name)
bgp->name = XSTRDUP(MTYPE_BGP_NAME, name);
event_add_timer(bm->master, bgp_startup_timer_expire, bgp,
@@ -3928,16 +3929,16 @@ static void bgp_zclient_set_redist(afi_t afi, int type, unsigned short instance,
{
if (instance) {
if (set)
- redist_add_instance(&zclient->mi_redist[afi][type],
+ redist_add_instance(&bgp_zclient->mi_redist[afi][type],
instance);
else
- redist_del_instance(&zclient->mi_redist[afi][type],
+ redist_del_instance(&bgp_zclient->mi_redist[afi][type],
instance);
} else {
if (set)
- vrf_bitmap_set(&zclient->redist[afi][type], vrf_id);
+ vrf_bitmap_set(&bgp_zclient->redist[afi][type], vrf_id);
else
- vrf_bitmap_unset(&zclient->redist[afi][type], vrf_id);
+ vrf_bitmap_unset(&bgp_zclient->redist[afi][type], vrf_id);
}
}
@@ -4264,7 +4265,7 @@ int bgp_delete(struct bgp *bgp)
}
}
- if (bgp->peer_self && !IS_BGP_INSTANCE_HIDDEN(bgp)) {
+ if (bgp->peer_self && (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating)) {
peer_delete(bgp->peer_self);
bgp->peer_self = NULL;
}
@@ -4281,7 +4282,7 @@ int bgp_delete(struct bgp *bgp)
/* TODO - Other memory may need to be freed - e.g., NHT */
#ifdef ENABLE_BGP_VNC
- if (!IS_BGP_INSTANCE_HIDDEN(bgp))
+ if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating)
rfapi_delete(bgp);
#endif
@@ -4289,8 +4290,7 @@ int bgp_delete(struct bgp *bgp)
FOREACH_AFI_SAFI (afi, safi) {
struct bgp_aggregate *aggregate = NULL;
- for (struct bgp_dest *dest =
- bgp_table_top(bgp->aggregate[afi][safi]);
+ for (dest = bgp_table_top(bgp->aggregate[afi][safi]);
dest; dest = bgp_route_next(dest)) {
aggregate = bgp_dest_get_bgp_aggregate_info(dest);
if (aggregate == NULL)
@@ -4332,7 +4332,7 @@ int bgp_delete(struct bgp *bgp)
bgp_zebra_instance_deregister(bgp);
}
- if (!IS_BGP_INSTANCE_HIDDEN(bgp)) {
+ if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) {
/* Remove visibility via the master list -
* there may however still be routes to be processed
* still referencing the struct bgp.
@@ -4344,7 +4344,7 @@ int bgp_delete(struct bgp *bgp)
vrf = bgp_vrf_lookup_by_instance_type(bgp);
bgp_handle_socket(bgp, vrf, VRF_UNKNOWN, false);
- if (vrf && !IS_BGP_INSTANCE_HIDDEN(bgp))
+ if (vrf && (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating))
bgp_vrf_unlink(bgp, vrf);
/* Update EVPN VRF pointer */
@@ -4355,7 +4355,7 @@ int bgp_delete(struct bgp *bgp)
bgp_set_evpn(bgp_get_default());
}
- if (!IS_BGP_INSTANCE_HIDDEN(bgp)) {
+ if (!IS_BGP_INSTANCE_HIDDEN(bgp) || bm->terminating) {
if (bgp->process_queue)
work_queue_free_and_null(&bgp->process_queue);
bgp_unlock(bgp); /* initial reference */
@@ -4789,7 +4789,7 @@ enum bgp_peer_active peer_active(struct peer_connection *connection)
return BGP_PEER_CONNECTION_UNSPECIFIED;
if (peer->bfd_config) {
- if (bfd_session_is_down(peer->bfd_config->session))
+ if (peer_established(connection) && bfd_session_is_down(peer->bfd_config->session))
return BGP_PEER_BFD_DOWN;
}
@@ -8683,6 +8683,10 @@ void bgp_master_init(struct event_loop *master, const int buffer_size,
bm = &bgp_master;
+ /* Initialize the peer connection FIFO list */
+ peer_connection_fifo_init(&bm->connection_fifo);
+ pthread_mutex_init(&bm->peer_connection_mtx, NULL);
+
zebra_announce_init(&bm->zebra_announce_head);
zebra_l2_vni_init(&bm->zebra_l2_vni_head);
zebra_l3_vni_init(&bm->zebra_l3_vni_head);
@@ -8968,6 +8972,9 @@ void bgp_terminate(void)
EVENT_OFF(bm->t_bgp_zebra_l3_vni);
bgp_mac_finish();
+#ifdef ENABLE_BGP_VNC
+ rfapi_terminate();
+#endif
}
struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h
index 4b5833151f..bbc45994b4 100644
--- a/bgpd/bgpd.h
+++ b/bgpd/bgpd.h
@@ -107,6 +107,9 @@ enum bgp_af_index {
extern struct frr_pthread *bgp_pth_io;
extern struct frr_pthread *bgp_pth_ka;
+/* FIFO list for peer connections */
+PREDECL_LIST(peer_connection_fifo);
+
/* BGP master for system wide configurations and variables. */
struct bgp_master {
/* BGP instance list. */
@@ -121,6 +124,11 @@ struct bgp_master {
/* BGP port number. */
uint16_t port;
+ /* FIFO list head for peer connections */
+ struct peer_connection_fifo_head connection_fifo;
+ struct event *e_process_packet;
+ pthread_mutex_t peer_connection_mtx;
+
/* Listener addresses */
struct list *addresses;
@@ -1378,7 +1386,6 @@ struct peer_connection {
struct event *t_pmax_restart;
struct event *t_routeadv;
- struct event *t_process_packet;
struct event *t_stop_with_notify;
@@ -1394,7 +1401,14 @@ struct peer_connection {
union sockunion *su_local; /* Sockunion of local address. */
union sockunion *su_remote; /* Sockunion of remote address. */
+
+ /* For FIFO list */
+ struct peer_connection_fifo_item fifo_item;
};
+
+/* Declare the FIFO list implementation */
+DECLARE_LIST(peer_connection_fifo, struct peer_connection, fifo_item);
+
const char *bgp_peer_get_connection_direction(struct peer_connection *connection);
extern struct peer_connection *bgp_peer_connection_new(struct peer *peer);
extern void bgp_peer_connection_free(struct peer_connection **connection);
diff --git a/bgpd/rfapi/rfapi.c b/bgpd/rfapi/rfapi.c
index 241cbcb359..dfe52a9cba 100644
--- a/bgpd/rfapi/rfapi.c
+++ b/bgpd/rfapi/rfapi.c
@@ -946,8 +946,7 @@ void add_vnc_route(struct rfapi_descriptor *rfd, /* cookie, VPN UN addr, peer */
}
}
- if (attrhash_cmp(bpi->attr, new_attr)
- && !CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED)) {
+ if (!CHECK_FLAG(bpi->flags, BGP_PATH_REMOVED) && attrhash_cmp(bpi->attr, new_attr)) {
bgp_attr_unintern(&new_attr);
bgp_dest_unlock_node(bn);
@@ -3546,6 +3545,8 @@ DEFUN (skiplist_debug_cli,
void rfapi_init(void)
{
+ rfapi_rib_init();
+ rfapi_import_init();
bgp_rfapi_cfg_init();
vnc_debug_init();
@@ -3576,6 +3577,12 @@ void rfapi_init(void)
rfapi_vty_init();
}
+void rfapi_terminate(void)
+{
+ rfapi_import_terminate();
+ rfapi_rib_terminate();
+}
+
#ifdef DEBUG_RFAPI
static void rfapi_print_exported(struct bgp *bgp)
{
diff --git a/bgpd/rfapi/rfapi_backend.h b/bgpd/rfapi/rfapi_backend.h
index 32ea0a2821..b89df74b9a 100644
--- a/bgpd/rfapi/rfapi_backend.h
+++ b/bgpd/rfapi/rfapi_backend.h
@@ -14,6 +14,7 @@
#include "bgpd/bgp_nexthop.h"
extern void rfapi_init(void);
+extern void rfapi_terminate(void);
extern void vnc_zebra_init(struct event_loop *master);
extern void vnc_zebra_destroy(void);
diff --git a/bgpd/rfapi/rfapi_import.c b/bgpd/rfapi/rfapi_import.c
index d9f63700f0..0d5a18afbb 100644
--- a/bgpd/rfapi/rfapi_import.c
+++ b/bgpd/rfapi/rfapi_import.c
@@ -53,13 +53,22 @@
#undef DEBUG_BI_SEARCH
/*
+ * Hash to keep track of outstanding timers so we can force them to
+ * expire at shutdown time, thus freeing their allocated memory.
+ */
+PREDECL_HASH(rwcb);
+
+/*
* Allocated for each withdraw timer instance; freed when the timer
* expires or is canceled
*/
struct rfapi_withdraw {
+ struct rwcb_item rwcbi;
+
struct rfapi_import_table *import_table;
struct agg_node *node;
struct bgp_path_info *info;
+ void (*timer_service_func)(struct event *t); /* for cleanup */
safi_t safi; /* used only for bulk operations */
/*
* For import table node reference count checking (i.e., debugging).
@@ -72,6 +81,19 @@ struct rfapi_withdraw {
int lockoffset;
};
+static int _rwcb_cmp(const struct rfapi_withdraw *w1, const struct rfapi_withdraw *w2)
+{
+ return (w1 != w2);
+}
+
+static uint32_t _rwcb_hash(const struct rfapi_withdraw *w)
+{
+ return (uintptr_t)w & 0xffffffff;
+}
+
+DECLARE_HASH(rwcb, struct rfapi_withdraw, rwcbi, _rwcb_cmp, _rwcb_hash);
+static struct rwcb_head _rwcbhash;
+
/*
* DEBUG FUNCTION
* Count remote routes and compare with actively-maintained values.
@@ -826,6 +848,7 @@ static void rfapiBgpInfoChainFree(struct bgp_path_info *bpi)
struct rfapi_withdraw *wcb =
EVENT_ARG(bpi->extra->vnc->vnc.import.timer);
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
EVENT_OFF(bpi->extra->vnc->vnc.import.timer);
}
@@ -1329,11 +1352,11 @@ rfapiRouteInfo2NextHopEntry(struct rfapi_ip_prefix *rprefix,
bgp_attr_extcom_tunnel_type(bpi->attr, &tun_type);
if (tun_type == BGP_ENCAP_TYPE_MPLS) {
- struct prefix p;
+ struct prefix pfx;
/* MPLS carries UN address in next hop */
- rfapiNexthop2Prefix(bpi->attr, &p);
- if (p.family != AF_UNSPEC) {
- rfapiQprefix2Raddr(&p, &new->un_address);
+ rfapiNexthop2Prefix(bpi->attr, &pfx);
+ if (pfx.family != AF_UNSPEC) {
+ rfapiQprefix2Raddr(&pfx, &new->un_address);
have_vnc_tunnel_un = 1;
}
}
@@ -1750,7 +1773,7 @@ struct rfapi_next_hop_entry *rfapiRouteNode2NextHopList(
* Add non-withdrawn routes from less-specific prefix
*/
if (parent) {
- const struct prefix *p = agg_node_get_prefix(parent);
+ p = agg_node_get_prefix(parent);
rib_rn = rfd_rib_table ? agg_node_get(rfd_rib_table, p) : NULL;
rfapiQprefix2Rprefix(p, &rprefix);
@@ -2349,6 +2372,7 @@ static void rfapiWithdrawTimerVPN(struct event *t)
/* This callback is responsible for the withdraw object's memory */
if (early_exit) {
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
return;
}
@@ -2462,6 +2486,7 @@ done:
RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_MPLS_VPN, 1 + wcb->lockoffset);
agg_unlock_node(wcb->node); /* decr ref count */
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
}
@@ -2705,6 +2730,7 @@ static void rfapiWithdrawTimerEncap(struct event *t)
done:
RFAPI_CHECK_REFCOUNT(wcb->node, SAFI_ENCAP, 1);
agg_unlock_node(wcb->node); /* decr ref count */
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
skiplist_free(vpn_node_sl);
}
@@ -2754,6 +2780,8 @@ rfapiBiStartWithdrawTimer(struct rfapi_import_table *import_table,
wcb->node = rn;
wcb->info = bpi;
wcb->import_table = import_table;
+ wcb->timer_service_func = timer_service_func;
+ rwcb_add(&_rwcbhash, wcb);
bgp_attr_intern(bpi->attr);
if (VNC_DEBUG(VERBOSE)) {
@@ -2819,6 +2847,7 @@ static void rfapiExpireEncapNow(struct rfapi_import_table *it,
wcb->info = bpi;
wcb->node = rn;
wcb->import_table = it;
+ rwcb_add(&_rwcbhash, wcb);
memset(&t, 0, sizeof(t));
t.arg = wcb;
rfapiWithdrawTimerEncap(&t); /* frees wcb */
@@ -3057,6 +3086,7 @@ static void rfapiBgpInfoFilteredImportEncap(
struct rfapi_withdraw *wcb = EVENT_ARG(
bpi->extra->vnc->vnc.import.timer);
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
EVENT_OFF(bpi->extra->vnc->vnc.import
.timer);
@@ -3083,6 +3113,7 @@ static void rfapiBgpInfoFilteredImportEncap(
wcb->info = bpi;
wcb->node = rn;
wcb->import_table = import_table;
+ rwcb_add(&_rwcbhash, wcb);
memset(&t, 0, sizeof(t));
t.arg = wcb;
rfapiWithdrawTimerEncap(
@@ -3149,6 +3180,7 @@ static void rfapiBgpInfoFilteredImportEncap(
struct rfapi_withdraw *wcb =
EVENT_ARG(bpi->extra->vnc->vnc.import.timer);
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
EVENT_OFF(bpi->extra->vnc->vnc.import.timer);
}
@@ -3192,7 +3224,7 @@ static void rfapiBgpInfoFilteredImportEncap(
__func__, rn);
#endif
for (m = RFAPI_MONITOR_ENCAP(rn); m; m = m->next) {
- const struct prefix *p;
+ const struct prefix *pfx;
/*
* For each referenced bpi/route, copy the ENCAP route's
@@ -3220,9 +3252,9 @@ static void rfapiBgpInfoFilteredImportEncap(
* list
* per prefix.
*/
- p = agg_node_get_prefix(m->node);
+ pfx = agg_node_get_prefix(m->node);
referenced_vpn_prefix =
- agg_node_get(referenced_vpn_table, p);
+ agg_node_get(referenced_vpn_table, pfx);
assert(referenced_vpn_prefix);
for (mnext = referenced_vpn_prefix->info; mnext;
mnext = mnext->next) {
@@ -3293,6 +3325,7 @@ static void rfapiExpireVpnNow(struct rfapi_import_table *it,
wcb->node = rn;
wcb->import_table = it;
wcb->lockoffset = lockoffset;
+ rwcb_add(&_rwcbhash, wcb);
memset(&t, 0, sizeof(t));
t.arg = wcb;
rfapiWithdrawTimerVPN(&t); /* frees wcb */
@@ -3510,6 +3543,7 @@ void rfapiBgpInfoFilteredImportVPN(
struct rfapi_withdraw *wcb = EVENT_ARG(
bpi->extra->vnc->vnc.import.timer);
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
EVENT_OFF(bpi->extra->vnc->vnc.import
.timer);
@@ -3729,6 +3763,7 @@ void rfapiBgpInfoFilteredImportVPN(
struct rfapi_withdraw *wcb =
EVENT_ARG(bpi->extra->vnc->vnc.import.timer);
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW, wcb);
EVENT_OFF(bpi->extra->vnc->vnc.import.timer);
}
@@ -4480,6 +4515,7 @@ static void rfapiDeleteRemotePrefixesIt(
RFAPI_UPDATE_ITABLE_COUNT(
bpi, wcb->import_table,
afi, 1);
+ rwcb_del(&_rwcbhash, wcb);
XFREE(MTYPE_RFAPI_WITHDRAW,
wcb);
EVENT_OFF(bpi->extra->vnc->vnc
@@ -4804,3 +4840,33 @@ uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime)
else
return RFAPI_LIFETIME_INFINITE_WITHDRAW_DELAY;
}
+
+void rfapi_import_init(void)
+{
+ rwcb_init(&_rwcbhash);
+}
+
+void rfapi_import_terminate(void)
+{
+ struct rfapi_withdraw *wcb;
+ struct bgp_path_info *bpi;
+ void (*timer_service_func)(struct event *t);
+ struct event t;
+
+ vnc_zlog_debug_verbose("%s: cleaning up %zu pending timers", __func__,
+ rwcb_count(&_rwcbhash));
+
+ /*
+ * clean up memory allocations stored in pending timers
+ */
+ while ((wcb = rwcb_pop(&_rwcbhash))) {
+ bpi = wcb->info;
+ assert(wcb == EVENT_ARG(bpi->extra->vnc->vnc.import.timer));
+ EVENT_OFF(bpi->extra->vnc->vnc.import.timer);
+
+ timer_service_func = wcb->timer_service_func;
+ memset(&t, 0, sizeof(t));
+ t.arg = wcb;
+ (*timer_service_func)(&t); /* frees wcb */
+ }
+}
diff --git a/bgpd/rfapi/rfapi_import.h b/bgpd/rfapi/rfapi_import.h
index 1a37e1c2db..536b8f0525 100644
--- a/bgpd/rfapi/rfapi_import.h
+++ b/bgpd/rfapi/rfapi_import.h
@@ -225,4 +225,7 @@ extern void rfapiCountAllItRoutes(int *pALRcount, /* active local routes */
--------------------------------------------*/
extern uint32_t rfapiGetHolddownFromLifetime(uint32_t lifetime);
+extern void rfapi_import_init(void);
+extern void rfapi_import_terminate(void);
+
#endif /* QUAGGA_HGP_RFAPI_IMPORT_H */
diff --git a/bgpd/rfapi/rfapi_rib.c b/bgpd/rfapi/rfapi_rib.c
index 53e416b2ee..fe6ad50f92 100644
--- a/bgpd/rfapi/rfapi_rib.c
+++ b/bgpd/rfapi/rfapi_rib.c
@@ -18,6 +18,7 @@
#include "lib/log.h"
#include "lib/skiplist.h"
#include "lib/workqueue.h"
+#include <typesafe.h>
#include "bgpd/bgpd.h"
#include "bgpd/bgp_route.h"
@@ -40,12 +41,11 @@
#define DEBUG_PENDING_DELETE_ROUTE 0
#define DEBUG_NHL 0
#define DEBUG_RIB_SL_RD 0
-#define DEBUG_CLEANUP 0
+#define DEBUG_CLEANUP 0
/* forward decl */
#if DEBUG_NHL
-static void rfapiRibShowRibSl(void *stream, struct prefix *pfx,
- struct skiplist *sl);
+static void rfapiRibShowRibSl(void *stream, const struct prefix *pfx, struct skiplist *sl);
#endif
/*
@@ -234,9 +234,45 @@ void rfapiFreeRfapiVnOptionChain(struct rfapi_vn_option *p)
}
+/*
+ * Hash to keep track of outstanding timers so we can force them to
+ * expire at shutdown time, thus freeing their allocated memory.
+ */
+PREDECL_HASH(rrtcb);
+
+/*
+ * Timer control block for recently-deleted and expired routes
+ */
+struct rfapi_rib_tcb {
+ struct rrtcb_item tcbi;
+
+ struct rfapi_descriptor *rfd;
+ struct skiplist *sl;
+ struct rfapi_info *ri;
+ struct agg_node *rn;
+ int flags;
+#define RFAPI_RIB_TCB_FLAG_DELETED 0x00000001
+};
+
+static int _rrtcb_cmp(const struct rfapi_rib_tcb *t1, const struct rfapi_rib_tcb *t2)
+{
+ return (t1 != t2);
+}
+
+static uint32_t _rrtcb_hash(const struct rfapi_rib_tcb *t)
+{
+ return (uintptr_t)t & 0xffffffff;
+}
+
+DECLARE_HASH(rrtcb, struct rfapi_rib_tcb, tcbi, _rrtcb_cmp, _rrtcb_hash);
+static struct rrtcb_head _rrtcbhash;
+
static void rfapi_info_free(struct rfapi_info *goner)
{
if (goner) {
+#if DEBUG_CLEANUP
+ zlog_debug("%s: ri %p, timer %p", __func__, goner, goner->timer);
+#endif
if (goner->tea_options) {
rfapiFreeBgpTeaOptionChain(goner->tea_options);
goner->tea_options = NULL;
@@ -253,32 +289,19 @@ static void rfapi_info_free(struct rfapi_info *goner)
struct rfapi_rib_tcb *tcb;
tcb = EVENT_ARG(goner->timer);
+#if DEBUG_CLEANUP
+ zlog_debug("%s: ri %p, tcb %p", __func__, goner, tcb);
+#endif
EVENT_OFF(goner->timer);
+ rrtcb_del(&_rrtcbhash, tcb);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
XFREE(MTYPE_RFAPI_INFO, goner);
}
}
-/*
- * Timer control block for recently-deleted and expired routes
- */
-struct rfapi_rib_tcb {
- struct rfapi_descriptor *rfd;
- struct skiplist *sl;
- struct rfapi_info *ri;
- struct agg_node *rn;
- int flags;
-#define RFAPI_RIB_TCB_FLAG_DELETED 0x00000001
-};
-
-/*
- * remove route from rib
- */
-static void rfapiRibExpireTimer(struct event *t)
+static void _rfapiRibExpireTimer(struct rfapi_rib_tcb *tcb)
{
- struct rfapi_rib_tcb *tcb = EVENT_ARG(t);
-
RFAPI_RIB_CHECK_COUNTS(1, 0);
/*
@@ -309,11 +332,22 @@ static void rfapiRibExpireTimer(struct event *t)
agg_unlock_node(tcb->rn);
}
+ rrtcb_del(&_rrtcbhash, tcb);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
RFAPI_RIB_CHECK_COUNTS(1, 0);
}
+/*
+ * remove route from rib
+ */
+static void rfapiRibExpireTimer(struct event *t)
+{
+ struct rfapi_rib_tcb *tcb = EVENT_ARG(t);
+
+ _rfapiRibExpireTimer(tcb);
+}
+
static void rfapiRibStartTimer(struct rfapi_descriptor *rfd,
struct rfapi_info *ri,
struct agg_node *rn, /* route node attached to */
@@ -349,6 +383,8 @@ static void rfapiRibStartTimer(struct rfapi_descriptor *rfd,
event_add_timer(bm->master, rfapiRibExpireTimer, tcb, ri->lifetime,
&ri->timer);
+
+ rrtcb_add(&_rrtcbhash, tcb);
}
extern void rfapi_rib_key_init(struct prefix *prefix, /* may be NULL */
@@ -519,6 +555,7 @@ void rfapiRibClear(struct rfapi_descriptor *rfd)
tcb = EVENT_ARG(
ri->timer);
EVENT_OFF(ri->timer);
+ rrtcb_del(&_rrtcbhash, tcb);
XFREE(MTYPE_RFAPI_RECENT_DELETE,
tcb);
}
@@ -852,11 +889,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
int rib_node_started_nonempty = 0;
int sendingsomeroutes = 0;
const struct prefix *p;
-#if DEBUG_PROCESS_PENDING_NODE
- unsigned int count_rib_initial = 0;
- unsigned int count_pend_vn_initial = 0;
- unsigned int count_pend_cost_initial = 0;
-#endif
assert(pn);
p = agg_node_get_prefix(pn);
@@ -885,19 +917,6 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
slPendPt = (struct skiplist *)(pn->aggregate);
lPendCost = (struct list *)(pn->info);
-#if DEBUG_PROCESS_PENDING_NODE
- /* debugging */
- if (slRibPt)
- count_rib_initial = skiplist_count(slRibPt);
-
- if (slPendPt)
- count_pend_vn_initial = skiplist_count(slPendPt);
-
- if (lPendCost && lPendCost != (struct list *)1)
- count_pend_cost_initial = lPendCost->count;
-#endif
-
-
/*
* Handle special case: delete all routes at prefix
*/
@@ -920,6 +939,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
tcb = EVENT_ARG(ri->timer);
EVENT_OFF(ri->timer);
+ rrtcb_del(&_rrtcbhash, tcb);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
@@ -1005,6 +1025,7 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
tcb = EVENT_ARG(ori->timer);
EVENT_OFF(ori->timer);
+ rrtcb_del(&_rrtcbhash, tcb);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
@@ -1017,6 +1038,11 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
#endif
} else {
+#if DEBUG_PROCESS_PENDING_NODE
+ vnc_zlog_debug_verbose("%s: slRibPt ri %p matched in pending list",
+ __func__, ori);
+#endif
+
/*
* Found in pending list. If same lifetime,
* cost, options,
@@ -1040,14 +1066,10 @@ static void process_pending_node(struct bgp *bgp, struct rfapi_descriptor *rfd,
rfapi_info_free(
ri); /* grr... */
}
- }
#if DEBUG_PROCESS_PENDING_NODE
- vnc_zlog_debug_verbose(
- "%s: slRibPt ri %p matched in pending list, %s",
- __func__, ori,
- (same ? "same info"
- : "different info"));
+ vnc_zlog_debug_verbose("%s: same info", __func__);
#endif
+ }
}
}
/*
@@ -1339,6 +1361,7 @@ callback:
tcb = EVENT_ARG(ri->timer);
EVENT_OFF(ri->timer);
+ rrtcb_del(&_rrtcbhash, tcb);
XFREE(MTYPE_RFAPI_RECENT_DELETE, tcb);
}
RFAPI_RIB_CHECK_COUNTS(0, delete_list->count);
@@ -2285,8 +2308,7 @@ static int print_rib_sl(int (*fp)(void *, const char *, ...), struct vty *vty,
/*
* This one is for debugging (set stream to NULL to send output to log)
*/
-static void rfapiRibShowRibSl(void *stream, struct prefix *pfx,
- struct skiplist *sl)
+static void rfapiRibShowRibSl(void *stream, const struct prefix *pfx, struct skiplist *sl)
{
int (*fp)(void *, const char *, ...);
struct vty *vty;
@@ -2426,3 +2448,25 @@ void rfapiRibShowResponses(void *stream, struct prefix *pfx_match,
fp(out, "\n");
}
}
+
+void rfapi_rib_init(void)
+{
+ rrtcb_init(&_rrtcbhash);
+}
+
+void rfapi_rib_terminate(void)
+{
+ struct rfapi_rib_tcb *tcb;
+
+ vnc_zlog_debug_verbose("%s: cleaning up %zu pending timers", __func__,
+ rrtcb_count(&_rrtcbhash));
+
+ /*
+ * Clean up memory allocations stored in pending timers
+ */
+ while ((tcb = rrtcb_pop(&_rrtcbhash))) {
+ assert(tcb == EVENT_ARG(tcb->ri->timer));
+ EVENT_OFF(tcb->ri->timer);
+ _rfapiRibExpireTimer(tcb); /* deletes hash entry, frees tcb */
+ }
+}
diff --git a/bgpd/rfapi/rfapi_rib.h b/bgpd/rfapi/rfapi_rib.h
index 5fa838bd34..3e34f26fcd 100644
--- a/bgpd/rfapi/rfapi_rib.h
+++ b/bgpd/rfapi/rfapi_rib.h
@@ -138,4 +138,7 @@ extern int rfapi_rib_key_cmp(const void *k1, const void *k2);
extern void rfapiAdbFree(struct rfapi_adb *adb);
+extern void rfapi_rib_init(void);
+extern void rfapi_rib_terminate(void);
+
#endif /* QUAGGA_HGP_RFAPI_RIB_H */
diff --git a/bgpd/rfapi/vnc_import_bgp.c b/bgpd/rfapi/vnc_import_bgp.c
index e688638ed7..612caed0cf 100644
--- a/bgpd/rfapi/vnc_import_bgp.c
+++ b/bgpd/rfapi/vnc_import_bgp.c
@@ -338,13 +338,12 @@ static int process_unicast_route(struct bgp *bgp, /* in */
hattr = *attr;
if (rmap) {
- struct bgp_path_info info;
+ struct bgp_path_info pinfo = {};
route_map_result_t ret;
- memset(&info, 0, sizeof(info));
- info.peer = peer;
- info.attr = &hattr;
- ret = route_map_apply(rmap, prefix, &info);
+ pinfo.peer = peer;
+ pinfo.attr = &hattr;
+ ret = route_map_apply(rmap, prefix, &pinfo);
if (ret == RMAP_DENYMATCH) {
bgp_attr_flush(&hattr);
vnc_zlog_debug_verbose(
@@ -768,13 +767,12 @@ static void vnc_import_bgp_add_route_mode_plain(struct bgp *bgp,
hattr = *attr;
if (rmap) {
- struct bgp_path_info info;
+ struct bgp_path_info pinfo = {};
route_map_result_t ret;
- memset(&info, 0, sizeof(info));
- info.peer = peer;
- info.attr = &hattr;
- ret = route_map_apply(rmap, prefix, &info);
+ pinfo.peer = peer;
+ pinfo.attr = &hattr;
+ ret = route_map_apply(rmap, prefix, &pinfo);
if (ret == RMAP_DENYMATCH) {
bgp_attr_flush(&hattr);
vnc_zlog_debug_verbose(
diff --git a/configure.ac b/configure.ac
index f9f3286563..00a5620529 100644
--- a/configure.ac
+++ b/configure.ac
@@ -467,6 +467,7 @@ AC_C_FLAG([-Wbad-function-cast])
AC_C_FLAG([-Wwrite-strings])
AC_C_FLAG([-Wundef])
AC_C_FLAG([-Wimplicit-fallthrough])
+AC_C_FLAG([-Wshadow])
if test "$enable_gcc_ultra_verbose" = "yes" ; then
AC_C_FLAG([-Wcast-qual])
AC_C_FLAG([-Wmissing-noreturn])
@@ -474,7 +475,6 @@ if test "$enable_gcc_ultra_verbose" = "yes" ; then
AC_C_FLAG([-Wunreachable-code])
AC_C_FLAG([-Wpacked])
AC_C_FLAG([-Wpadded])
- AC_C_FLAG([-Wshadow])
else
AC_C_FLAG([-Wno-unused-result])
fi
diff --git a/doc/developer/mgmtd-dev.rst b/doc/developer/mgmtd-dev.rst
index f113d1b521..554f767c39 100644
--- a/doc/developer/mgmtd-dev.rst
+++ b/doc/developer/mgmtd-dev.rst
@@ -429,3 +429,8 @@ The client and server sides of oper-state query
.. figure:: ../figures/cli-oper-state.svg
:align: center
+
+Config datastore cleanup for non-implict commits (i.e., file reads currently)
+
+.. figure:: ../figures/datastores.svg
+ :align: center
diff --git a/doc/figures/datastores.drawio b/doc/figures/datastores.drawio
new file mode 100644
index 0000000000..5e17087196
--- /dev/null
+++ b/doc/figures/datastores.drawio
@@ -0,0 +1,291 @@
+<mxfile host="Electron" agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
+ <diagram name="Page-1" id="i24xzCYeKZV1rkTH0XTW">
+ <mxGraphModel dx="1667" dy="1191" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1100" pageHeight="850" math="0" shadow="0">
+ <root>
+ <mxCell id="0" />
+ <mxCell id="1" parent="0" />
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-36" value="nb_candidate_commit_apply()" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;verticalAlign=top;" vertex="1" parent="1">
+ <mxGeometry x="890" y="670" width="180" height="136.87" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-29" value="&lt;i&gt;&lt;font style=&quot;font-size: 16px;&quot;&gt;Daemon CLI Parsing (lib/vty.c)&lt;/font&gt;&lt;/i&gt;" style="rounded=1;whiteSpace=wrap;html=1;dashed=1;fillColor=#dae8fc;strokeColor=default;fillStyle=solid;strokeWidth=1;perimeterSpacing=0;dashPattern=1 2;gradientColor=none;gradientDirection=radial;glass=0;shadow=0;opacity=50;verticalAlign=bottom;spacingBottom=30;" parent="1" vertex="1">
+ <mxGeometry x="50" y="220" width="660" height="170" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-7" value="&lt;div style=&quot;font-size: 12px;&quot;&gt;mgmtd&lt;/div&gt;&lt;div style=&quot;font-size: 12px;&quot;&gt;(new config path)&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;arcSize=24;fillColor=#dae8fc;strokeColor=#6c8ebf;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1" parent="1" vertex="1">
+ <mxGeometry x="230" y="40" width="490" height="270" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-13" value="&lt;div&gt;&lt;font&gt;vty_shared_&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font&gt;candidate_config&lt;/font&gt;&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
+ <mxGeometry x="136.25" y="70" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-14" value="&lt;div&gt;running_config&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+ <mxGeometry x="260" y="70" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-18" value="" style="group;shadow=0;" parent="1" vertex="1" connectable="0">
+ <mxGeometry x="80" y="60" width="270" height="210" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-19" value="&lt;div style=&quot;font-size: 12px;&quot;&gt;B daemon&amp;nbsp;&lt;span style=&quot;background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));&quot;&gt;(old direct vty)&lt;/span&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;arcSize=24;fillColor=#fad9d5;strokeColor=#ae4132;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1" parent="QL32OzfzetEIIOdSfswY-18" vertex="1">
+ <mxGeometry x="-10" width="270" height="190" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-20" value="&lt;div&gt;&lt;font&gt;vty_shared_&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font&gt;candidate_config&lt;/font&gt;&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="QL32OzfzetEIIOdSfswY-18" vertex="1">
+ <mxGeometry x="20" y="30" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-21" value="&lt;div&gt;running_config&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="QL32OzfzetEIIOdSfswY-18" vertex="1">
+ <mxGeometry x="150" y="30" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-23" value="&lt;div style=&quot;font-size: 12px;&quot;&gt;A daemon (old direct vty)&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;arcSize=24;fillColor=#fad9d5;strokeColor=#ae4132;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1" parent="QL32OzfzetEIIOdSfswY-18" vertex="1">
+ <mxGeometry x="-40" y="20" width="270" height="190" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-25" value="&lt;div&gt;running_config&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" parent="1" vertex="1">
+ <mxGeometry x="200" y="110" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="4hLhriEXD62TuEoW85Ij-1" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="648.75" y="160" as="sourcePoint" />
+ <mxPoint x="487.5" y="585" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="790" y="160" />
+ <mxPoint x="790" y="530" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-8" value="&lt;div&gt;&lt;font&gt;vty_mgmt_&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font&gt;candidate_config&lt;/font&gt;&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
+ <mxGeometry x="551.25" y="70" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-26" value="mm-&amp;gt;running" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="370" y="230" width="120" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-14" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="QL32OzfzetEIIOdSfswY-27" target="QL32OzfzetEIIOdSfswY-26">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-27" value="mm-&amp;gt;candidate" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
+ <mxGeometry x="540" y="230" width="120" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-1" value="vty_config_entry()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fillStyle=auto;strokeWidth=3;" parent="1" vertex="1">
+ <mxGeometry x="315" y="500" width="130" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-3" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" source="QL32OzfzetEIIOdSfswY-24" target="4hLhriEXD62TuEoW85Ij-1" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="120" y="260" as="sourcePoint" />
+ <mxPoint x="320" y="600" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="120" y="530" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-24" value="&lt;div&gt;&lt;font&gt;vty_shared_&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font&gt;candidate_config&lt;/font&gt;&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
+ <mxGeometry x="70" y="110" width="97.5" height="130" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-8" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-4" target="4hLhriEXD62TuEoW85Ij-7" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-4" value="CLI: config_exclusive()&lt;div&gt;(northbound_cli.c)&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1">
+ <mxGeometry x="910" y="40" width="140" height="50" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-5" value="CLI: config_private()&lt;div&gt;(northbound_cli.c)&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1">
+ <mxGeometry x="760" y="45" width="140" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-6" value="vty_config_entry()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fillStyle=auto;strokeWidth=3;" parent="1" vertex="1">
+ <mxGeometry x="860" y="230" width="120" height="60" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-10" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-7" target="4hLhriEXD62TuEoW85Ij-6" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-7" value="&lt;div&gt;private_config&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" parent="1" vertex="1">
+ <mxGeometry x="871.25" y="130" width="97.5" height="70" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-9" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-5" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="910" y="130" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="850" y="110" />
+ <mxPoint x="911" y="110" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-15" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" parent="1" source="4hLhriEXD62TuEoW85Ij-11" target="4hLhriEXD62TuEoW85Ij-1" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-20" value="2" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-11" target="4hLhriEXD62TuEoW85Ij-1" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-16" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;startArrow=classic;startFill=1;strokeWidth=2;" edge="1" parent="1" source="4hLhriEXD62TuEoW85Ij-11" target="U9ftda_CDvz5WDsUi4ve-15">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-17" value="1" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-16">
+ <mxGeometry x="0.0305" y="2" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-19" value="1: (mgmtd only)" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-16">
+ <mxGeometry x="0.0074" y="1" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-11" value="CLI: config_terminal()&lt;div&gt;(command.c)&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d0cee2;strokeColor=#56517e;" parent="1" vertex="1">
+ <mxGeometry x="315" y="420" width="130" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-31" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-29" target="4hLhriEXD62TuEoW85Ij-11" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-27" value="&lt;div style=&quot;font-size: 12px;&quot;&gt;&lt;br&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;arcSize=12;fillColor=#dae8fc;strokeColor=#6c8ebf;shadow=1;comic=0;labelBackgroundColor=none;fontFamily=Verdana;fontSize=12;align=center;verticalAlign=top;fontStyle=1;container=0;" parent="1" vertex="1">
+ <mxGeometry x="50" y="600" width="550" height="190" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-18" value="vty_read_config()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
+ <mxGeometry x="260" y="670" width="130" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-21" value="vty_apply_config()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
+ <mxGeometry x="260" y="730" width="130" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-22" value="&lt;b&gt;&lt;i&gt;&quot;copy FILE to rrunning&quot;&lt;/i&gt;&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
+ <mxGeometry x="63.75" y="730" width="150" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-23" value="&lt;b&gt;&lt;i&gt;vtysh_main.c: main()&lt;/i&gt;&lt;/b&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
+ <mxGeometry x="430" y="730" width="150" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-19" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-18" target="4hLhriEXD62TuEoW85Ij-16" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-26" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-21" target="4hLhriEXD62TuEoW85Ij-18" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-25" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-22" target="4hLhriEXD62TuEoW85Ij-21" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-24" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-23" target="4hLhriEXD62TuEoW85Ij-21" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-34" value="VTYSH" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=default;fontColor=#333333;opacity=50;dashed=1;dashPattern=8 8;" parent="1" vertex="1">
+ <mxGeometry x="500" y="610" width="90" height="30" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-12" value="" style="curved=0;endArrow=none;html=1;rounded=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;exitX=0.25;exitY=1;exitDx=0;exitDy=0;dashed=1;startFill=0;" edge="1" parent="1">
+ <mxGeometry width="50" height="50" relative="1" as="geometry">
+ <mxPoint x="215" y="400" as="sourcePoint" />
+ <mxPoint x="380" y="400" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="215" y="370" />
+ <mxPoint x="380" y="370" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-16" value="vty_read_file()&lt;div&gt;&lt;b&gt;&lt;i&gt;&quot;conf term file-lock&quot;&lt;/i&gt;&lt;/b&gt;&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" parent="1" vertex="1">
+ <mxGeometry x="260" y="610" width="130" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="4hLhriEXD62TuEoW85Ij-17" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;jumpStyle=line;exitX=0.5;exitY=0;exitDx=0;exitDy=0;shadow=1;" parent="1" source="4hLhriEXD62TuEoW85Ij-16" edge="1">
+ <mxGeometry relative="1" as="geometry">
+ <Array as="points">
+ <mxPoint x="325" y="580" />
+ <mxPoint x="215" y="580" />
+ </Array>
+ <mxPoint x="395" y="670" as="sourcePoint" />
+ <mxPoint x="215" y="390" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-28" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;startArrow=classic;startFill=1;endArrow=oval;endFill=1;" parent="1" source="QL32OzfzetEIIOdSfswY-14" target="QL32OzfzetEIIOdSfswY-26" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="QL32OzfzetEIIOdSfswY-29" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=oval;startFill=1;startArrow=classic;endFill=1;" parent="1" source="QL32OzfzetEIIOdSfswY-8" target="QL32OzfzetEIIOdSfswY-27" edge="1">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-15" value="&lt;div&gt;lock mm-&amp;gt;candidate&lt;/div&gt;" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;" vertex="1" parent="1">
+ <mxGeometry x="580" y="420" width="130" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-20" value="If we don&#39;t lock for non-mgmtd then&lt;div&gt;multiple vtysh conf t are allowed!&lt;/div&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;fontStyle=3;fontColor=#FF0000;" vertex="1" parent="1">
+ <mxGeometry x="425" y="463" width="210" height="40" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-24" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-21" target="U9ftda_CDvz5WDsUi4ve-23">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-21" value="vty_config_node_exit()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=#b85450;fillStyle=auto;strokeWidth=3;" vertex="1" parent="1">
+ <mxGeometry x="830" y="340" width="180" height="45" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-26" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-23" target="U9ftda_CDvz5WDsUi4ve-25">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-29" value="pendign == true" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-26">
+ <mxGeometry x="-0.0182" y="-3" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-23" value="&lt;div&gt;&amp;nbsp; &amp;nbsp;nb_cli_pending_commit_check()&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1">
+ <mxGeometry x="830" y="420" width="180" height="35" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-28" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" target="U9ftda_CDvz5WDsUi4ve-27">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="920" y="570" as="sourcePoint" />
+ <Array as="points">
+ <mxPoint x="920" y="569" />
+ <mxPoint x="920" y="596" />
+ <mxPoint x="910" y="596" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-35" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-27" target="U9ftda_CDvz5WDsUi4ve-36">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="920" y="574.37" as="sourcePoint" />
+ <mxPoint x="1000" y="610.0000000000001" as="targetPoint" />
+ <Array as="points">
+ <mxPoint x="960" y="635" />
+ <mxPoint x="980" y="635" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-47" value="success" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-35">
+ <mxGeometry x="-0.275" y="1" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-51" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-25" target="U9ftda_CDvz5WDsUi4ve-27">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-25" value="nb_cli_classic_commit()" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1">
+ <mxGeometry x="830" y="500" width="180" height="37.5" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-31" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-27" target="U9ftda_CDvz5WDsUi4ve-30">
+ <mxGeometry relative="1" as="geometry">
+ <Array as="points">
+ <mxPoint x="880" y="635" />
+ <mxPoint x="781" y="635" />
+ </Array>
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-32" value="fail" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="U9ftda_CDvz5WDsUi4ve-31">
+ <mxGeometry x="-0.055" y="-3" relative="1" as="geometry">
+ <mxPoint as="offset" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-27" value="nb_candidate_commit_prepare()" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1">
+ <mxGeometry x="830" y="566.25" width="180" height="33.75" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-30" value="" style="whiteSpace=wrap;html=1;fillColor=#e1d5e7;strokeColor=#9673a6;rounded=1;fillStyle=auto;strokeWidth=1;" vertex="1" parent="1">
+ <mxGeometry x="691.25" y="670.01" width="180" height="99.99" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-40" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-38" target="U9ftda_CDvz5WDsUi4ve-39">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-38" value="&lt;div&gt;running&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
+ <mxGeometry x="706.25" y="685" width="50" height="70" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-39" value="&lt;div&gt;private or&lt;/div&gt;&lt;div&gt;candidate&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
+ <mxGeometry x="796.25" y="685" width="60" height="70" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-42" value="&lt;div&gt;running&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#d5e8d4;strokeColor=#82b366;" vertex="1" parent="1">
+ <mxGeometry x="990" y="715" width="50" height="70" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-41" value="&lt;div&gt;private or&lt;/div&gt;&lt;div&gt;candidate&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;" style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;align=center;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
+ <mxGeometry x="900" y="715" width="65" height="70" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-44" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-36" target="U9ftda_CDvz5WDsUi4ve-36">
+ <mxGeometry relative="1" as="geometry" />
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-48" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="U9ftda_CDvz5WDsUi4ve-41" target="U9ftda_CDvz5WDsUi4ve-42">
+ <mxGeometry relative="1" as="geometry">
+ <mxPoint x="960" y="705" as="sourcePoint" />
+ <mxPoint x="990" y="705" as="targetPoint" />
+ </mxGeometry>
+ </mxCell>
+ <mxCell id="U9ftda_CDvz5WDsUi4ve-52" value="&lt;b&gt;&lt;font style=&quot;font-size: 15px;&quot;&gt;Config Datastore Non-Implicit Commit Cleanup&lt;/font&gt;&lt;/b&gt;" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
+ <mxGeometry x="400" y="10" width="360" height="30" as="geometry" />
+ </mxCell>
+ </root>
+ </mxGraphModel>
+ </diagram>
+</mxfile>
diff --git a/doc/figures/datastores.svg b/doc/figures/datastores.svg
new file mode 100644
index 0000000000..41f612fc68
--- /dev/null
+++ b/doc/figures/datastores.svg
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent; color-scheme: light dark;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="1035px" height="806px" viewBox="-0.5 -0.5 1035 806"><defs/><g><g data-cell-id="0"><g data-cell-id="1"><g data-cell-id="U9ftda_CDvz5WDsUi4ve-36"><g><rect x="854" y="660" width="180" height="136.87" rx="20.53" ry="20.53" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 667px; margin-left: 855px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nb_candidate_commit_apply()</div></div></div></foreignObject><text x="944" y="679" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">nb_candidate_commit_apply()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-29"><g><rect x="14" y="210" width="660" height="170" rx="25.5" ry="25.5" fill-opacity="0.5" fill="#dae8fc" stroke="#000000" stroke-opacity="0.5" stroke-dasharray="1 2" pointer-events="all" style="fill: rgb(218, 232, 252); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe center; width: 658px; height: 1px; padding-top: 347px; margin-left: 15px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><i><font style="font-size: 16px;">Daemon CLI Parsing (lib/vty.c)</font></i></div></div></div></foreignObject><text x="344" y="347" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Daemon CLI Parsing (lib/vty.c)</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-7"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="194" y="30" width="490" height="270" rx="64.8" ry="64.8" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all" style="fill: rgb(218, 232, 252); stroke: rgb(108, 142, 191);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 488px; height: 1px; padding-top: 37px; margin-left: 195px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Verdana&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;">mgmtd</div><div style="font-size: 12px;">(new config path)</div></div></div></div></foreignObject><text x="439" y="49" fill="light-dark(#000000, #ffffff)" font-family="&quot;Verdana&quot;" font-size="12px" text-anchor="middle" font-weight="bold">mgmtd...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-13"><g><path d="M 100.25 75 C 100.25 66.72 122.08 60 149 60 C 161.93 60 174.33 61.58 183.47 64.39 C 192.61 67.21 197.75 71.02 197.75 75 L 197.75 175 C 197.75 183.28 175.92 190 149 190 C 122.08 190 100.25 183.28 100.25 175 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 197.75 75 C 197.75 83.28 175.92 90 149 90 C 122.08 90 100.25 83.28 100.25 75" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 138px; margin-left: 101px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_shared_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="149" y="141" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_shared_...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-14"><g><path d="M 224 75 C 224 66.72 245.83 60 272.75 60 C 285.68 60 298.08 61.58 307.22 64.39 C 316.36 67.21 321.5 71.02 321.5 75 L 321.5 175 C 321.5 183.28 299.67 190 272.75 190 C 245.83 190 224 183.28 224 175 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 321.5 75 C 321.5 83.28 299.67 90 272.75 90 C 245.83 90 224 83.28 224 75" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 138px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running_config</div></div></div></div></foreignObject><text x="273" y="141" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">running_config</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-18"><g/><g data-cell-id="QL32OzfzetEIIOdSfswY-19"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="34" y="50" width="270" height="190" rx="45.6" ry="45.6" fill="#fad9d5" stroke="#ae4132" pointer-events="all" style="fill: rgb(250, 217, 213); stroke: rgb(174, 65, 50);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 57px; margin-left: 35px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Verdana&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;">B daemon <span style="background-color: transparent; color: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));">(old direct vty)</span></div></div></div></div></foreignObject><text x="169" y="69" fill="light-dark(#000000, #ffffff)" font-family="&quot;Verdana&quot;" font-size="12px" text-anchor="middle" font-weight="bold">B daemon (old direct vty)</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-20"><g><path d="M 64 95 C 64 86.72 85.83 80 112.75 80 C 125.68 80 138.08 81.58 147.22 84.39 C 156.36 87.21 161.5 91.02 161.5 95 L 161.5 195 C 161.5 203.28 139.67 210 112.75 210 C 85.83 210 64 203.28 64 195 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 161.5 95 C 161.5 103.28 139.67 110 112.75 110 C 85.83 110 64 103.28 64 95" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 158px; margin-left: 65px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_shared_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="113" y="161" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_shared_...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-21"><g><path d="M 194 95 C 194 86.72 215.83 80 242.75 80 C 255.68 80 268.08 81.58 277.22 84.39 C 286.36 87.21 291.5 91.02 291.5 95 L 291.5 195 C 291.5 203.28 269.67 210 242.75 210 C 215.83 210 194 203.28 194 195 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 291.5 95 C 291.5 103.28 269.67 110 242.75 110 C 215.83 110 194 103.28 194 95" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 158px; margin-left: 195px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running_config</div></div></div></div></foreignObject><text x="243" y="161" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">running_config</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-23"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="4" y="70" width="270" height="190" rx="45.6" ry="45.6" fill="#fad9d5" stroke="#ae4132" pointer-events="all" style="fill: rgb(250, 217, 213); stroke: rgb(174, 65, 50);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 268px; height: 1px; padding-top: 77px; margin-left: 5px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Verdana&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;">A daemon (old direct vty)</div></div></div></div></foreignObject><text x="139" y="89" fill="light-dark(#000000, #ffffff)" font-family="&quot;Verdana&quot;" font-size="12px" text-anchor="middle" font-weight="bold">A daemon (old direct vty)</text></switch></g></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-25"><g><path d="M 164 115 C 164 106.72 185.83 100 212.75 100 C 225.68 100 238.08 101.58 247.22 104.39 C 256.36 107.21 261.5 111.02 261.5 115 L 261.5 215 C 261.5 223.28 239.67 230 212.75 230 C 185.83 230 164 223.28 164 215 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 261.5 115 C 261.5 123.28 239.67 130 212.75 130 C 185.83 130 164 123.28 164 115" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 178px; margin-left: 165px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running_config</div></div></div></div></foreignObject><text x="213" y="181" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">running_config</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-2"><g><path d="M 612.75 150 L 754 150 L 754 520 L 415.37 520" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 410.12 520 L 417.12 516.5 L 415.37 520 L 417.12 523.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-8"><g><path d="M 515.25 75 C 515.25 66.72 537.08 60 564 60 C 576.93 60 589.33 61.58 598.47 64.39 C 607.61 67.21 612.75 71.02 612.75 75 L 612.75 175 C 612.75 183.28 590.92 190 564 190 C 537.08 190 515.25 183.28 515.25 175 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 612.75 75 C 612.75 83.28 590.92 90 564 90 C 537.08 90 515.25 83.28 515.25 75" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 138px; margin-left: 516px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_mgmt_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="564" y="141" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_mgmt_...</text></switch></g></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-26"><g><rect x="334" y="220" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 250px; margin-left: 335px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">mm-&gt;running</div></div></div></foreignObject><text x="394" y="254" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">mm-&gt;running</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-14"><g><path d="M 504 250 L 460.37 250" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 455.12 250 L 462.12 246.5 L 460.37 250 L 462.12 253.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-27"><g><rect x="504" y="220" width="120" height="60" fill="#ffffff" stroke="#000000" pointer-events="all" style="fill: light-dark(#ffffff, var(--ge-dark-color, #121212)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 250px; margin-left: 505px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">mm-&gt;candidate</div></div></div></foreignObject><text x="564" y="254" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">mm-&gt;candidate</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-1"><g><rect x="279" y="490" width="130" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" stroke-width="3" pointer-events="all" style="fill: rgb(248, 206, 204); stroke: rgb(184, 84, 80);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 520px; margin-left: 280px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_config_entry()</div></div></div></foreignObject><text x="344" y="524" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_config_entry()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-3"><g><path d="M 84 230 L 84 520 L 272.63 520" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 277.88 520 L 270.88 523.5 L 272.63 520 L 270.88 516.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-24"><g><path d="M 34 115 C 34 106.72 55.83 100 82.75 100 C 95.68 100 108.08 101.58 117.22 104.39 C 126.36 107.21 131.5 111.02 131.5 115 L 131.5 215 C 131.5 223.28 109.67 230 82.75 230 C 55.83 230 34 223.28 34 215 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 131.5 115 C 131.5 123.28 109.67 130 82.75 130 C 55.83 130 34 123.28 34 115" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 178px; margin-left: 35px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div><font>vty_shared_</font></div><div><font>candidate_config</font></div></div></div></div></foreignObject><text x="83" y="181" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_shared_...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-8"><g><path d="M 944 80 L 944 100 L 884.1 100 L 884.1 113.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884.1 118.88 L 880.6 111.88 L 884.1 113.63 L 887.6 111.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-4"><g><rect x="874" y="30" width="140" height="50" rx="7.5" ry="7.5" fill="#d0cee2" stroke="#56517e" pointer-events="all" style="fill: rgb(208, 206, 226); stroke: rgb(86, 81, 126);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 55px; margin-left: 875px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">CLI: config_exclusive()<div>(northbound_cli.c)</div></div></div></div></foreignObject><text x="944" y="59" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">CLI: config_exclusive()...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-5"><g><rect x="724" y="35" width="140" height="40" rx="6" ry="6" fill="#d0cee2" stroke="#56517e" pointer-events="all" style="fill: rgb(208, 206, 226); stroke: rgb(86, 81, 126);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 138px; height: 1px; padding-top: 55px; margin-left: 725px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">CLI: config_private()<div>(northbound_cli.c)</div></div></div></div></foreignObject><text x="794" y="59" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">CLI: config_private()...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-6"><g><rect x="824" y="220" width="120" height="60" rx="9" ry="9" fill="#f8cecc" stroke="#b85450" stroke-width="3" pointer-events="all" style="fill: rgb(248, 206, 204); stroke: rgb(184, 84, 80);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 250px; margin-left: 825px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_config_entry()</div></div></div></foreignObject><text x="884" y="254" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_config_entry()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-10"><g><path d="M 884.1 190 L 884.1 210 L 884.06 213.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884.01 218.88 L 880.58 211.85 L 884.06 213.63 L 887.58 211.92 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-7"><g><path d="M 835.25 135 C 835.25 126.72 857.08 120 884 120 C 896.93 120 909.33 121.58 918.47 124.39 C 927.61 127.21 932.75 131.02 932.75 135 L 932.75 175 C 932.75 183.28 910.92 190 884 190 C 857.08 190 835.25 183.28 835.25 175 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 932.75 135 C 932.75 143.28 910.92 150 884 150 C 857.08 150 835.25 143.28 835.25 135" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 96px; height: 1px; padding-top: 168px; margin-left: 836px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>private_config</div></div></div></div></foreignObject><text x="884" y="171" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">private_config</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-9"><g><path d="M 814 75 L 814 100 L 875 100 L 874.32 113.64" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 874.06 118.88 L 870.91 111.72 L 874.32 113.64 L 877.9 112.07 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-15"><g><path d="M 344 450 L 344 483.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 344 488.88 L 340.5 481.88 L 344 483.63 L 347.5 481.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-20"><g><path d="M 344 450 L 344 483.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 344 488.88 L 340.5 481.88 L 344 483.63 L 347.5 481.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 470px; margin-left: 344px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">2</div></div></div></foreignObject><text x="344" y="473" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="11px" text-anchor="middle">2</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-16"><g><path d="M 417.24 430 L 535.76 430" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 411.24 430 L 419.24 426 L 417.24 430 L 419.24 434 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 541.76 430 L 533.76 434 L 535.76 430 L 533.76 426 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-17"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 429px; margin-left: 480px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">1</div></div></div></foreignObject><text x="480" y="432" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="11px" text-anchor="middle">1</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-19"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 430px; margin-left: 478px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">1: (mgmtd only)</div></div></div></foreignObject><text x="478" y="433" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="11px" text-anchor="middle">1: (mgmtd only)</text></switch></g></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-11"><g><rect x="279" y="410" width="130" height="40" rx="6" ry="6" fill="#d0cee2" stroke="#56517e" pointer-events="all" style="fill: rgb(208, 206, 226); stroke: rgb(86, 81, 126);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 430px; margin-left: 280px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">CLI: config_terminal()<div>(command.c)</div></div></div></div></foreignObject><text x="344" y="434" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">CLI: config_terminal(...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-31"><g><path d="M 344 380 L 344 400 L 344 390 L 344 403.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 344 408.88 L 340.5 401.88 L 344 403.63 L 347.5 401.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-27"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><rect x="14" y="590" width="550" height="190" rx="22.8" ry="22.8" fill="#dae8fc" stroke="#6c8ebf" pointer-events="all" style="fill: rgb(218, 232, 252); stroke: rgb(108, 142, 191);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 548px; height: 1px; padding-top: 597px; margin-left: 15px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Verdana&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; "><div style="font-size: 12px;"><br /></div></div></div></div></foreignObject><text x="289" y="609" fill="light-dark(#000000, #ffffff)" font-family="&quot;Verdana&quot;" font-size="12px" text-anchor="middle" font-weight="bold">&#xa;</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-18"><g><rect x="224" y="660" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 680px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_read_config()</div></div></div></foreignObject><text x="289" y="684" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_read_config()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-21"><g><rect x="224" y="720" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 740px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_apply_config()</div></div></div></foreignObject><text x="289" y="744" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_apply_config()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-22"><g><rect x="27.75" y="720" width="150" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 148px; height: 1px; padding-top: 740px; margin-left: 29px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b><i>"copy FILE to rrunning"</i></b></div></div></div></foreignObject><text x="103" y="744" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">"copy FILE to rrunning"</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-23"><g><rect x="394" y="720" width="150" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 148px; height: 1px; padding-top: 740px; margin-left: 395px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><b><i>vtysh_main.c: main()</i></b></div></div></div></foreignObject><text x="469" y="744" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vtysh_main.c: main()</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-19"><g><path d="M 289 660 L 289 640 L 289 660 L 289 646.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 289 641.12 L 292.5 648.12 L 289 646.37 L 285.5 648.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-26"><g><path d="M 289 720 L 289 700 L 289 720 L 289 706.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 289 701.12 L 292.5 708.12 L 289 706.37 L 285.5 708.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-25"><g><path d="M 177.75 740 L 217.63 740" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 222.88 740 L 215.88 743.5 L 217.63 740 L 215.88 736.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-24"><g><path d="M 394 740 L 360.37 740" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 355.12 740 L 362.12 736.5 L 360.37 740 L 362.12 743.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-34"><g><rect x="464" y="600" width="90" height="30" rx="4.5" ry="4.5" fill-opacity="0.5" fill="#f5f5f5" stroke="#000000" stroke-opacity="0.5" stroke-dasharray="8 8" pointer-events="all" style="fill: rgb(245, 245, 245); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 615px; margin-left: 465px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #333333; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: #333333; line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">VTYSH</div></div></div></foreignObject><text x="509" y="619" fill="#333333" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">VTYSH</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-12"><g><path d="M 179 390 L 179 360 L 344 360 L 344 390" fill="none" stroke="#000000" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-16"><g><rect x="224" y="600" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 620px; margin-left: 225px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_read_file()<div><b><i>"conf term file-lock"</i></b></div></div></div></div></foreignObject><text x="289" y="624" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_read_file()...</text></switch></g></g></g><g data-cell-id="4hLhriEXD62TuEoW85Ij-17"><g style="filter: drop-shadow(light-dark(rgba(0, 0, 0, 0.25), rgba(237, 237, 237, 0.25)) 2px 3px 2px);"><path d="M 289 600 L 289 570 L 179 570 L 179 523 M 176 523 L 182 523 M 182 517 L 176 517 M 179 517 L 179 517 L 179 386.37" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 179 381.12 L 182.5 388.12 L 179 386.37 L 175.5 388.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-28"><g><path d="M 327.87 125 L 394 125 L 394 217" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 322.62 125 L 329.62 121.5 L 327.87 125 L 329.62 128.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><ellipse cx="394" cy="220" rx="3" ry="3" fill="#000000" stroke="#000000" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="QL32OzfzetEIIOdSfswY-29"><g><path d="M 564.1 196.37 L 564.1 210 L 564.03 217" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 564.1 191.12 L 567.6 198.12 L 564.1 196.37 L 560.6 198.12 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><ellipse cx="564" cy="220" rx="3" ry="3" fill="#000000" stroke="#000000" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-15"><g><rect x="544" y="410" width="130" height="40" rx="6" ry="6" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 430px; margin-left: 545px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>lock mm-&gt;candidate</div></div></div></div></foreignObject><text x="609" y="434" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">lock mm-&gt;candidate</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-20"><g><rect x="389" y="453" width="210" height="40" fill="none" stroke="none" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 473px; margin-left: 494px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #FF0000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: #FF0000; line-height: 1.2; pointer-events: all; font-weight: bold; font-style: italic; white-space: nowrap; ">If we don't lock for non-mgmtd then<div>multiple vtysh conf t are allowed!</div></div></div></div></foreignObject><text x="494" y="477" fill="#FF0000" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle" font-weight="bold" font-style="italic">If we don't lock for non-mgmtd then...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-24"><g><path d="M 884 375 L 884 395 L 884 390 L 884 403.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 408.88 L 880.5 401.88 L 884 403.63 L 887.5 401.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-21"><g><rect x="794" y="330" width="180" height="45" rx="6.75" ry="6.75" fill="#f8cecc" stroke="#b85450" stroke-width="3" pointer-events="all" style="fill: rgb(248, 206, 204); stroke: rgb(184, 84, 80);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 353px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">vty_config_node_exit()</div></div></div></foreignObject><text x="884" y="356" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">vty_config_node_exit()</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-26"><g><path d="M 884 445 L 884 483.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 488.88 L 880.5 481.88 L 884 483.63 L 887.5 481.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-29"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 468px; margin-left: 882px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">pendign == true</div></div></div></foreignObject><text x="882" y="471" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="11px" text-anchor="middle">pendign == true</text></switch></g></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-23"><g><rect x="794" y="410" width="180" height="35" rx="5.25" ry="5.25" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 428px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>   nb_cli_pending_commit_check()</div><div><br /></div></div></div></div></foreignObject><text x="884" y="431" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">nb_cli_pending_commit_check...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-28"><g><path d="M 884 560 L 884 562.62" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 557.37 L 887.5 564.37 L 884 562.62 L 880.5 564.37 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-35"><g><path d="M 924 590 L 924 625 L 944 625 L 944 653.63" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 944 658.88 L 940.5 651.88 L 944 653.63 L 947.5 651.88 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-47"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 624px; margin-left: 926px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">success</div></div></div></foreignObject><text x="926" y="627" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="11px" text-anchor="middle">success</text></switch></g></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-51"><g><path d="M 884 527.5 L 884 547.5 L 884 536.3 L 884 549.88" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 884 555.13 L 880.5 548.13 L 884 549.88 L 887.5 548.13 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-25"><g><rect x="794" y="490" width="180" height="37.5" rx="5.63" ry="5.63" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 509px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nb_cli_classic_commit()</div></div></div></foreignObject><text x="884" y="512" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">nb_cli_classic_commit()</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-31"><g><path d="M 844 590 L 844 625 L 745 625 L 745 653.64" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 745 658.89 L 741.5 651.89 L 745 653.64 L 748.5 651.89 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-32"><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 623px; margin-left: 800px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; background-color: #ffffff; "><div style="display: inline-block; font-size: 11px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; background-color: light-dark(#ffffff, var(--ge-dark-color, #121212)); white-space: nowrap; ">fail</div></div></div></foreignObject><text x="800" y="626" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="11px" text-anchor="middle">fail</text></switch></g></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-27"><g><rect x="794" y="556.25" width="180" height="33.75" rx="5.06" ry="5.06" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 178px; height: 1px; padding-top: 573px; margin-left: 795px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; ">nb_candidate_commit_prepare()</div></div></div></foreignObject><text x="884" y="577" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">nb_candidate_commit_prepare()</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-30"><g><rect x="655.25" y="660.01" width="180" height="99.99" rx="15" ry="15" fill="#e1d5e7" stroke="#9673a6" pointer-events="all" style="fill: rgb(225, 213, 231); stroke: rgb(150, 115, 166);"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-40"><g><path d="M 720.25 710 L 753.88 710" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 759.13 710 L 752.13 713.5 L 753.88 710 L 752.13 706.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-38"><g><path d="M 670.25 690 C 670.25 681.72 681.44 675 695.25 675 C 701.88 675 708.24 676.58 712.93 679.39 C 717.62 682.21 720.25 686.02 720.25 690 L 720.25 730 C 720.25 738.28 709.06 745 695.25 745 C 681.44 745 670.25 738.28 670.25 730 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 720.25 690 C 720.25 698.28 709.06 705 695.25 705 C 681.44 705 670.25 698.28 670.25 690" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 48px; height: 1px; padding-top: 723px; margin-left: 671px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running</div></div></div></div></foreignObject><text x="695" y="726" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">running</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-39"><g><path d="M 760.25 690 C 760.25 681.72 773.68 675 790.25 675 C 798.21 675 805.84 676.58 811.46 679.39 C 817.09 682.21 820.25 686.02 820.25 690 L 820.25 730 C 820.25 738.28 806.82 745 790.25 745 C 773.68 745 760.25 738.28 760.25 730 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 820.25 690 C 820.25 698.28 806.82 705 790.25 705 C 773.68 705 760.25 698.28 760.25 690" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 58px; height: 1px; padding-top: 723px; margin-left: 761px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>private or</div><div>candidate</div><div><br /></div></div></div></div></foreignObject><text x="790" y="726" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">private or...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-42"><g><path d="M 954 720 C 954 711.72 965.19 705 979 705 C 985.63 705 991.99 706.58 996.68 709.39 C 1001.37 712.21 1004 716.02 1004 720 L 1004 760 C 1004 768.28 992.81 775 979 775 C 965.19 775 954 768.28 954 760 Z" fill="#d5e8d4" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(213, 232, 212); stroke: rgb(130, 179, 102);"/><path d="M 1004 720 C 1004 728.28 992.81 735 979 735 C 965.19 735 954 728.28 954 720" fill="none" stroke="#82b366" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(130, 179, 102);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 48px; height: 1px; padding-top: 753px; margin-left: 955px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>running</div></div></div></div></foreignObject><text x="979" y="756" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">running</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-41"><g><path d="M 864 720 C 864 711.72 878.55 705 896.5 705 C 905.12 705 913.39 706.58 919.48 709.39 C 925.58 712.21 929 716.02 929 720 L 929 760 C 929 768.28 914.45 775 896.5 775 C 878.55 775 864 768.28 864 760 Z" fill="#fff2cc" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="fill: rgb(255, 242, 204); stroke: rgb(214, 182, 86);"/><path d="M 929 720 C 929 728.28 914.45 735 896.5 735 C 878.55 735 864 728.28 864 720" fill="none" stroke="#d6b656" stroke-miterlimit="10" pointer-events="all" style="stroke: rgb(214, 182, 86);"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 63px; height: 1px; padding-top: 753px; margin-left: 865px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: normal; word-wrap: normal; "><div>private or</div><div>candidate</div><div><br /></div></div></div></div></foreignObject><text x="897" y="756" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">private or...</text></switch></g></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-44"><g/></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-48"><g><path d="M 929 740 L 949 740 L 934 740 L 947.63 740" fill="none" stroke="#000000" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/><path d="M 952.88 740 L 945.88 743.5 L 947.63 740 L 945.88 736.5 Z" fill="#000000" stroke="#000000" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/></g></g><g data-cell-id="U9ftda_CDvz5WDsUi4ve-52"><g><rect x="364" y="0" width="360" height="30" fill="none" stroke="none" pointer-events="all"/></g><g><g transform="translate(-0.5 -0.5)"><switch><foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"><div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 15px; margin-left: 544px;"><div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; "><div style="display: inline-block; font-size: 12px; font-family: &quot;Helvetica&quot;; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; white-space: nowrap; "><b><font style="font-size: 15px;">Config Datastore Non-Implicit Commit Cleanup</font></b></div></div></div></foreignObject><text x="544" y="19" fill="light-dark(#000000, #ffffff)" font-family="&quot;Helvetica&quot;" font-size="12px" text-anchor="middle">Config Datastore Non-Implicit Commit Cleanup</text></switch></g></g></g></g></g></g></svg> \ No newline at end of file
diff --git a/doc/user/frr-reload.rst b/doc/user/frr-reload.rst
index bd295dbbad..586d6103b5 100644
--- a/doc/user/frr-reload.rst
+++ b/doc/user/frr-reload.rst
@@ -25,6 +25,8 @@ There are several options that control the behavior of ``frr-reload``:
* ``--stdout``: print output to stdout
* ``--bindir BINDIR``: path to the vtysh executable
* ``--confdir CONFDIR``: path to the existing daemon config files
+* ``--logfile FILENAME``: file (with path) to logfile for the reload operation.
+ Default is ``/var/log/frr/frr-reload.log``
* ``--rundir RUNDIR``: path to a folder to be used to write the temporary files
needed by the script to do its job. The script should have write access to it
* ``--daemon DAEMON``: by default ``frr-reload.py`` assumes that we are using
diff --git a/doc/user/static.rst b/doc/user/static.rst
index c1d11cf0b0..8a32460547 100644
--- a/doc/user/static.rst
+++ b/doc/user/static.rst
@@ -46,8 +46,8 @@ a static prefix and gateway, with several possible forms.
NETWORK is destination prefix with a valid v4 or v6 network based upon
initial form of the command.
- GATEWAY is the IP address to use as next-hop for the prefix. Currently, it must match
- the v4 or v6 route type specified at the start of the command.
+ GATEWAY is the IP address to use as next-hop for the prefix. Routes of type v4 can use v4 and v6 next-hops,
+ v6 routes only support v6 next-hops.
IFNAME is the name of the interface to use as next-hop. If only IFNAME is specified
(without GATEWAY), a connected route will be created.
diff --git a/eigrpd/eigrp_main.c b/eigrpd/eigrp_main.c
index 089e18439f..c9ce018966 100644
--- a/eigrpd/eigrp_main.c
+++ b/eigrpd/eigrp_main.c
@@ -99,6 +99,8 @@ static void sigint(void)
keychain_terminate();
route_map_finish();
+ prefix_list_reset();
+
eigrp_terminate();
exit(0);
diff --git a/eigrpd/eigrp_northbound.c b/eigrpd/eigrp_northbound.c
index 90af47e9e2..de6da954cf 100644
--- a/eigrpd/eigrp_northbound.c
+++ b/eigrpd/eigrp_northbound.c
@@ -739,7 +739,7 @@ static int eigrpd_instance_redistribute_create(struct nb_cb_create_args *args)
else
vrfid = VRF_DEFAULT;
- if (vrf_bitmap_check(&zclient->redist[AFI_IP][proto], vrfid))
+ if (vrf_bitmap_check(&eigrp_zclient->redist[AFI_IP][proto], vrfid))
return NB_ERR_INCONSISTENCY;
break;
case NB_EV_PREPARE:
diff --git a/eigrpd/eigrp_vty.c b/eigrpd/eigrp_vty.c
index e68b85d801..2ad4a25422 100644
--- a/eigrpd/eigrp_vty.c
+++ b/eigrpd/eigrp_vty.c
@@ -280,14 +280,14 @@ DEFPY (show_ip_eigrp_neighbors,
struct eigrp *eigrp;
if (vrf && strncmp(vrf, "all", sizeof("all")) == 0) {
- struct vrf *vrf;
+ struct vrf *tvrf;
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- eigrp = eigrp_lookup(vrf->vrf_id);
+ RB_FOREACH (tvrf, vrf_name_head, &vrfs_by_name) {
+ eigrp = eigrp_lookup(tvrf->vrf_id);
if (!eigrp)
continue;
- vty_out(vty, "VRF %s:\n", vrf->name);
+ vty_out(vty, "VRF %s:\n", tvrf->name);
eigrp_neighbors_helper(vty, eigrp, ifname, detail);
}
@@ -333,7 +333,7 @@ DEFPY (clear_ip_eigrp_neighbors,
eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
/* iterate over all neighbors on eigrp interface */
- frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
+ frr_each_safe (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
zlog_debug(
"Neighbor %pI4 (%s) is down: manually cleared",
@@ -393,7 +393,7 @@ DEFPY (clear_ip_eigrp_neighbors_int,
eigrp_hello_send(ei, EIGRP_HELLO_GRACEFUL_SHUTDOWN, NULL);
/* iterate over all neighbors on eigrp interface */
- frr_each (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
+ frr_each_safe (eigrp_nbr_hash, &ei->nbr_hash_head, nbr) {
if (nbr->state != EIGRP_NEIGHBOR_DOWN) {
zlog_debug(
"Neighbor %pI4 (%s) is down: manually cleared",
diff --git a/eigrpd/eigrp_zebra.c b/eigrpd/eigrp_zebra.c
index 5b0c64ffd0..955a3203ac 100644
--- a/eigrpd/eigrp_zebra.c
+++ b/eigrpd/eigrp_zebra.c
@@ -46,7 +46,7 @@ static int eigrp_interface_address_delete(ZAPI_CALLBACK_ARGS);
static int eigrp_zebra_read_route(ZAPI_CALLBACK_ARGS);
/* Zebra structure to hold current status. */
-struct zclient *zclient = NULL;
+struct zclient *eigrp_zclient = NULL;
/* For registering threads. */
extern struct event_loop *master;
@@ -98,17 +98,17 @@ static zclient_handler *const eigrp_handlers[] = {
void eigrp_zebra_init(void)
{
- zclient = zclient_new(master, &zclient_options_default, eigrp_handlers,
- array_size(eigrp_handlers));
+ eigrp_zclient = zclient_new(master, &zclient_options_default, eigrp_handlers,
+ array_size(eigrp_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
- zclient->zebra_connected = eigrp_zebra_connected;
+ zclient_init(eigrp_zclient, ZEBRA_ROUTE_EIGRP, 0, &eigrpd_privs);
+ eigrp_zclient->zebra_connected = eigrp_zebra_connected;
}
void eigrp_zebra_stop(void)
{
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(eigrp_zclient);
+ zclient_free(eigrp_zclient);
}
/* Zebra route add and delete treatment. */
@@ -192,7 +192,7 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
struct listnode *node;
int count = 0;
- if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
+ if (!eigrp_zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
return;
memset(&api, 0, sizeof(api));
@@ -226,14 +226,14 @@ void eigrp_zebra_route_add(struct eigrp *eigrp, struct prefix *p,
zlog_debug("Zebra: Route add %pFX", p);
}
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, eigrp_zclient, &api);
}
void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p)
{
struct zapi_route api;
- if (!zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
+ if (!eigrp_zclient->redist[AFI_IP][ZEBRA_ROUTE_EIGRP])
return;
memset(&api, 0, sizeof(api));
@@ -241,7 +241,7 @@ void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p)
api.type = ZEBRA_ROUTE_EIGRP;
api.safi = SAFI_UNICAST;
memcpy(&api.prefix, p, sizeof(*p));
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, eigrp_zclient, &api);
if (IS_DEBUG_EIGRP(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Zebra: Route del %pFX", p);
@@ -252,10 +252,8 @@ void eigrp_zebra_route_delete(struct eigrp *eigrp, struct prefix *p)
static int eigrp_is_type_redistributed(int type, vrf_id_t vrf_id)
{
return ((DEFAULT_ROUTE_TYPE(type))
- ? vrf_bitmap_check(
- &zclient->default_information[AFI_IP], vrf_id)
- : vrf_bitmap_check(&zclient->redist[AFI_IP][type],
- vrf_id));
+ ? vrf_bitmap_check(&eigrp_zclient->default_information[AFI_IP], vrf_id)
+ : vrf_bitmap_check(&eigrp_zclient->redist[AFI_IP][type], vrf_id));
}
int eigrp_redistribute_set(struct eigrp *eigrp, int type,
@@ -280,7 +278,7 @@ int eigrp_redistribute_set(struct eigrp *eigrp, int type,
eigrp->dmetric[type] = metric;
- zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type, 0,
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, eigrp_zclient, AFI_IP, type, 0,
eigrp->vrf_id);
++eigrp->redistribute;
@@ -293,7 +291,7 @@ int eigrp_redistribute_unset(struct eigrp *eigrp, int type)
if (eigrp_is_type_redistributed(type, eigrp->vrf_id)) {
memset(&eigrp->dmetric[type], 0, sizeof(struct eigrp_metrics));
- zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP,
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, eigrp_zclient, AFI_IP,
type, 0, eigrp->vrf_id);
--eigrp->redistribute;
}
diff --git a/eigrpd/eigrpd.c b/eigrpd/eigrpd.c
index 543a54da13..bc7c60c501 100644
--- a/eigrpd/eigrpd.c
+++ b/eigrpd/eigrpd.c
@@ -52,7 +52,6 @@ static struct eigrp_master eigrp_master;
struct eigrp_master *eigrp_om;
-extern struct zclient *zclient;
extern struct in_addr router_id_zebra;
int eigrp_master_hash_cmp(const struct eigrp *a, const struct eigrp *b)
diff --git a/eigrpd/eigrpd.h b/eigrpd/eigrpd.h
index 15d2bb54ee..28b1dc9a11 100644
--- a/eigrpd/eigrpd.h
+++ b/eigrpd/eigrpd.h
@@ -52,7 +52,7 @@ struct eigrp_master {
};
/* Extern variables. */
-extern struct zclient *zclient;
+extern struct zclient *eigrp_zclient;
extern struct event_loop *master;
extern struct eigrp_master *eigrp_om;
extern struct zebra_privs_t eigrpd_privs;
diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c
index 078280acf5..39ed076fab 100644
--- a/isisd/isis_adjacency.c
+++ b/isisd/isis_adjacency.c
@@ -653,7 +653,6 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
json_object_object_add(iface_json, "ipv6-link-local",
ipv6_link_json);
for (unsigned int i = 0; i < adj->ll_ipv6_count; i++) {
- char buf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &adj->ll_ipv6_addrs[i], buf,
sizeof(buf));
json_object_string_add(ipv6_link_json, "ipv6",
@@ -666,7 +665,6 @@ void isis_adj_print_json(struct isis_adjacency *adj, struct json_object *json,
ipv6_non_link_json);
for (unsigned int i = 0; i < adj->global_ipv6_count;
i++) {
- char buf[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, &adj->global_ipv6_addrs[i],
buf, sizeof(buf));
json_object_string_add(ipv6_non_link_json,
diff --git a/isisd/isis_affinitymap.c b/isisd/isis_affinitymap.c
index 595091db27..a6b9cf9d4c 100644
--- a/isisd/isis_affinitymap.c
+++ b/isisd/isis_affinitymap.c
@@ -64,4 +64,8 @@ void isis_affinity_map_init(void)
affinity_map_set_update_hook(isis_affinity_map_update);
}
+void isis_affinity_map_terminate(void)
+{
+ affinity_map_terminate();
+}
#endif /* ifndef FABRICD */
diff --git a/isisd/isis_affinitymap.h b/isisd/isis_affinitymap.h
index c432e99f51..525ee0467a 100644
--- a/isisd/isis_affinitymap.h
+++ b/isisd/isis_affinitymap.h
@@ -15,6 +15,7 @@ extern "C" {
#endif
extern void isis_affinity_map_init(void);
+extern void isis_affinity_map_terminate(void);
#ifdef __cplusplus
}
diff --git a/isisd/isis_bfd.c b/isisd/isis_bfd.c
index 5e24e35210..c003b8002d 100644
--- a/isisd/isis_bfd.c
+++ b/isisd/isis_bfd.c
@@ -211,7 +211,7 @@ static int bfd_handle_circuit_add_addr(struct isis_circuit *circuit)
void isis_bfd_init(struct event_loop *tm)
{
- bfd_protocol_integration_init(zclient, tm);
+ bfd_protocol_integration_init(isis_zclient, tm);
hook_register(isis_adj_state_change_hook, bfd_handle_adj_state_change);
hook_register(isis_adj_ip_enabled_hook, bfd_handle_adj_ip_enabled);
diff --git a/isisd/isis_cli.c b/isisd/isis_cli.c
index c86d929903..46611a75ec 100644
--- a/isisd/isis_cli.c
+++ b/isisd/isis_cli.c
@@ -2157,7 +2157,7 @@ DEFPY_YANG_NOSH (isis_srv6_node_msd,
/*
* XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-segs-left
*/
-DEFPY (isis_srv6_node_msd_max_segs_left,
+DEFPY_YANG (isis_srv6_node_msd_max_segs_left,
isis_srv6_node_msd_max_segs_left_cmd,
"[no] max-segs-left (0-255)$max_segs_left",
NO_STR
@@ -2177,7 +2177,7 @@ DEFPY (isis_srv6_node_msd_max_segs_left,
/*
* XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-pop
*/
-DEFPY (isis_srv6_node_msd_max_end_pop,
+DEFPY_YANG (isis_srv6_node_msd_max_end_pop,
isis_srv6_node_msd_max_end_pop_cmd,
"[no] max-end-pop (0-255)$max_end_pop",
NO_STR
@@ -2196,7 +2196,7 @@ DEFPY (isis_srv6_node_msd_max_end_pop,
/*
* XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-h-encaps
*/
-DEFPY (isis_srv6_node_msd_max_h_encaps,
+DEFPY_YANG (isis_srv6_node_msd_max_h_encaps,
isis_srv6_node_msd_max_h_encaps_cmd,
"[no] max-h-encaps (0-255)$max_h_encaps",
NO_STR
@@ -2216,7 +2216,7 @@ DEFPY (isis_srv6_node_msd_max_h_encaps,
/*
* XPath: /frr-isisd:isis/instance/segment-routing-srv6/msd/node-msd/max-end-d
*/
-DEFPY (isis_srv6_node_msd_max_end_d,
+DEFPY_YANG (isis_srv6_node_msd_max_end_d,
isis_srv6_node_msd_max_end_d_cmd,
"[no] max-end-d (0-255)$max_end_d",
NO_STR
@@ -2262,7 +2262,7 @@ void cli_show_isis_srv6_node_msd_end(struct vty *vty, const struct lyd_node *dno
/*
* XPath: /frr-isisd:isis/instance/segment-routing-srv6/interface
*/
-DEFPY (isis_srv6_interface,
+DEFPY_YANG (isis_srv6_interface,
isis_srv6_interface_cmd,
"[no] interface WORD$interface",
NO_STR
@@ -3268,7 +3268,7 @@ void cli_show_ip_isis_frr(struct vty *vty, const struct lyd_node *dnode,
/*
* XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/lfa/enable
*/
-DEFPY(isis_lfa, isis_lfa_cmd,
+DEFPY_YANG(isis_lfa, isis_lfa_cmd,
"[no] isis fast-reroute lfa [level-1|level-2]$level",
NO_STR
"IS-IS routing protocol\n"
@@ -3311,7 +3311,7 @@ DEFPY(isis_lfa, isis_lfa_cmd,
* XPath:
* /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/lfa/exclude-interface
*/
-DEFPY(isis_lfa_exclude_interface, isis_lfa_exclude_interface_cmd,
+DEFPY_YANG(isis_lfa_exclude_interface, isis_lfa_exclude_interface_cmd,
"[no] isis fast-reroute lfa [level-1|level-2]$level exclude interface IFNAME$ifname",
NO_STR
"IS-IS routing protocol\n"
@@ -3362,7 +3362,7 @@ void cli_show_frr_lfa_exclude_interface(struct vty *vty,
* XPath:
* /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/enable
*/
-DEFPY(isis_remote_lfa, isis_remote_lfa_cmd,
+DEFPY_YANG(isis_remote_lfa, isis_remote_lfa_cmd,
"[no] isis fast-reroute remote-lfa tunnel mpls-ldp [level-1|level-2]$level",
NO_STR
"IS-IS routing protocol\n"
@@ -3407,7 +3407,7 @@ DEFPY(isis_remote_lfa, isis_remote_lfa_cmd,
* XPath:
* /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/remote-lfa/maximum-metric
*/
-DEFPY(isis_remote_lfa_max_metric, isis_remote_lfa_max_metric_cmd,
+DEFPY_YANG(isis_remote_lfa_max_metric, isis_remote_lfa_max_metric_cmd,
"[no] isis fast-reroute remote-lfa maximum-metric (1-16777215)$metric [level-1|level-2]$level",
NO_STR
"IS-IS routing protocol\n"
@@ -3460,7 +3460,7 @@ void cli_show_frr_remote_lfa_max_metric(struct vty *vty,
/*
* XPath: /frr-interface:lib/interface/frr-isisd:isis/fast-reroute/level-{1,2}/ti-lfa/enable
*/
-DEFPY(isis_ti_lfa, isis_ti_lfa_cmd,
+DEFPY_YANG(isis_ti_lfa, isis_ti_lfa_cmd,
"[no] isis fast-reroute ti-lfa [level-1|level-2]$level [node-protection$node_protection [link-fallback$link_fallback]]",
NO_STR
"IS-IS routing protocol\n"
@@ -3578,7 +3578,7 @@ void cli_show_isis_log_pdu_drops(struct vty *vty, const struct lyd_node *dnode,
/*
* XPath: /frr-isisd:isis/instance/mpls/ldp-sync
*/
-DEFPY(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync",
+DEFPY_YANG(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync",
MPLS_STR MPLS_LDP_SYNC_STR)
{
nb_cli_enqueue_change(vty, "./mpls/ldp-sync", NB_OP_CREATE, NULL);
@@ -3586,7 +3586,7 @@ DEFPY(isis_mpls_ldp_sync, isis_mpls_ldp_sync_cmd, "mpls ldp-sync",
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(no_isis_mpls_ldp_sync, no_isis_mpls_ldp_sync_cmd, "no mpls ldp-sync",
+DEFPY_YANG(no_isis_mpls_ldp_sync, no_isis_mpls_ldp_sync_cmd, "no mpls ldp-sync",
NO_STR MPLS_STR NO_MPLS_LDP_SYNC_STR)
{
nb_cli_enqueue_change(vty, "./mpls/ldp-sync", NB_OP_DESTROY, NULL);
@@ -3600,7 +3600,7 @@ void cli_show_isis_mpls_ldp_sync(struct vty *vty, const struct lyd_node *dnode,
vty_out(vty, " mpls ldp-sync\n");
}
-DEFPY(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd,
+DEFPY_YANG(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd,
"mpls ldp-sync holddown (0-10000)",
MPLS_STR MPLS_LDP_SYNC_STR
"Time to wait for LDP-SYNC to occur before restoring interface metric\n"
@@ -3612,7 +3612,7 @@ DEFPY(isis_mpls_ldp_sync_holddown, isis_mpls_ldp_sync_holddown_cmd,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(no_isis_mpls_ldp_sync_holddown, no_isis_mpls_ldp_sync_holddown_cmd,
+DEFPY_YANG(no_isis_mpls_ldp_sync_holddown, no_isis_mpls_ldp_sync_holddown_cmd,
"no mpls ldp-sync holddown [<(1-10000)>]",
NO_STR MPLS_STR MPLS_LDP_SYNC_STR NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n")
{
@@ -3633,7 +3633,7 @@ void cli_show_isis_mpls_ldp_sync_holddown(struct vty *vty,
/*
* XPath: /frr-interface:lib/interface/frr-isisd:isis/mpls/ldp-sync
*/
-DEFPY(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd,
+DEFPY_YANG(isis_mpls_if_ldp_sync, isis_mpls_if_ldp_sync_cmd,
"[no] isis mpls ldp-sync",
NO_STR "IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR)
{
@@ -3663,7 +3663,7 @@ void cli_show_isis_mpls_if_ldp_sync(struct vty *vty,
vty_out(vty, " isis mpls ldp-sync\n");
}
-DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd,
+DEFPY_YANG(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd,
"isis mpls ldp-sync holddown (0-10000)",
"IS-IS routing protocol\n" MPLS_STR MPLS_LDP_SYNC_STR
"Time to wait for LDP-SYNC to occur before restoring interface metric\n"
@@ -3684,7 +3684,7 @@ DEFPY(isis_mpls_if_ldp_sync_holddown, isis_mpls_if_ldp_sync_holddown_cmd,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd,
+DEFPY_YANG(no_isis_mpls_if_ldp_sync_holddown, no_isis_mpls_if_ldp_sync_holddown_cmd,
"no isis mpls ldp-sync holddown [<(1-10000)>]",
NO_STR "IS-IS routing protocol\n" MPLS_STR NO_MPLS_LDP_SYNC_STR
NO_MPLS_LDP_SYNC_HOLDDOWN_STR "Time in seconds\n")
diff --git a/isisd/isis_flags.c b/isisd/isis_flags.c
index a621b4b5ed..09f46fbb58 100644
--- a/isisd/isis_flags.c
+++ b/isisd/isis_flags.c
@@ -26,12 +26,14 @@ long int flags_get_index(struct flags *flags)
{
struct listnode *node;
long int index;
+ const void *ptr;
if (flags->free_idcs == NULL || flags->free_idcs->count == 0) {
index = flags->maxindex++;
} else {
node = listhead(flags->free_idcs);
- index = (long int)listgetdata(node);
+ ptr = listgetdata(node);
+ index = (long int)ptr;
listnode_delete(flags->free_idcs, (void *)index);
index--;
}
diff --git a/isisd/isis_ldp_sync.c b/isisd/isis_ldp_sync.c
index 53676ffe36..99e9227ad5 100644
--- a/isisd/isis_ldp_sync.c
+++ b/isisd/isis_ldp_sync.c
@@ -40,10 +40,9 @@
#include "isisd/isis_errors.h"
#include "isisd/isis_tx_queue.h"
#include "isisd/isis_nb.h"
+#include "isisd/isis_zebra.h"
#include "isisd/isis_ldp_sync.h"
-extern struct zclient *zclient;
-
/*
* LDP-SYNC msg between IGP and LDP
*/
@@ -122,8 +121,8 @@ void isis_ldp_sync_state_req_msg(struct isis_circuit *circuit)
request.proto = LDP_IGP_SYNC_IF_STATE_REQUEST;
request.ifindex = ifp->ifindex;
- zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST,
- (uint8_t *)&request, sizeof(request));
+ zclient_send_opaque(isis_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST,
+ (uint8_t *)&request, sizeof(request));
}
/*
diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c
index 28b987df38..4952c689fc 100644
--- a/isisd/isis_lsp.c
+++ b/isisd/isis_lsp.c
@@ -1125,7 +1125,6 @@ static void lsp_build(struct isis_lsp *lsp, struct isis_area *area)
struct isis_router_cap *rcap;
#ifndef FABRICD
struct isis_router_cap_fad *rcap_fad;
- struct listnode *node;
struct flex_algo *fa;
#endif /* ifndef FABRICD */
diff --git a/isisd/isis_main.c b/isisd/isis_main.c
index 0d9b3df39c..c36c531a17 100644
--- a/isisd/isis_main.c
+++ b/isisd/isis_main.c
@@ -109,6 +109,10 @@ static __attribute__((__noreturn__)) void terminate(int i)
isis_master_terminate();
route_map_finish();
+ prefix_list_reset();
+#ifndef FABRICD
+ isis_affinity_map_terminate();
+#endif
vrf_terminate();
frr_fini();
diff --git a/isisd/isis_route.c b/isisd/isis_route.c
index b907c962be..0a0c6341d6 100644
--- a/isisd/isis_route.c
+++ b/isisd/isis_route.c
@@ -240,7 +240,7 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
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 isis_sr_psid_info *vsr = &vadj->sr;
struct mpls_label_stack *label_stack = vadj->label_stack;
/*
@@ -248,7 +248,7 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
* environment.
*/
if (CHECK_FLAG(im->options, F_ISIS_UNIT_TEST)) {
- isis_route_add_dummy_nexthops(rinfo, sadj->id, sr,
+ isis_route_add_dummy_nexthops(rinfo, sadj->id, vsr,
label_stack);
if (!allow_ecmp)
break;
@@ -260,7 +260,7 @@ isis_route_info_new(struct prefix *prefix, struct prefix_ipv6 *src_p,
ISIS_CIRCUIT_FLAPPED_AFTER_SPF))
SET_FLAG(rinfo->flag, ISIS_ROUTE_FLAG_ZEBRA_RESYNC);
- adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, sr,
+ adjinfo2nexthop(prefix->family, rinfo->nexthops, adj, vsr,
label_stack);
if (!allow_ecmp)
break;
diff --git a/isisd/isis_snmp.c b/isisd/isis_snmp.c
index 83a06b6998..24320e9ed9 100644
--- a/isisd/isis_snmp.c
+++ b/isisd/isis_snmp.c
@@ -692,15 +692,15 @@ static int isis_circuit_snmp_id_free(struct isis_circuit *circuit)
static struct isis_circuit *isis_snmp_circuit_next(struct isis_circuit *circuit)
{
uint32_t start;
- uint32_t off;
+ uint32_t offset;
start = 1;
if (circuit != NULL)
start = circuit->snmp_id + 1;
- for (off = start; off < SNMP_CIRCUITS_MAX; off++) {
- circuit = snmp_circuits[off];
+ for (offset = start; offset < SNMP_CIRCUITS_MAX; offset++) {
+ circuit = snmp_circuits[offset];
if (circuit != NULL)
return circuit;
@@ -759,7 +759,7 @@ static int isis_snmp_get_level_match(int is_type, int level)
static int isis_snmp_conv_exact(uint8_t *buf, size_t max_len, size_t *out_len,
const oid *idx, size_t idx_len)
{
- size_t off;
+ size_t offset;
size_t len;
/* Oid representation: length followed by bytes */
@@ -774,11 +774,11 @@ static int isis_snmp_conv_exact(uint8_t *buf, size_t max_len, size_t *out_len,
if (idx_len < len + 1)
return 0;
- for (off = 0; off < len; off++) {
- if (idx[off + 1] > 0xff)
+ for (offset = 0; offset < len; offset++) {
+ if (idx[offset + 1] > 0xff)
return 0;
- buf[off] = (uint8_t)(idx[off + 1] & 0xff);
+ buf[offset] = (uint8_t)(idx[offset + 1] & 0xff);
}
*out_len = len;
@@ -789,7 +789,7 @@ static int isis_snmp_conv_exact(uint8_t *buf, size_t max_len, size_t *out_len,
static int isis_snmp_conv_next(uint8_t *buf, size_t max_len, size_t *out_len,
int *try_exact, const oid *idx, size_t idx_len)
{
- size_t off;
+ size_t offset;
size_t len;
size_t cmp_len;
@@ -809,15 +809,15 @@ static int isis_snmp_conv_next(uint8_t *buf, size_t max_len, size_t *out_len,
if ((idx_len - 1) < cmp_len)
cmp_len = idx_len - 1;
- for (off = 0; off < cmp_len; off++) {
- if (idx[off + 1] > 0xff) {
- memset(buf + off, 0xff, len - off);
+ for (offset = 0; offset < cmp_len; offset++) {
+ if (idx[offset + 1] > 0xff) {
+ memset(buf + offset, 0xff, len - off);
*out_len = len;
*try_exact = 1;
return 1;
}
- buf[off] = (uint8_t)(idx[off + 1] & 0xff);
+ buf[offset] = (uint8_t)(idx[offset + 1] & 0xff);
}
if (cmp_len < len)
@@ -983,7 +983,7 @@ static int isis_snmp_circuit_lookup_exact(oid *oid_idx, size_t oid_idx_len,
static int isis_snmp_circuit_lookup_next(oid *oid_idx, size_t oid_idx_len,
struct isis_circuit **ret_circuit)
{
- oid off;
+ oid offset;
oid start;
struct isis_circuit *circuit;
@@ -996,10 +996,10 @@ static int isis_snmp_circuit_lookup_next(oid *oid_idx, size_t oid_idx_len,
start = oid_idx[0];
}
- for (off = start; off < SNMP_CIRCUITS_MAX; ++off) {
- circuit = snmp_circuits[off];
+ for (offset = start; offset < SNMP_CIRCUITS_MAX; ++offset) {
+ circuit = snmp_circuits[offset];
- if (circuit != NULL && off > start) {
+ if (circuit != NULL && offset > start) {
if (ret_circuit != NULL)
*ret_circuit = circuit;
@@ -1052,7 +1052,7 @@ static int isis_snmp_circuit_level_lookup_next(
oid *oid_idx, size_t oid_idx_len, int check_match,
struct isis_circuit **ret_circuit, int *ret_level)
{
- oid off;
+ oid offset;
oid start;
struct isis_circuit *circuit = NULL;
int level;
@@ -1066,13 +1066,13 @@ static int isis_snmp_circuit_level_lookup_next(
start = oid_idx[0];
}
- for (off = start; off < SNMP_CIRCUITS_MAX; off++) {
- circuit = snmp_circuits[off];
+ for (offset = start; offset < SNMP_CIRCUITS_MAX; offset++) {
+ circuit = snmp_circuits[offset];
if (circuit == NULL)
continue;
- if (off > start || oid_idx_len < 2) {
+ if (offset > start || oid_idx_len < 2) {
/* Found and can use level 1 */
level = IS_LEVEL_1;
break;
@@ -1504,7 +1504,7 @@ static uint8_t *isis_snmp_find_man_area(struct variable *v, oid *name,
struct iso_address *area_addr = NULL;
oid *oid_idx;
size_t oid_idx_len;
- size_t off = 0;
+ size_t offset = 0;
*write_method = NULL;
@@ -1539,8 +1539,8 @@ static uint8_t *isis_snmp_find_man_area(struct variable *v, oid *name,
/* Append index */
name[v->namelen] = area_addr->addr_len;
- for (off = 0; off < area_addr->addr_len; off++)
- name[v->namelen + 1 + off] = area_addr->area_addr[off];
+ for (offset = 0; offset < area_addr->addr_len; offset++)
+ name[v->namelen + 1 + offset] = area_addr->area_addr[offset];
*length = v->namelen + 1 + area_addr->addr_len;
}
@@ -1628,7 +1628,7 @@ static uint8_t *isis_snmp_find_router(struct variable *v, oid *name,
struct isis_dynhn *dyn = NULL;
oid *oid_idx;
size_t oid_idx_len;
- size_t off = 0;
+ size_t offset = 0;
struct isis *isis = isis_lookup_by_vrfid(VRF_DEFAULT);
if (isis == NULL)
@@ -1729,8 +1729,8 @@ static uint8_t *isis_snmp_find_router(struct variable *v, oid *name,
/* Append index */
name[v->namelen] = ISIS_SYS_ID_LEN;
- for (off = 0; off < ISIS_SYS_ID_LEN; off++)
- name[v->namelen + 1 + off] = dyn->id[off];
+ for (offset = 0; offset < ISIS_SYS_ID_LEN; offset++)
+ name[v->namelen + 1 + off] = dyn->id[offset];
name[v->namelen + 1 + ISIS_SYS_ID_LEN] = (oid)dyn->level;
@@ -2803,8 +2803,8 @@ static int isis_snmp_init(struct event_loop *tm)
struct isis_func_to_prefix *h2f = isis_func_to_prefix_arr;
struct variable *v;
- for (size_t off = 0; off < isis_var_count; off++) {
- v = &isis_var_arr[off];
+ for (size_t offset = 0; offset < isis_var_count; offset++) {
+ v = &isis_var_arr[offset];
if (v->findVar != h2f->ihtp_func) {
/* Next table */
@@ -2858,7 +2858,7 @@ static int isis_snmp_db_overload_update(const struct isis_area *area)
{
netsnmp_variable_list *notification_vars;
long val;
- uint32_t off;
+ uint32_t offset;
if (!isis_snmp_trap_throttle(ISIS_TRAP_DB_OVERLOAD))
return 0;
@@ -2880,8 +2880,8 @@ static int isis_snmp_db_overload_update(const struct isis_area *area)
(uint8_t *)&val, sizeof(val));
/* Patch sys_level_state with proper index */
- off = array_size(isis_snmp_trap_data_var_sys_level_state) - 1;
- isis_snmp_trap_data_var_sys_level_state[off] = val;
+ offset = array_size(isis_snmp_trap_data_var_sys_level_state) - 1;
+ isis_snmp_trap_data_var_sys_level_state[offset] = val;
/* Prepare data */
if (area->overload_bit)
diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c
index 9c32a8447c..5960fef755 100644
--- a/isisd/isis_spf.c
+++ b/isisd/isis_spf.c
@@ -1195,7 +1195,7 @@ end:
&& !spftree->area->attached_bit_rcv_ignore
&& (spftree->area->is_type & IS_LEVEL_1)
&& !isis_level2_adj_up(spftree->area)) {
- struct prefix_pair ip_info = { {0} };
+ memset(&ip_info, 0, sizeof(ip_info));
if (IS_DEBUG_RTE_EVENTS)
zlog_debug("ISIS-Spf (%pLS): add default %s route",
lsp->hdr.lsp_id,
diff --git a/isisd/isis_sr.c b/isisd/isis_sr.c
index 95ea36c3a8..fd6a44504c 100644
--- a/isisd/isis_sr.c
+++ b/isisd/isis_sr.c
@@ -749,11 +749,11 @@ void sr_adj_sid_add_single(struct isis_adjacency *adj, int family, bool backup,
sra->backup_nexthops = list_new();
for (ALL_LIST_ELEMENTS_RO(nexthops, node, vadj)) {
- struct isis_adjacency *adj = vadj->sadj->adj;
+ struct isis_adjacency *tadj = vadj->sadj->adj;
struct mpls_label_stack *label_stack;
label_stack = vadj->label_stack;
- adjinfo2nexthop(family, sra->backup_nexthops, adj, NULL,
+ adjinfo2nexthop(family, sra->backup_nexthops, tadj, NULL,
label_stack);
}
}
diff --git a/isisd/isis_te.c b/isisd/isis_te.c
index 32492ae0c0..cf92ae46e9 100644
--- a/isisd/isis_te.c
+++ b/isisd/isis_te.c
@@ -704,15 +704,15 @@ static int isis_te_export(uint8_t type, void *link_state)
switch (type) {
case LS_MSG_TYPE_NODE:
ls_vertex2msg(&msg, (struct ls_vertex *)link_state);
- rc = ls_send_msg(zclient, &msg, NULL);
+ rc = ls_send_msg(isis_zclient, &msg, NULL);
break;
case LS_MSG_TYPE_ATTRIBUTES:
ls_edge2msg(&msg, (struct ls_edge *)link_state);
- rc = ls_send_msg(zclient, &msg, NULL);
+ rc = ls_send_msg(isis_zclient, &msg, NULL);
break;
case LS_MSG_TYPE_PREFIX:
ls_subnet2msg(&msg, (struct ls_subnet *)link_state);
- rc = ls_send_msg(zclient, &msg, NULL);
+ rc = ls_send_msg(isis_zclient, &msg, NULL);
break;
default:
rc = -1;
@@ -1494,7 +1494,7 @@ static void isis_te_parse_lsp(struct mpls_te_area *mta, struct isis_lsp *lsp)
/* Clean remaining Orphan Edges or Subnets */
if (IS_EXPORT_TE(mta))
- ls_vertex_clean(ted, vertex, zclient);
+ ls_vertex_clean(ted, vertex, isis_zclient);
else
ls_vertex_clean(ted, vertex, NULL);
}
@@ -1653,7 +1653,7 @@ int isis_te_sync_ted(struct zapi_opaque_reg_info dst)
if (IS_MPLS_TE(mta) && IS_EXPORT_TE(mta)) {
te_debug(" |- Export TED from area %s",
area->area_tag);
- rc = ls_sync_ted(mta->ted, zclient, &dst);
+ rc = ls_sync_ted(mta->ted, isis_zclient, &dst);
if (rc != 0)
return rc;
}
diff --git a/isisd/isis_tlvs.c b/isisd/isis_tlvs.c
index 8c97dcda2f..41a17dbd1a 100644
--- a/isisd/isis_tlvs.c
+++ b/isisd/isis_tlvs.c
@@ -129,6 +129,7 @@ static int unpack_tlvs(enum isis_tlv_context context, size_t avail_len,
struct stream *stream, struct sbuf *log, void *dest,
int indent, bool *unpacked_known_tlvs);
static void isis_free_subsubtlvs(struct isis_subsubtlvs *subsubtlvs);
+static void isis_tlvs_del_asla_free(void *arg);
/* For tests/isisd, TLV text requires ipv4-unicast instead of standard */
static const char *isis_mtid2str_fake(uint16_t mtid)
@@ -147,6 +148,7 @@ struct isis_ext_subtlvs *isis_alloc_ext_subtlvs(void)
init_item_list(&ext->adj_sid);
init_item_list(&ext->lan_sid);
ext->aslas = list_new();
+ ext->aslas->del = isis_tlvs_del_asla_free;
init_item_list(&ext->srv6_endx_sid);
init_item_list(&ext->srv6_lan_endx_sid);
@@ -518,7 +520,7 @@ static void format_item_asla_subtlvs(struct isis_asla_subtlvs *asla,
asla->max_rsv_bw);
if (IS_SUBTLV(asla, EXT_UNRSV_BW)) {
sbuf_push(buf, indent + 2, "Unreserved Bandwidth:\n");
- for (int j = 0; j < MAX_CLASS_TYPE; j += 2) {
+ for (j = 0; j < MAX_CLASS_TYPE; j += 2) {
sbuf_push(
buf, indent + 2,
"[%d]: %g (Bytes/sec),\t[%d]: %g (Bytes/sec)\n",
@@ -3209,7 +3211,7 @@ static struct isis_item *copy_item_lsp_entry(struct isis_item *i)
}
static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i,
- struct sbuf *buf, struct json_object *json,
+ struct sbuf *sbuf, struct json_object *json,
int indent)
{
struct isis_lsp_entry *e = (struct isis_lsp_entry *)i;
@@ -3229,10 +3231,9 @@ static void format_item_lsp_entry(uint16_t mtid, struct isis_item *i,
json_object_string_add(lsp_json, "chksum", buf);
json_object_int_add(lsp_json, "lifetime", e->checksum);
} else
- sbuf_push(
- buf, indent,
- "LSP Entry: %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus\n",
- sys_id, e->seqno, e->checksum, e->rem_lifetime);
+ sbuf_push(sbuf, indent,
+ "LSP Entry: %s, seq 0x%08x, cksum 0x%04hx, lifetime %hus\n",
+ sys_id, e->seqno, e->checksum, e->rem_lifetime);
}
static void free_item_lsp_entry(struct isis_item *i)
@@ -3553,7 +3554,7 @@ static void copy_tlv_protocols_supported(struct isis_protocols_supported *src,
}
static void format_tlv_protocols_supported(struct isis_protocols_supported *p,
- struct sbuf *buf,
+ struct sbuf *sbuf,
struct json_object *json, int indent)
{
if (!p || !p->count || !p->protocols)
@@ -3572,12 +3573,12 @@ static void format_tlv_protocols_supported(struct isis_protocols_supported *p,
nlpid2str(p->protocols[i]));
}
} else {
- sbuf_push(buf, indent, "Protocols Supported: ");
+ sbuf_push(sbuf, indent, "Protocols Supported: ");
for (uint8_t i = 0; i < p->count; i++) {
- sbuf_push(buf, 0, "%s%s", nlpid2str(p->protocols[i]),
+ sbuf_push(sbuf, 0, "%s%s", nlpid2str(p->protocols[i]),
(i + 1 < p->count) ? ", " : "");
}
- sbuf_push(buf, 0, "\n");
+ sbuf_push(sbuf, 0, "\n");
}
}
@@ -5275,9 +5276,9 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
/* Flex Algo Definitions */
for (int i = 0; i < SR_ALGORITHM_COUNT; i++) {
struct isis_router_cap_fad *fad;
- size_t subtlv_len;
struct admin_group *ag;
uint32_t admin_group_length;
+ size_t j;
fad = router_cap->fads[i];
if (!fad)
@@ -5315,8 +5316,8 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
if (admin_group_length) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_EXCAG);
stream_putc(s, sizeof(uint32_t) * admin_group_length);
- for (size_t i = 0; i < admin_group_length; i++)
- stream_putl(s, admin_group_get_offset(ag, i));
+ for (j = 0; j < admin_group_length; j++)
+ stream_putl(s, admin_group_get_offset(ag, j));
}
ag = &fad->fad.admin_group_include_any;
@@ -5324,8 +5325,8 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
if (admin_group_length) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_INCANYAG);
stream_putc(s, sizeof(uint32_t) * admin_group_length);
- for (size_t i = 0; i < admin_group_length; i++)
- stream_putl(s, admin_group_get_offset(ag, i));
+ for (j = 0; j < admin_group_length; j++)
+ stream_putl(s, admin_group_get_offset(ag, j));
}
ag = &fad->fad.admin_group_include_all;
@@ -5333,8 +5334,8 @@ static int pack_tlv_router_cap(const struct isis_router_cap *router_cap,
if (admin_group_length) {
stream_putc(s, ISIS_SUBTLV_FAD_SUBSUBTLV_INCALLAG);
stream_putc(s, sizeof(uint32_t) * admin_group_length);
- for (size_t i = 0; i < admin_group_length; i++)
- stream_putl(s, admin_group_get_offset(ag, i));
+ for (j = 0; j < admin_group_length; j++)
+ stream_putl(s, admin_group_get_offset(ag, j));
}
if (fad->fad.flags != 0) {
@@ -8137,12 +8138,19 @@ void isis_tlvs_del_srv6_lan_endx_sid(struct isis_ext_subtlvs *exts,
UNSET_SUBTLV(exts, EXT_SRV6_LAN_ENDX_SID);
}
+static void isis_tlvs_del_asla_free(void *arg)
+{
+ struct isis_asla_subtlvs *asla = arg;
+
+ admin_group_term(&asla->ext_admin_group);
+ XFREE(MTYPE_ISIS_SUBTLV, asla);
+}
+
void isis_tlvs_del_asla_flex_algo(struct isis_ext_subtlvs *ext,
struct isis_asla_subtlvs *asla)
{
- admin_group_term(&asla->ext_admin_group);
listnode_delete(ext->aslas, asla);
- XFREE(MTYPE_ISIS_SUBTLV, asla);
+ isis_tlvs_del_asla_free(asla);
}
struct isis_asla_subtlvs *
diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c
index c2670143f2..15af9636ca 100644
--- a/isisd/isis_zebra.c
+++ b/isisd/isis_zebra.c
@@ -45,7 +45,7 @@
#include "isisd/isis_sr.h"
#include "isisd/isis_ldp_sync.h"
-struct zclient *zclient;
+struct zclient *isis_zclient;
static struct zclient *zclient_sync;
/* Router-id update message from zebra. */
@@ -254,7 +254,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 (isis_zclient->sock < 0)
return;
/* Uninstall the route if it doesn't have any valid nexthop. */
@@ -295,7 +295,7 @@ void isis_zebra_route_add_route(struct isis *isis, struct prefix *prefix,
return;
api.nexthop_num = count;
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, isis_zclient, &api);
}
void isis_zebra_route_del_route(struct isis *isis,
@@ -305,7 +305,7 @@ void isis_zebra_route_del_route(struct isis *isis,
{
struct zapi_route api;
- if (zclient->sock < 0)
+ if (isis_zclient->sock < 0)
return;
if (!CHECK_FLAG(route_info->flag, ISIS_ROUTE_FLAG_ZEBRA_SYNCED))
@@ -321,7 +321,7 @@ void isis_zebra_route_del_route(struct isis *isis,
SET_FLAG(api.message, ZAPI_MESSAGE_SRCPFX);
}
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, isis_zclient, &api);
}
/**
@@ -388,7 +388,7 @@ void isis_zebra_prefix_sid_install(struct isis_area *area,
}
/* Send message to zebra. */
- (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
+ (void)zebra_send_mpls_labels(isis_zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
}
/**
@@ -415,7 +415,7 @@ void isis_zebra_prefix_sid_uninstall(struct isis_area *area,
zl.local_label = psid->label;
/* Send message to zebra. */
- (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
+ (void)zebra_send_mpls_labels(isis_zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
}
/**
@@ -471,7 +471,7 @@ void isis_zebra_send_adjacency_sid(int cmd, const struct sr_adjacency *sra)
}
}
- (void)zebra_send_mpls_labels(zclient, cmd, &zl);
+ (void)zebra_send_mpls_labels(isis_zclient, cmd, &zl);
}
static int isis_zebra_read(ZAPI_CALLBACK_ARGS)
@@ -523,9 +523,9 @@ void isis_zebra_redistribute_set(afi_t afi, int type, vrf_id_t vrf_id,
{
if (type == DEFAULT_ROUTE)
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- zclient, afi, vrf_id);
+ isis_zclient, afi, vrf_id);
else
- zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, afi, type,
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, isis_zclient, afi, type,
tableid, vrf_id);
}
@@ -534,9 +534,9 @@ void isis_zebra_redistribute_unset(afi_t afi, int type, vrf_id_t vrf_id,
{
if (type == DEFAULT_ROUTE)
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
- zclient, afi, vrf_id);
+ isis_zclient, afi, vrf_id);
else
- zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, afi,
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, isis_zclient, afi,
type, tableid, vrf_id);
}
@@ -549,7 +549,7 @@ int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa)
struct zapi_rlfa_request zr = {};
int ret;
- if (!zclient)
+ if (!isis_zclient)
return 0;
zr.igp.vrf_id = area->isis->vrf_id;
@@ -565,7 +565,7 @@ int isis_zebra_rlfa_register(struct isis_spftree *spftree, struct rlfa *rlfa)
zlog_debug("ISIS-LFA: registering RLFA %pFX@%pI4 with LDP",
&rlfa->prefix, &rlfa->pq_address);
- ret = zclient_send_opaque_unicast(zclient, LDP_RLFA_REGISTER,
+ ret = zclient_send_opaque_unicast(isis_zclient, LDP_RLFA_REGISTER,
ZEBRA_ROUTE_LDP, 0, 0,
(const uint8_t *)&zr, sizeof(zr));
if (ret == ZCLIENT_SEND_FAILURE) {
@@ -585,8 +585,8 @@ void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree)
struct zapi_rlfa_igp igp = {};
int ret;
- if (!zclient || spftree->type != SPF_TYPE_FORWARD
- || CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES))
+ if (!isis_zclient || spftree->type != SPF_TYPE_FORWARD ||
+ CHECK_FLAG(spftree->flags, F_SPFTREE_NO_ADJACENCIES))
return;
if (IS_DEBUG_LFA)
@@ -599,7 +599,7 @@ void isis_zebra_rlfa_unregister_all(struct isis_spftree *spftree)
igp.isis.spf.level = spftree->level;
igp.isis.spf.run_id = spftree->runcount;
- ret = zclient_send_opaque_unicast(zclient, LDP_RLFA_UNREGISTER_ALL,
+ ret = zclient_send_opaque_unicast(isis_zclient, LDP_RLFA_UNREGISTER_ALL,
ZEBRA_ROUTE_LDP, 0, 0,
(const uint8_t *)&igp, sizeof(igp));
if (ret == ZCLIENT_SEND_FAILURE)
@@ -774,27 +774,27 @@ int isis_zebra_label_manager_connect(void)
void isis_zebra_vrf_register(struct isis *isis)
{
- if (!zclient || zclient->sock < 0 || !isis)
+ if (!isis_zclient || isis_zclient->sock < 0 || !isis)
return;
if (isis->vrf_id != VRF_UNKNOWN) {
if (IS_DEBUG_EVENTS)
zlog_debug("%s: Register VRF %s id %u", __func__,
isis->name, isis->vrf_id);
- zclient_send_reg_requests(zclient, isis->vrf_id);
+ zclient_send_reg_requests(isis_zclient, isis->vrf_id);
}
}
void isis_zebra_vrf_deregister(struct isis *isis)
{
- if (!zclient || zclient->sock < 0 || !isis)
+ if (!isis_zclient || isis_zclient->sock < 0 || !isis)
return;
if (isis->vrf_id != VRF_UNKNOWN) {
if (IS_DEBUG_EVENTS)
zlog_debug("%s: Deregister VRF %s id %u", __func__,
isis->name, isis->vrf_id);
- zclient_send_dereg_requests(zclient, isis->vrf_id);
+ zclient_send_dereg_requests(isis_zclient, isis->vrf_id);
}
}
@@ -820,9 +820,9 @@ int isis_zebra_ls_register(bool up)
int rc;
if (up)
- rc = ls_register(zclient, true);
+ rc = ls_register(isis_zclient, true);
else
- rc = ls_unregister(zclient, true);
+ rc = ls_unregister(isis_zclient, true);
return rc;
}
@@ -934,7 +934,7 @@ static void isis_zebra_send_localsid(int cmd, const struct in6_addr *sid,
memcpy(&api.prefix, &p, sizeof(p));
if (cmd == ZEBRA_ROUTE_DELETE)
- return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, zclient,
+ return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, isis_zclient,
&api);
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
@@ -952,7 +952,7 @@ static void isis_zebra_send_localsid(int cmd, const struct in6_addr *sid,
api.nexthop_num = 1;
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, isis_zclient, &api);
}
/**
@@ -1007,6 +1007,10 @@ void isis_zebra_srv6_sid_install(struct isis_area *area,
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1072,6 +1076,10 @@ void isis_zebra_srv6_sid_uninstall(struct isis_area *area,
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1145,6 +1153,10 @@ void isis_zebra_srv6_adj_sid_install(struct srv6_adjacency *sra)
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1199,6 +1211,10 @@ void isis_zebra_srv6_adj_sid_uninstall(struct srv6_adjacency *sra)
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
default:
zlog_err(
"ISIS-SRv6 (%s): unsupported SRv6 endpoint behavior %u",
@@ -1372,7 +1388,7 @@ static int isis_zebra_process_srv6_locator_delete(ZAPI_CALLBACK_ARGS)
*/
int isis_zebra_srv6_manager_get_locator_chunk(const char *name)
{
- return srv6_manager_get_locator_chunk(zclient, name);
+ return srv6_manager_get_locator_chunk(isis_zclient, name);
}
@@ -1385,7 +1401,7 @@ int isis_zebra_srv6_manager_get_locator_chunk(const char *name)
*/
int isis_zebra_srv6_manager_release_locator_chunk(const char *name)
{
- return srv6_manager_release_locator_chunk(zclient, name);
+ return srv6_manager_release_locator_chunk(isis_zclient, name);
}
/**
@@ -1403,7 +1419,7 @@ int isis_zebra_srv6_manager_get_locator(const char *name)
* Send the Get Locator request to the SRv6 Manager and return the
* result
*/
- return srv6_manager_get_locator(zclient, name);
+ return srv6_manager_get_locator(isis_zclient, name);
}
/**
@@ -1434,7 +1450,7 @@ bool isis_zebra_request_srv6_sid(const struct srv6_sid_ctx *ctx,
* Send the Get SRv6 SID request to the SRv6 Manager and check the
* result
*/
- ret = srv6_manager_get_sid(zclient, ctx, sid_value, locator_name, NULL);
+ ret = srv6_manager_get_sid(isis_zclient, ctx, sid_value, locator_name, NULL);
if (ret < 0) {
zlog_warn("%s: error getting SRv6 SID!", __func__);
return false;
@@ -1462,7 +1478,7 @@ void isis_zebra_release_srv6_sid(const struct srv6_sid_ctx *ctx)
* Send the Release SRv6 SID request to the SRv6 Manager and check the
* result
*/
- ret = srv6_manager_release_sid(zclient, ctx);
+ ret = srv6_manager_release_sid(isis_zclient, ctx);
if (ret < 0) {
zlog_warn("%s: error releasing SRv6 SID!", __func__);
return;
@@ -1533,6 +1549,7 @@ static int isis_zebra_srv6_sid_notify(ZAPI_CALLBACK_ARGS)
isis_zebra_srv6_sid_uninstall(area, sid);
listnode_delete(area->srv6db.srv6_sids,
sid);
+ isis_srv6_sid_free(sid);
}
/* Allocate new SRv6 End SID */
@@ -1631,16 +1648,16 @@ static zclient_handler *const isis_handlers[] = {
[ZEBRA_SRV6_SID_NOTIFY] = isis_zebra_srv6_sid_notify,
};
-void isis_zebra_init(struct event_loop *master, int instance)
+void isis_zebra_init(struct event_loop *mst, int instance)
{
/* Initialize asynchronous zclient. */
- zclient = zclient_new(master, &zclient_options_default, isis_handlers,
+ isis_zclient = zclient_new(mst, &zclient_options_default, isis_handlers,
array_size(isis_handlers));
- zclient_init(zclient, PROTO_TYPE, 0, &isisd_privs);
- zclient->zebra_connected = isis_zebra_connected;
+ zclient_init(isis_zclient, PROTO_TYPE, 0, &isisd_privs);
+ isis_zclient->zebra_connected = isis_zebra_connected;
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
+ zclient_sync = zclient_new(mst, &zclient_options_sync, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_ISIS;
zclient_sync->instance = instance;
@@ -1654,11 +1671,11 @@ void isis_zebra_init(struct event_loop *master, int instance)
void isis_zebra_stop(void)
{
- zclient_unregister_opaque(zclient, LDP_RLFA_LABELS);
- zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
- zclient_unregister_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
+ zclient_unregister_opaque(isis_zclient, LDP_RLFA_LABELS);
+ zclient_unregister_opaque(isis_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
+ zclient_unregister_opaque(isis_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
zclient_stop(zclient_sync);
zclient_free(zclient_sync);
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(isis_zclient);
+ zclient_free(isis_zclient);
}
diff --git a/isisd/isis_zebra.h b/isisd/isis_zebra.h
index 79da16efac..83a71b7dc9 100644
--- a/isisd/isis_zebra.h
+++ b/isisd/isis_zebra.h
@@ -11,7 +11,7 @@
#include "isisd.h"
-extern struct zclient *zclient;
+extern struct zclient *isis_zclient;
struct label_chunk {
uint32_t start;
diff --git a/isisd/isisd.c b/isisd/isisd.c
index a0faf31221..2260ba664f 100644
--- a/isisd/isisd.c
+++ b/isisd/isisd.c
@@ -187,12 +187,12 @@ struct isis *isis_lookup_by_sysid(const uint8_t *sysid)
return NULL;
}
-void isis_master_init(struct event_loop *master)
+void isis_master_init(struct event_loop *mst)
{
memset(&isis_master, 0, sizeof(isis_master));
im = &isis_master;
im->isis = list_new();
- im->master = master;
+ im->master = mst;
}
void isis_master_terminate(void)
@@ -694,24 +694,24 @@ static void isis_set_redist_vrf_bitmaps(struct isis *isis, bool set)
if (type == DEFAULT_ROUTE) {
if (set)
vrf_bitmap_set(
- &zclient->default_information
+ &isis_zclient->default_information
[afi],
isis->vrf_id);
else
vrf_bitmap_unset(
- &zclient->default_information
+ &isis_zclient->default_information
[afi],
isis->vrf_id);
} else {
if (set)
vrf_bitmap_set(
- &zclient->redist
+ &isis_zclient->redist
[afi]
[type],
isis->vrf_id);
else
vrf_bitmap_unset(
- &zclient->redist
+ &isis_zclient->redist
[afi]
[type],
isis->vrf_id);
diff --git a/ldpd/lde.c b/ldpd/lde.c
index 876dd41630..b0f9e5191f 100644
--- a/ldpd/lde.c
+++ b/ldpd/lde.c
@@ -538,8 +538,8 @@ static void lde_dispatch_parent(struct event *thread)
sizeof(struct ldpd_init))
fatalx("INIT imsg with wrong len");
- memcpy(&init, imsg.data, sizeof(init));
- lde_init(&init);
+ memcpy(&ldp_init, imsg.data, sizeof(ldp_init));
+ lde_init(&ldp_init);
break;
case IMSG_AGENTX_ENABLED:
ldp_agentx_enabled();
diff --git a/ldpd/ldp_snmp.c b/ldpd/ldp_snmp.c
index ed391ac600..2e7933f95c 100644
--- a/ldpd/ldp_snmp.c
+++ b/ldpd/ldp_snmp.c
@@ -620,10 +620,10 @@ static uint8_t *ldpHelloAdjacencyTable(struct variable *v, oid name[], size_t *l
memcpy(name, v->name, v->namelen * sizeof(oid));
/* Append index */
- struct in_addr entityLdpId = {.s_addr = 0};
+ entityLdpId.s_addr = 0;
entityLdpId.s_addr = ldp_rtr_id_get(leconf);
- struct in_addr peerLdpId = ctl_adj->id;
+ peerLdpId = ctl_adj->id;
oid_copy_in_addr(name + v->namelen, &entityLdpId);
name[v->namelen + 4] = 0;
diff --git a/ldpd/ldp_vty_exec.c b/ldpd/ldp_vty_exec.c
index f3bcd1b254..20b60bd373 100644
--- a/ldpd/ldp_vty_exec.c
+++ b/ldpd/ldp_vty_exec.c
@@ -1954,10 +1954,9 @@ ldp_vty_show_interface(struct vty *vty, const char *af_str, const char *json)
return (ldp_vty_dispatch(vty, &ibuf, SHOW_IFACE, &params));
}
-int
-ldp_vty_show_capabilities(struct vty *vty, const char *json)
+int ldp_vty_show_capabilities(struct vty *vty, const char *use_json)
{
- if (json) {
+ if (use_json) {
json_object *json;
json_object *json_array;
json_object *json_cap;
diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c
index df682a1347..cf7ebdff41 100644
--- a/ldpd/ldp_zebra.c
+++ b/ldpd/ldp_zebra.c
@@ -38,7 +38,7 @@ static int ldp_sync_zebra_send_announce(void);
static int ldp_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS);
static void ldp_sync_zebra_init(void);
-static struct zclient *zclient;
+static struct zclient *ldp_zclient;
extern struct zclient *zclient_sync;
static bool zebra_registered = false;
@@ -100,23 +100,23 @@ pw2zpw(struct l2vpn_pw *pw, struct zapi_pw *zpw)
static void
ldp_zebra_opaque_register(void)
{
- zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
- zclient_register_opaque(zclient, LDP_RLFA_REGISTER);
- zclient_register_opaque(zclient, LDP_RLFA_UNREGISTER_ALL);
+ zclient_register_opaque(ldp_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
+ zclient_register_opaque(ldp_zclient, LDP_RLFA_REGISTER);
+ zclient_register_opaque(ldp_zclient, LDP_RLFA_UNREGISTER_ALL);
}
static void
ldp_zebra_opaque_unregister(void)
{
- zclient_unregister_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
- zclient_unregister_opaque(zclient, LDP_RLFA_REGISTER);
- zclient_unregister_opaque(zclient, LDP_RLFA_UNREGISTER_ALL);
+ zclient_unregister_opaque(ldp_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST);
+ zclient_unregister_opaque(ldp_zclient, LDP_RLFA_REGISTER);
+ zclient_unregister_opaque(ldp_zclient, LDP_RLFA_UNREGISTER_ALL);
}
int
ldp_sync_zebra_send_state_update(struct ldp_igp_sync_if_state *state)
{
- if (zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE,
+ if (zclient_send_opaque(ldp_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE,
(const uint8_t *)state, sizeof(*state))
== ZCLIENT_SEND_FAILURE)
return -1;
@@ -130,9 +130,9 @@ ldp_sync_zebra_send_announce(void)
struct ldp_igp_sync_announce announce;
announce.proto = ZEBRA_ROUTE_LDP;
- if (zclient_send_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE,
- (const uint8_t *)&announce, sizeof(announce))
- == ZCLIENT_SEND_FAILURE)
+ if (zclient_send_opaque(ldp_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE,
+ (const uint8_t *)&announce,
+ sizeof(announce)) == ZCLIENT_SEND_FAILURE)
return -1;
else
return 0;
@@ -142,7 +142,7 @@ int ldp_zebra_send_rlfa_labels(struct zapi_rlfa_response *rlfa_labels)
{
int ret;
- ret = zclient_send_opaque(zclient, LDP_RLFA_LABELS,
+ ret = zclient_send_opaque(ldp_zclient, LDP_RLFA_LABELS,
(const uint8_t *)rlfa_labels,
sizeof(*rlfa_labels));
if (ret == ZCLIENT_SEND_FAILURE) {
@@ -271,7 +271,7 @@ ldp_zebra_send_mpls_labels(int cmd, struct kroute *kr)
znh->label_num = 1;
znh->labels[0] = kr->remote_label;
- if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
+ if (zebra_send_mpls_labels(ldp_zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
return -1;
return 0;
@@ -295,7 +295,7 @@ kmpw_add(struct zapi_pw *zpw)
debug_zebra_out("pseudowire %s nexthop %s (add)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
- return zebra_send_pw(zclient, ZEBRA_PW_ADD, zpw) == ZCLIENT_SEND_FAILURE;
+ return zebra_send_pw(ldp_zclient, ZEBRA_PW_ADD, zpw) == ZCLIENT_SEND_FAILURE;
}
int
@@ -304,7 +304,7 @@ kmpw_del(struct zapi_pw *zpw)
debug_zebra_out("pseudowire %s nexthop %s (del)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
- return zebra_send_pw(zclient, ZEBRA_PW_DELETE, zpw) == ZCLIENT_SEND_FAILURE;
+ return zebra_send_pw(ldp_zclient, ZEBRA_PW_DELETE, zpw) == ZCLIENT_SEND_FAILURE;
}
int
@@ -314,7 +314,7 @@ kmpw_set(struct zapi_pw *zpw)
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop),
zpw->local_label, zpw->remote_label);
- return zebra_send_pw(zclient, ZEBRA_PW_SET, zpw) == ZCLIENT_SEND_FAILURE;
+ return zebra_send_pw(ldp_zclient, ZEBRA_PW_SET, zpw) == ZCLIENT_SEND_FAILURE;
}
int
@@ -323,7 +323,7 @@ kmpw_unset(struct zapi_pw *zpw)
debug_zebra_out("pseudowire %s nexthop %s (unset)",
zpw->ifname, log_addr(zpw->af, (union ldpd_addr *)&zpw->nexthop));
- return zebra_send_pw(zclient, ZEBRA_PW_UNSET, zpw) == ZCLIENT_SEND_FAILURE;
+ return zebra_send_pw(ldp_zclient, ZEBRA_PW_UNSET, zpw) == ZCLIENT_SEND_FAILURE;
}
void
@@ -620,18 +620,18 @@ void ldp_zebra_regdereg_zebra_info(bool want_register)
want_register ? "Register" : "De-register");
if (want_register) {
- zclient_send_reg_requests(zclient, VRF_DEFAULT);
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
+ zclient_send_reg_requests(ldp_zclient, VRF_DEFAULT);
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ldp_zclient, AFI_IP,
ZEBRA_ROUTE_ALL, 0, VRF_DEFAULT);
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ldp_zclient,
AFI_IP6, ZEBRA_ROUTE_ALL, 0,
VRF_DEFAULT);
} else {
- zclient_send_dereg_requests(zclient, VRF_DEFAULT);
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ zclient_send_dereg_requests(ldp_zclient, VRF_DEFAULT);
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ldp_zclient,
AFI_IP, ZEBRA_ROUTE_ALL, 0,
VRF_DEFAULT);
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ldp_zclient,
AFI_IP6, ZEBRA_ROUTE_ALL, 0,
VRF_DEFAULT);
}
@@ -678,7 +678,7 @@ static zclient_handler *const ldp_handlers[] = {
[ZEBRA_OPAQUE_MESSAGE] = ldp_zebra_opaque_msg_handler,
};
-void ldp_zebra_init(struct event_loop *master)
+void ldp_zebra_init(struct event_loop *mst)
{
hook_register_prio(if_real, 0, ldp_ifp_create);
hook_register_prio(if_up, 0, ldp_ifp_up);
@@ -686,12 +686,12 @@ void ldp_zebra_init(struct event_loop *master)
hook_register_prio(if_unreal, 0, ldp_ifp_destroy);
/* Set default values. */
- zclient = zclient_new(master, &zclient_options_default, ldp_handlers,
- array_size(ldp_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
+ ldp_zclient = zclient_new(mst, &zclient_options_default, ldp_handlers,
+ array_size(ldp_handlers));
+ zclient_init(ldp_zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs);
/* set callbacks */
- zclient->zebra_connected = ldp_zebra_connected;
+ ldp_zclient->zebra_connected = ldp_zebra_connected;
/* Access list initialize. */
access_list_add_hook(ldp_zebra_filter_update);
@@ -702,9 +702,9 @@ void
ldp_zebra_destroy(void)
{
ldp_zebra_opaque_unregister();
- zclient_stop(zclient);
- zclient_free(zclient);
- zclient = NULL;
+ zclient_stop(ldp_zclient);
+ zclient_free(ldp_zclient);
+ ldp_zclient = NULL;
if (zclient_sync == NULL)
return;
diff --git a/ldpd/ldpd.c b/ldpd/ldpd.c
index 4d38fdcd02..e4e1dc6fec 100644
--- a/ldpd/ldpd.c
+++ b/ldpd/ldpd.c
@@ -74,7 +74,7 @@ DEFINE_QOBJ_TYPE(ldpd_conf);
const char *log_procname;
struct ldpd_global global;
-struct ldpd_init init;
+struct ldpd_init ldp_init;
struct ldpd_conf *ldpd_conf, *vty_conf;
static struct imsgev *iev_ldpe, *iev_ldpe_sync;
@@ -272,8 +272,8 @@ main(int argc, char *argv[])
"%s/" LDPD_SOCK_NAME, optarg);
break;
case 'n':
- init.instance = atoi(optarg);
- if (init.instance < 1)
+ ldp_init.instance = atoi(optarg);
+ if (ldp_init.instance < 1)
exit(0);
break;
case 'L':
@@ -291,11 +291,11 @@ main(int argc, char *argv[])
snprintf(ctl_sock_path, sizeof(ctl_sock_path),
"%s/" LDPD_SOCK_NAME, frr_runstatedir);
- strlcpy(init.user, ldpd_privs.user, sizeof(init.user));
- strlcpy(init.group, ldpd_privs.group, sizeof(init.group));
- strlcpy(init.ctl_sock_path, ctl_sock_path, sizeof(init.ctl_sock_path));
- strlcpy(init.zclient_serv_path, frr_zclientpath,
- sizeof(init.zclient_serv_path));
+ strlcpy(ldp_init.user, ldpd_privs.user, sizeof(ldp_init.user));
+ strlcpy(ldp_init.group, ldpd_privs.group, sizeof(ldp_init.group));
+ strlcpy(ldp_init.ctl_sock_path, ctl_sock_path, sizeof(ldp_init.ctl_sock_path));
+ strlcpy(ldp_init.zclient_serv_path, frr_zclientpath,
+ sizeof(ldp_init.zclient_serv_path));
argc -= optind;
if (argc > 0 || (lflag && eflag))
@@ -428,7 +428,7 @@ main(int argc, char *argv[])
fatal("could not establish imsg links");
main_imsg_compose_both(IMSG_DEBUG_UPDATE, &ldp_debug, sizeof(ldp_debug));
- main_imsg_compose_both(IMSG_INIT, &init, sizeof(init));
+ main_imsg_compose_both(IMSG_INIT, &ldp_init, sizeof(ldp_init));
main_imsg_send_config(ldpd_conf);
if (CHECK_FLAG(ldpd_conf->ipv4.flags, F_LDPD_AF_ENABLED))
diff --git a/ldpd/ldpd.h b/ldpd/ldpd.h
index ad831a6ea3..700c388724 100644
--- a/ldpd/ldpd.h
+++ b/ldpd/ldpd.h
@@ -739,7 +739,7 @@ struct ctl_ldp_sync {
extern struct ldpd_conf *ldpd_conf, *vty_conf;
extern struct ldpd_global global;
-extern struct ldpd_init init;
+extern struct ldpd_init ldp_init;
/* parse.y */
struct ldpd_conf *parse_config(char *);
diff --git a/ldpd/ldpe.c b/ldpd/ldpe.c
index 0a3a03bc38..50875e644d 100644
--- a/ldpd/ldpe.c
+++ b/ldpd/ldpe.c
@@ -373,8 +373,8 @@ static void ldpe_dispatch_main(struct event *thread)
if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(struct ldpd_init))
fatalx("INIT imsg with wrong len");
- memcpy(&init, imsg.data, sizeof(init));
- ldpe_init(&init);
+ memcpy(&ldp_init, imsg.data, sizeof(ldp_init));
+ ldpe_init(&ldp_init);
break;
case IMSG_AGENTX_ENABLED:
ldp_agentx_enabled();
diff --git a/lib/affinitymap.c b/lib/affinitymap.c
index 6ff8e83f91..10b339364b 100644
--- a/lib/affinitymap.c
+++ b/lib/affinitymap.c
@@ -127,3 +127,12 @@ void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
{
affinity_map_master.update_hook = func;
}
+
+void affinity_map_terminate(void)
+{
+ struct affinity_map *map;
+ struct listnode *node, *nnode;
+
+ for (ALL_LIST_ELEMENTS(affinity_map_master.maps, node, nnode, map))
+ affinity_map_free(map);
+}
diff --git a/lib/affinitymap.h b/lib/affinitymap.h
index ebe2659bf7..efac1d6423 100644
--- a/lib/affinitymap.h
+++ b/lib/affinitymap.h
@@ -71,7 +71,7 @@ void affinity_map_set_update_hook(void (*func)(const char *affmap_name,
uint16_t new_pos));
void affinity_map_init(void);
-
+void affinity_map_terminate(void);
#ifdef __cplusplus
}
diff --git a/lib/darr.h b/lib/darr.h
index 4638b904d1..76743cc946 100644
--- a/lib/darr.h
+++ b/lib/darr.h
@@ -511,11 +511,11 @@ void *__darr_resize(void *a, uint count, size_t esize, struct memtype *mt);
*/
#define darr_pop(A) \
({ \
- uint __len = _darr_len(A); \
- assert(__len); \
- darr_remove(A, __len - 1); \
+ uint __poplen = _darr_len(A); \
+ assert(__poplen); \
+ darr_remove(A, __poplen - 1); \
/* count on fact that we don't resize */ \
- (A)[__len - 1]; \
+ (A)[__poplen - 1]; \
})
/**
diff --git a/lib/elf_py.c b/lib/elf_py.c
index 14012a2173..7609ea59c1 100644
--- a/lib/elf_py.c
+++ b/lib/elf_py.c
@@ -518,12 +518,12 @@ static void elfsect_add_relocations(struct elfsect *w, Elf_Scn *rel,
relw->es = w;
if (relhdr->sh_type == SHT_REL) {
- GElf_Rel _rel, *rel;
+ GElf_Rel _rel, *erel;
- rel = gelf_getrel(reldata, i, &_rel);
+ erel = gelf_getrel(reldata, i, &_rel);
relw->rela = &relw->_rela;
- relw->rela->r_offset = rel->r_offset;
- relw->rela->r_info = rel->r_info;
+ relw->rela->r_offset = erel->r_offset;
+ relw->rela->r_info = erel->r_info;
relw->rela->r_addend = 0;
relw->relative = true;
} else
@@ -581,14 +581,14 @@ static PyObject *elfsect_wrap(struct elffile *ef, Elf_Scn *scn, size_t idx,
elfrelocs_init(&w->relocs);
for (i = 0; i < ef->ehdr->e_shnum; i++) {
- Elf_Scn *scn = elf_getscn(ef->elf, i);
- GElf_Shdr _shdr, *shdr = gelf_getshdr(scn, &_shdr);
+ Elf_Scn *escn = elf_getscn(ef->elf, i);
+ GElf_Shdr _shdr, *shdr = gelf_getshdr(escn, &_shdr);
if (shdr->sh_type != SHT_RELA && shdr->sh_type != SHT_REL)
continue;
if (shdr->sh_info && shdr->sh_info != idx)
continue;
- elfsect_add_relocations(w, scn, shdr);
+ elfsect_add_relocations(w, escn, shdr);
}
return (PyObject *)w;
diff --git a/lib/filter_cli.c b/lib/filter_cli.c
index b3ad5fb46d..6d8d288d81 100644
--- a/lib/filter_cli.c
+++ b/lib/filter_cli.c
@@ -1400,10 +1400,14 @@ DEFPY_YANG(
snprintf(xpath, sizeof(xpath),
"/frr-filter:lib/prefix-list[type='ipv6'][name='%s']", name);
if (seq_str == NULL) {
- /* Use XPath to find the next sequence number. */
- sseq = acl_get_seq(vty, xpath, false);
- if (sseq < 0)
- return CMD_WARNING_CONFIG_FAILED;
+ if (plist_is_dup(vty->candidate_config->dnode, &pda))
+ sseq = pda.pda_seq;
+ else {
+ /* Use XPath to find the next sequence number. */
+ sseq = acl_get_seq(vty, xpath, false);
+ if (sseq < 0)
+ return CMD_WARNING_CONFIG_FAILED;
+ }
snprintfrr(xpath_entry, sizeof(xpath_entry),
"%s/entry[sequence='%" PRId64 "']", xpath, sseq);
diff --git a/lib/frr_pthread.h b/lib/frr_pthread.h
index bb751b7071..368ada36ad 100644
--- a/lib/frr_pthread.h
+++ b/lib/frr_pthread.h
@@ -233,11 +233,13 @@ int frr_pthread_non_controlled_startup(pthread_t thread, const char *name,
unused, cleanup(_frr_mtx_unlock))) = _frr_mtx_lock(mutex), \
/* end */
-#define frr_with_mutex(...) \
- for (pthread_mutex_t MACRO_REPEAT(_frr_with_mutex, ##__VA_ARGS__) \
- *_once = NULL; _once == NULL; _once = (void *)1) \
+#define _frr_with_mutex_once(_once, ...) \
+ for (pthread_mutex_t MACRO_REPEAT(_frr_with_mutex, ##__VA_ARGS__)*_once = NULL; \
+ _once == NULL; _once = (void *)1) \
/* end */
+#define frr_with_mutex(...) _frr_with_mutex_once(NAMECTR(_once_), __VA_ARGS__)
+
/* variant 2:
* (more suitable for long blocks, no extra indentation)
*
diff --git a/lib/libfrr.c b/lib/libfrr.c
index 8a37b51c47..d40624a102 100644
--- a/lib/libfrr.c
+++ b/lib/libfrr.c
@@ -1192,9 +1192,10 @@ void frr_detach(void)
frr_check_detach();
}
-void frr_run(struct event_loop *master)
+void frr_run(struct event_loop *loop)
{
char instanceinfo[64] = "";
+ struct event thread;
if (!(di->flags & FRR_MANUAL_VTY_START))
frr_vty_serv_start(false);
@@ -1212,7 +1213,7 @@ void frr_run(struct event_loop *master)
vty_stdio(frr_terminal_close);
if (daemon_ctl_sock != -1) {
set_nonblocking(daemon_ctl_sock);
- event_add_read(master, frr_daemon_ctl, NULL,
+ event_add_read(loop, frr_daemon_ctl, NULL,
daemon_ctl_sock, &daemon_ctl_thread);
}
} else if (di->daemon_mode) {
@@ -1242,8 +1243,7 @@ void frr_run(struct event_loop *master)
/* end fixed stderr startup logging */
zlog_startup_end();
- struct event thread;
- while (event_fetch(master, &thread))
+ while (event_fetch(loop, &thread))
event_call(&thread);
}
diff --git a/lib/link_state.c b/lib/link_state.c
index 3d96c75f6d..27cc2558f5 100644
--- a/lib/link_state.c
+++ b/lib/link_state.c
@@ -2555,9 +2555,9 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
if (CHECK_FLAG(attr->flags, LS_ATTR_UNRSV_BW)) {
jbw = json_object_new_array();
json_object_object_add(jte, "unreserved-bandwidth", jbw);
- for (int i = 0; i < MAX_CLASS_TYPE; i++) {
+ for (i = 0; i < MAX_CLASS_TYPE; i++) {
jobj = json_object_new_object();
- snprintfrr(buf, 13, "class-type-%u", i);
+ snprintfrr(buf, 13, "class-type-%u", (unsigned int)i);
json_object_double_add(jobj, buf,
attr->standard.unrsv_bw[i]);
json_object_array_add(jbw, jobj);
@@ -2599,7 +2599,7 @@ static void ls_show_edge_json(struct ls_edge *edge, struct json_object *json)
if (CHECK_FLAG(attr->flags, LS_ATTR_SRLG)) {
jsrlg = json_object_new_array();
json_object_object_add(jte, "srlgs", jsrlg);
- for (int i = 1; i < attr->srlg_len; i++) {
+ for (i = 1; i < attr->srlg_len; i++) {
jobj = json_object_new_object();
json_object_int_add(jobj, "srlg", attr->srlgs[i]);
json_object_array_add(jsrlg, jobj);
diff --git a/lib/linklist.h b/lib/linklist.h
index f922891df9..d86db36f55 100644
--- a/lib/linklist.h
+++ b/lib/linklist.h
@@ -67,7 +67,11 @@ struct list {
#define listcount(X) ((X)->count)
#define list_isempty(X) ((X)->head == NULL && (X)->tail == NULL)
/* return X->data only if X and X->data are not NULL */
-#define listgetdata(X) (assert(X), assert((X)->data != NULL), (X)->data)
+static inline void *listgetdata(const struct listnode *X)
+{
+ assert((X != NULL) && ((X)->data != NULL));
+ return X->data;
+}
/* App is going to manage listnode memory */
#define listset_app_node_mem(X) ((X)->flags |= LINKLIST_FLAG_NODE_MEM_BY_APP)
#define listnode_init(X, val) ((X)->data = (val))
diff --git a/lib/northbound.c b/lib/northbound.c
index f860b83c45..a1e26d2523 100644
--- a/lib/northbound.c
+++ b/lib/northbound.c
@@ -235,8 +235,9 @@ static int nb_node_validate_cb(const struct nb_node *nb_node,
* depends on context (e.g. some daemons might augment "frr-interface"
* while others don't).
*/
- if (!valid && callback_implemented && operation != NB_CB_GET_NEXT
- && operation != NB_CB_GET_KEYS && operation != NB_CB_LOOKUP_ENTRY)
+ if (!valid && callback_implemented && operation != NB_CB_GET_NEXT &&
+ operation != NB_CB_GET_KEYS && operation != NB_CB_LIST_ENTRY_DONE &&
+ operation != NB_CB_LOOKUP_ENTRY)
flog_warn(EC_LIB_NB_CB_UNNEEDED,
"unneeded '%s' callback for '%s'",
nb_cb_operation_name(operation), nb_node->xpath);
@@ -283,6 +284,8 @@ static unsigned int nb_node_validate_cbs(const struct nb_node *nb_node)
state_optional);
error += nb_node_validate_cb(nb_node, NB_CB_GET_KEYS, !!nb_node->cbs.get_keys,
state_optional);
+ error += nb_node_validate_cb(nb_node, NB_CB_LIST_ENTRY_DONE, !!nb_node->cbs.list_entry_done,
+ true);
error += nb_node_validate_cb(nb_node, NB_CB_LOOKUP_ENTRY, !!nb_node->cbs.lookup_entry,
state_optional);
error += nb_node_validate_cb(nb_node, NB_CB_RPC, !!nb_node->cbs.rpc,
@@ -1806,6 +1809,19 @@ int nb_callback_get_keys(const struct nb_node *nb_node, const void *list_entry,
return nb_node->cbs.get_keys(&args);
}
+void nb_callback_list_entry_done(const struct nb_node *nb_node, const void *parent_list_entry,
+ const void *list_entry)
+{
+ if (CHECK_FLAG(nb_node->flags, F_NB_NODE_IGNORE_CFG_CBS) || !nb_node->cbs.list_entry_done)
+ return;
+
+ DEBUGD(&nb_dbg_cbs_state,
+ "northbound callback (list_entry_done): node [%s] parent_list_entry [%p] list_entry [%p]",
+ nb_node->xpath, parent_list_entry, list_entry);
+
+ nb_node->cbs.list_entry_done(parent_list_entry, list_entry);
+}
+
const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
const void *parent_list_entry,
const struct yang_list_keys *keys)
@@ -1943,6 +1959,7 @@ static int nb_callback_configuration(struct nb_context *context,
case NB_CB_GET_ELEM:
case NB_CB_GET_NEXT:
case NB_CB_GET_KEYS:
+ case NB_CB_LIST_ENTRY_DONE:
case NB_CB_LOOKUP_ENTRY:
case NB_CB_RPC:
case NB_CB_NOTIFY:
@@ -2322,6 +2339,7 @@ bool nb_cb_operation_is_valid(enum nb_cb_operation operation,
}
return true;
case NB_CB_GET_KEYS:
+ case NB_CB_LIST_ENTRY_DONE:
case NB_CB_LOOKUP_ENTRY:
switch (snode->nodetype) {
case LYS_LIST:
@@ -2625,6 +2643,8 @@ const char *nb_cb_operation_name(enum nb_cb_operation operation)
return "get_next";
case NB_CB_GET_KEYS:
return "get_keys";
+ case NB_CB_LIST_ENTRY_DONE:
+ return "list_entry_done";
case NB_CB_LOOKUP_ENTRY:
return "lookup_entry";
case NB_CB_RPC:
diff --git a/lib/northbound.h b/lib/northbound.h
index 0468c58de3..53abf90a9f 100644
--- a/lib/northbound.h
+++ b/lib/northbound.h
@@ -98,6 +98,7 @@ enum nb_cb_operation {
NB_CB_GET_ELEM,
NB_CB_GET_NEXT,
NB_CB_GET_KEYS,
+ NB_CB_LIST_ENTRY_DONE,
NB_CB_LOOKUP_ENTRY,
NB_CB_RPC,
NB_CB_NOTIFY,
@@ -518,6 +519,24 @@ struct nb_callbacks {
/*
* Operational data callback for YANG lists.
*
+ * This callback function is called to cleanup any resources that may be
+ * held by a backend opaque `list_entry` value (e.g., a lock). It is
+ * called when the northbound code is done using a `list_entry` value it
+ * obtained using the lookup_entry() callback. It is also called on the
+ * `list_entry` returned from the get_next() or lookup_next() callbacks
+ * if the iteration aborts before walking to the end of the list. The
+ * intention is to allow any resources (e.g., a lock) to now be
+ * released.
+ *
+ * args
+ * parent_list_entry - pointer to the parent list entry
+ * list_entry - value returned previously from `lookup_entry()`
+ */
+ void (*list_entry_done)(const void *parent_list_entry, const void *list_entry);
+
+ /*
+ * Operational data callback for YANG lists.
+ *
* The callback function should return a list entry based on the list
* keys given as a parameter. Keyless lists don't need to implement this
* callback.
@@ -883,6 +902,8 @@ extern int nb_callback_get_keys(const struct nb_node *nb_node,
extern const void *nb_callback_lookup_entry(const struct nb_node *nb_node,
const void *parent_list_entry,
const struct yang_list_keys *keys);
+extern void nb_callback_list_entry_done(const struct nb_node *nb_node,
+ const void *parent_list_entry, const void *list_entry);
extern const void *nb_callback_lookup_node_entry(struct lyd_node *node,
const void *parent_list_entry);
extern const void *nb_callback_lookup_next(const struct nb_node *nb_node,
diff --git a/lib/northbound_oper.c b/lib/northbound_oper.c
index 626c37082e..0ce9d77259 100644
--- a/lib/northbound_oper.c
+++ b/lib/northbound_oper.c
@@ -139,6 +139,9 @@ static const void *nb_op_list_get_next(struct nb_op_yield_state *ys, struct nb_n
static const void *nb_op_list_lookup_entry(struct nb_op_yield_state *ys, struct nb_node *nb_node,
const struct nb_op_node_info *pni, struct lyd_node *node,
const struct yang_list_keys *keys);
+static void nb_op_list_list_entry_done(struct nb_op_yield_state *ys, struct nb_node *nb_node,
+ const struct nb_op_node_info *pni, const void *list_entry);
+static void ys_pop_inner(struct nb_op_yield_state *ys);
/* -------------------- */
/* Function Definitions */
@@ -157,6 +160,7 @@ nb_op_create_yield_state(const char *xpath, struct yang_translator *translator,
/* remove trailing '/'s */
while (darr_len(ys->xpath) > 1 && ys->xpath[darr_len(ys->xpath) - 2] == '/') {
darr_setlen(ys->xpath, darr_len(ys->xpath) - 1);
+ assert(darr_last(ys->xpath)); /* quiet clang-analyzer :( */
*darr_last(ys->xpath) = 0;
}
ys->xpath_orig = darr_strdup(xpath);
@@ -188,6 +192,9 @@ static inline void nb_op_free_yield_state(struct nb_op_yield_state *ys,
darr_free(ys->non_specific_predicate);
darr_free(ys->query_tokstr);
darr_free(ys->schema_path);
+ /* need to cleanup resources, so pop these individually */
+ while (darr_len(ys->node_infos))
+ ys_pop_inner(ys);
darr_free(ys->node_infos);
darr_free(ys->xpath_orig);
darr_free(ys->xpath);
@@ -222,10 +229,20 @@ static void ys_trim_xpath(struct nb_op_yield_state *ys)
static void ys_pop_inner(struct nb_op_yield_state *ys)
{
- uint len = darr_len(ys->node_infos);
+ struct nb_op_node_info *ni, *pni;
+ struct nb_node *nb_node;
+ int i = darr_lasti(ys->node_infos);
- assert(len);
- darr_setlen(ys->node_infos, len - 1);
+ pni = i > 0 ? &ys->node_infos[i - 1] : NULL;
+ ni = &ys->node_infos[i];
+
+ /* list_entry's propagate so only free the first occurance */
+ if (ni->list_entry && (!pni || pni->list_entry != ni->list_entry)) {
+ nb_node = ni->schema ? ni->schema->priv : NULL;
+ if (nb_node)
+ nb_op_list_list_entry_done(ys, nb_node, pni, ni->list_entry);
+ }
+ darr_setlen(ys->node_infos, i);
ys_trim_xpath(ys);
}
@@ -872,6 +889,14 @@ static enum nb_error nb_op_list_get_keys(struct nb_op_yield_state *ys, struct nb
return 0;
}
+static void nb_op_list_list_entry_done(struct nb_op_yield_state *ys, struct nb_node *nb_node,
+ const struct nb_op_node_info *pni, const void *list_entry)
+{
+ if (CHECK_FLAG(nb_node->flags, F_NB_NODE_HAS_GET_TREE))
+ return;
+
+ nb_callback_list_entry_done(nb_node, pni ? pni->list_entry : NULL, list_entry);
+}
/**
* nb_op_add_leaf() - Add leaf data to the get tree results
@@ -1153,8 +1178,8 @@ static const struct lysc_node *nb_op_sib_first(struct nb_op_yield_state *ys,
*
* If the schema path (original query) is longer than our current node
* info stack (current xpath location), we are building back up to the
- * base of the user query, return the next schema node from the query
- * string (schema_path).
+ * base of the walk at the end of the user query path, return the next
+ * schema node from the query string (schema_path).
*/
if (last != NULL)
assert(last->schema == parent);
@@ -1525,6 +1550,18 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
*/
assert(!list_start);
is_specific_node = true;
+
+ /*
+ * Release the entry back to the daemon
+ */
+ assert(ni->list_entry == list_entry);
+ nb_op_list_list_entry_done(ys, nn, pni, list_entry);
+ ni->list_entry = NULL;
+
+ /*
+ * Continue on as we may reap the resulting node
+ * if empty.
+ */
list_entry = NULL;
}
@@ -1605,6 +1642,18 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
}
/*
+ * The walk API is that get/lookup_next returns NULL
+ * when done, those callbacks are also is responsible
+ * for releasing any state associated with previous
+ * list_entry's (e.g., any locks) during the iteration.
+ * Therefore we need to zero out the last top level
+ * list_entry so we don't mistakenly call the
+ * list_entry_done() callback on it.
+ */
+ if (!is_specific_node && !list_start && !list_entry)
+ ni->list_entry = NULL;
+
+ /*
* (FN:A) Reap empty list element? Check to see if we
* should reap an empty list element. We do this if the
* empty list element exists at or below the query base
@@ -1619,17 +1668,15 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
* have no non-key children, check for this condition
* and do not reap if true.
*/
- if (!list_start && ni->inner &&
- !lyd_child_no_keys(ni->inner) &&
+ if (!list_start && ni->inner && !lyd_child_no_keys(ni->inner) &&
/* not the top element with a key match */
- !((darr_ilen(ys->node_infos) ==
- darr_ilen(ys->schema_path) - 1) &&
+ !(darr_ilen(ys->schema_path) && /* quiet clang-analyzer :( */
+ (darr_ilen(ys->node_infos) == darr_ilen(ys->schema_path) - 1) &&
lysc_is_key((*darr_last(ys->schema_path)))) &&
- /* is this at or below the base? */
- darr_ilen(ys->node_infos) <= ys->query_base_level)
+ /* is this list entry below the query base? */
+ darr_ilen(ys->node_infos) - 1 < ys->query_base_level)
ys_free_inner(ys, ni);
-
if (!list_entry) {
/*
* List Iteration Done
@@ -1724,12 +1771,15 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
ni->xpath_len = len;
}
+ /* Save the new list_entry early so it can be cleaned up on error */
+ ni->list_entry = list_entry;
+ ni->schema = sib;
+
/* Need to get keys. */
if (!CHECK_FLAG(nn->flags, F_NB_NODE_KEYLESS_LIST)) {
ret = nb_op_list_get_keys(ys, nn, list_entry, &ni->keys);
if (ret) {
- darr_pop(ys->node_infos);
ret = NB_ERR_RESOURCE;
goto done;
}
@@ -1764,7 +1814,6 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
.inner,
sib, &ni->keys, &node);
if (err) {
- darr_pop(ys->node_infos);
ret = NB_ERR_RESOURCE;
goto done;
}
@@ -1774,8 +1823,7 @@ static enum nb_error __walk(struct nb_op_yield_state *ys, bool is_resume)
* Save the new list entry with the list node info
*/
ni->inner = node;
- ni->schema = node->schema;
- ni->list_entry = list_entry;
+ assert(ni->schema == node->schema);
ni->niters += 1;
ni->nents += 1;
diff --git a/lib/printf/vfprintf.c b/lib/printf/vfprintf.c
index 3f6700c838..12c4dad683 100644
--- a/lib/printf/vfprintf.c
+++ b/lib/printf/vfprintf.c
@@ -556,23 +556,23 @@ reswitch: switch (ch) {
case 'G':
if (flags & LONGDBL) {
long double arg = GETARG(long double);
- char fmt[6] = "%.*L";
- fmt[4] = ch;
- fmt[5] = '\0';
+ char lfmt[6] = "%.*L";
+ lfmt[4] = ch;
+ lfmt[5] = '\0';
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
- snprintf(buf, sizeof(buf), fmt, prec, arg);
+ snprintf(buf, sizeof(buf), lfmt, prec, arg);
#pragma GCC diagnostic pop
} else {
double arg = GETARG(double);
- char fmt[5] = "%.*";
- fmt[3] = ch;
- fmt[4] = '\0';
+ char lfmt[5] = "%.*";
+ lfmt[3] = ch;
+ lfmt[4] = '\0';
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
- snprintf(buf, sizeof(buf), fmt, prec, arg);
+ snprintf(buf, sizeof(buf), lfmt, prec, arg);
#pragma GCC diagnostic pop
}
cp = buf;
diff --git a/lib/resolver.c b/lib/resolver.c
index 901ccf8132..62b98091ec 100644
--- a/lib/resolver.c
+++ b/lib/resolver.c
@@ -282,7 +282,7 @@ static void resolver_cb_literal(struct event *t)
callback = query->callback;
query->callback = NULL;
- callback(query, ARES_SUCCESS, 1, &query->literal_addr);
+ callback(query, NULL, 1, &query->literal_addr);
}
void resolver_resolve(struct resolver_query *query, int af, vrf_id_t vrf_id,
diff --git a/lib/srv6.h b/lib/srv6.h
index 467f02a3c9..bd80253b55 100644
--- a/lib/srv6.h
+++ b/lib/srv6.h
@@ -179,9 +179,11 @@ enum srv6_endpoint_behavior_codepoint {
SRV6_ENDPOINT_BEHAVIOR_END_PSP = 0x0002,
SRV6_ENDPOINT_BEHAVIOR_END_X = 0x0005,
SRV6_ENDPOINT_BEHAVIOR_END_X_PSP = 0x0006,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS = 0x000E,
SRV6_ENDPOINT_BEHAVIOR_END_DT6 = 0x0012,
SRV6_ENDPOINT_BEHAVIOR_END_DT4 = 0x0013,
SRV6_ENDPOINT_BEHAVIOR_END_DT46 = 0x0014,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED = 0x001B,
SRV6_ENDPOINT_BEHAVIOR_END_PSP_USD = 0x001D,
SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD = 0x0021,
SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID = 0x002B,
@@ -193,6 +195,8 @@ enum srv6_endpoint_behavior_codepoint {
SRV6_ENDPOINT_BEHAVIOR_END_DT6_USID = 0x003E,
SRV6_ENDPOINT_BEHAVIOR_END_DT4_USID = 0x003F,
SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID = 0x0040,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID = 0x005D,
+ SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID = 0x005E,
SRV6_ENDPOINT_BEHAVIOR_OPAQUE = 0xFFFF,
};
@@ -215,6 +219,8 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav
return "End.X";
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP:
return "End.X PSP";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ return "End.B6.Encaps";
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
return "End.X PSP/USD";
case SRV6_ENDPOINT_BEHAVIOR_END_DT6:
@@ -223,6 +229,8 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav
return "End.DT4";
case SRV6_ENDPOINT_BEHAVIOR_END_DT46:
return "End.DT46";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ return "End.B6.Encaps.Red";
case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID:
return "uN";
case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID_PSP:
@@ -241,6 +249,10 @@ srv6_endpoint_behavior_codepoint2str(enum srv6_endpoint_behavior_codepoint behav
return "uDT4";
case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID:
return "uDT46";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ return "uB6.Encaps";
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
+ return "uB6.Encaps.Red";
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
return "Opaque";
}
diff --git a/lib/zclient.c b/lib/zclient.c
index 3e68e962aa..031f454385 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -3014,7 +3014,7 @@ size_t zebra_interface_link_params_write(struct stream *s,
size_t w, nb_ext_adm_grp;
struct if_link_params *iflp;
int i;
-
+ size_t j;
if (s == NULL || ifp == NULL)
return 0;
@@ -3045,8 +3045,8 @@ size_t zebra_interface_link_params_write(struct stream *s,
/* Extended Administrative Group */
nb_ext_adm_grp = admin_group_nb_words(&iflp->ext_admin_grp);
w += stream_putc(s, nb_ext_adm_grp);
- for (size_t i = 0; i < nb_ext_adm_grp; i++)
- stream_putl(s, admin_group_get_offset(&iflp->ext_admin_grp, i));
+ for (j = 0; j < nb_ext_adm_grp; j++)
+ stream_putl(s, admin_group_get_offset(&iflp->ext_admin_grp, j));
w += stream_putl(s, iflp->rmt_as);
w += stream_put_in_addr(s, &iflp->rmt_ip);
diff --git a/mgmtd/mgmt_ds.c b/mgmtd/mgmt_ds.c
index dabae4afd1..3a85525d93 100644
--- a/mgmtd/mgmt_ds.c
+++ b/mgmtd/mgmt_ds.c
@@ -74,8 +74,7 @@ static int mgmt_ds_dump_in_memory(struct mgmt_ds_ctx *ds_ctx,
return 0;
}
-static int mgmt_ds_replace_dst_with_src_ds(struct mgmt_ds_ctx *src,
- struct mgmt_ds_ctx *dst)
+static int ds_copy(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src)
{
if (!src || !dst)
return -1;
@@ -95,8 +94,7 @@ static int mgmt_ds_replace_dst_with_src_ds(struct mgmt_ds_ctx *src,
return 0;
}
-static int mgmt_ds_merge_src_with_dst_ds(struct mgmt_ds_ctx *src,
- struct mgmt_ds_ctx *dst)
+static int ds_merge(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src)
{
int ret;
@@ -151,9 +149,9 @@ void mgmt_ds_reset_candidate(void)
}
-int mgmt_ds_init(struct mgmt_master *mm)
+int mgmt_ds_init(struct mgmt_master *m)
{
- if (mgmt_ds_mm || mm->running_ds || mm->candidate_ds || mm->oper_ds)
+ if (mgmt_ds_mm || m->running_ds || m->candidate_ds || m->oper_ds)
assert(!"MGMTD: Call ds_init only once!");
/* Use Running DS from NB module??? */
@@ -178,10 +176,10 @@ int mgmt_ds_init(struct mgmt_master *mm)
oper.config_ds = false;
oper.ds_id = MGMTD_DS_OPERATIONAL;
- mm->running_ds = &running;
- mm->candidate_ds = &candidate;
- mm->oper_ds = &oper;
- mgmt_ds_mm = mm;
+ m->running_ds = &running;
+ m->candidate_ds = &candidate;
+ m->oper_ds = &oper;
+ mgmt_ds_mm = m;
return 0;
}
@@ -195,16 +193,15 @@ void mgmt_ds_destroy(void)
oper.root.dnode_root = NULL;
}
-struct mgmt_ds_ctx *mgmt_ds_get_ctx_by_id(struct mgmt_master *mm,
- Mgmtd__DatastoreId ds_id)
+struct mgmt_ds_ctx *mgmt_ds_get_ctx_by_id(struct mgmt_master *m, Mgmtd__DatastoreId ds_id)
{
switch (ds_id) {
case MGMTD_DS_CANDIDATE:
- return (mm->candidate_ds);
+ return (m->candidate_ds);
case MGMTD_DS_RUNNING:
- return (mm->running_ds);
+ return (m->running_ds);
case MGMTD_DS_OPERATIONAL:
- return (mm->oper_ds);
+ return (m->oper_ds);
case MGMTD_DS_NONE:
case MGMTD__DATASTORE_ID__STARTUP_DS:
case _MGMTD__DATASTORE_ID_IS_INT_SIZE:
@@ -251,14 +248,13 @@ void mgmt_ds_unlock(struct mgmt_ds_ctx *ds_ctx)
ds_ctx->locked = 0;
}
-int mgmt_ds_copy_dss(struct mgmt_ds_ctx *src_ds_ctx,
- struct mgmt_ds_ctx *dst_ds_ctx, bool updt_cmt_rec)
+int mgmt_ds_copy_dss(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src, bool updt_cmt_rec)
{
- if (mgmt_ds_replace_dst_with_src_ds(src_ds_ctx, dst_ds_ctx) != 0)
+ if (ds_copy(dst, src) != 0)
return -1;
- if (updt_cmt_rec && dst_ds_ctx->ds_id == MGMTD_DS_RUNNING)
- mgmt_history_new_record(dst_ds_ctx);
+ if (updt_cmt_rec && dst->ds_id == MGMTD_DS_RUNNING)
+ mgmt_history_new_record(dst);
return 0;
}
@@ -416,9 +412,9 @@ int mgmt_ds_load_config_from_file(struct mgmt_ds_ctx *dst,
parsed.ds_id = dst->ds_id;
if (merge)
- mgmt_ds_merge_src_with_dst_ds(&parsed, dst);
+ ds_merge(dst, &parsed);
else
- mgmt_ds_replace_dst_with_src_ds(&parsed, dst);
+ ds_copy(dst, &parsed);
nb_config_free(parsed.root.cfg_root);
diff --git a/mgmtd/mgmt_ds.h b/mgmtd/mgmt_ds.h
index b8e77e330a..f7e1d7c5ee 100644
--- a/mgmtd/mgmt_ds.h
+++ b/mgmtd/mgmt_ds.h
@@ -196,21 +196,19 @@ extern void mgmt_ds_unlock(struct mgmt_ds_ctx *ds_ctx);
/*
* Copy from source to destination datastore.
*
- * src_ds
- * Source datastore handle (ds to be copied from).
- *
- * dst_ds
+ * dst
* Destination datastore handle (ds to be copied to).
*
+ * src
+ * Source datastore handle (ds to be copied from).
+ *
* update_cmd_rec
* TRUE if need to update commit record, FALSE otherwise.
*
* Returns:
* 0 on success, -1 on failure.
*/
-extern int mgmt_ds_copy_dss(struct mgmt_ds_ctx *src_ds_ctx,
- struct mgmt_ds_ctx *dst_ds_ctx,
- bool update_cmt_rec);
+extern int mgmt_ds_copy_dss(struct mgmt_ds_ctx *dst, struct mgmt_ds_ctx *src, bool update_cmt_rec);
/*
* Fetch northbound configuration for a given datastore context.
diff --git a/mgmtd/mgmt_fe_adapter.c b/mgmtd/mgmt_fe_adapter.c
index 8d59198803..39686091e1 100644
--- a/mgmtd/mgmt_fe_adapter.c
+++ b/mgmtd/mgmt_fe_adapter.c
@@ -217,12 +217,6 @@ static void
mgmt_fe_session_cfg_txn_cleanup(struct mgmt_fe_session_ctx *session)
{
/*
- * Ensure any uncommitted changes in Candidate DS
- * is discarded.
- */
- mgmt_ds_copy_dss(mm->running_ds, mm->candidate_ds, false);
-
- /*
* Destroy the actual transaction created earlier.
*/
if (session->cfg_txn_id != MGMTD_TXN_ID_NONE)
@@ -1442,7 +1436,6 @@ static void fe_adapter_handle_get_data(struct mgmt_fe_session_ctx *session,
/* Check for yang-library shortcut */
if (nb_oper_is_yang_lib_query(msg->xpath)) {
struct lyd_node *ylib = NULL;
- LY_ERR err;
err = ly_ctx_get_yanglib_data(ly_native_ctx, &ylib, "%u",
ly_ctx_get_change_count(
diff --git a/mgmtd/mgmt_txn.c b/mgmtd/mgmt_txn.c
index 483dfab8e8..96ca62c847 100644
--- a/mgmtd/mgmt_txn.c
+++ b/mgmtd/mgmt_txn.c
@@ -764,17 +764,15 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn,
!txn->commit_cfg_req->req.commit_cfg.rollback);
/*
- * Successful commit: Merge Src DS into Dst DS if and only if
+ * Successful commit: Copy Src DS to Dst DS if and only if
* this was not a validate-only or abort request.
*/
if ((txn->session_id &&
!txn->commit_cfg_req->req.commit_cfg.validate_only &&
!txn->commit_cfg_req->req.commit_cfg.abort) ||
txn->commit_cfg_req->req.commit_cfg.rollback) {
- mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg
- .src_ds_ctx,
- txn->commit_cfg_req->req.commit_cfg
- .dst_ds_ctx,
+ mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx,
+ txn->commit_cfg_req->req.commit_cfg.src_ds_ctx,
create_cmt_info_rec);
}
@@ -783,22 +781,18 @@ static int mgmt_txn_send_commit_cfg_reply(struct mgmt_txn_ctx *txn,
* request.
*/
if (txn->session_id && txn->commit_cfg_req->req.commit_cfg.abort)
- mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg
- .dst_ds_ctx,
- txn->commit_cfg_req->req.commit_cfg
- .src_ds_ctx,
- false);
+ mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg.src_ds_ctx,
+ txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx, false);
} else {
/*
* The commit has failied. For implicit commit requests restore
- * back the contents of the candidate DS.
+ * back the contents of the candidate DS. For non-implicit
+ * commit we want to allow the user to re-commit on the changes
+ * (whether further modified or not).
*/
if (txn->commit_cfg_req->req.commit_cfg.implicit)
- mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg
- .dst_ds_ctx,
- txn->commit_cfg_req->req.commit_cfg
- .src_ds_ctx,
- false);
+ mgmt_ds_copy_dss(txn->commit_cfg_req->req.commit_cfg.src_ds_ctx,
+ txn->commit_cfg_req->req.commit_cfg.dst_ds_ctx, false);
}
if (txn->commit_cfg_req->req.commit_cfg.rollback) {
@@ -1993,17 +1987,17 @@ static void mgmt_txn_register_event(struct mgmt_txn_ctx *txn,
}
}
-int mgmt_txn_init(struct mgmt_master *mm, struct event_loop *tm)
+int mgmt_txn_init(struct mgmt_master *m, struct event_loop *loop)
{
if (mgmt_txn_mm || mgmt_txn_tm)
assert(!"MGMTD TXN: Call txn_init() only once");
- mgmt_txn_mm = mm;
- mgmt_txn_tm = tm;
- mgmt_txns_init(&mm->txn_list);
+ mgmt_txn_mm = m;
+ mgmt_txn_tm = loop;
+ mgmt_txns_init(&m->txn_list);
mgmt_txn_hash_init();
- assert(!mm->cfg_txn);
- mm->cfg_txn = NULL;
+ assert(!m->cfg_txn);
+ m->cfg_txn = NULL;
return 0;
}
diff --git a/nhrpd/nhrp_peer.c b/nhrpd/nhrp_peer.c
index fa11980c18..97932795a3 100644
--- a/nhrpd/nhrp_peer.c
+++ b/nhrpd/nhrp_peer.c
@@ -1355,6 +1355,11 @@ void nhrp_peer_recv(struct nhrp_peer *p, struct zbuf *zb)
}
break;
case NHRP_ROUTE_NBMA_NEXTHOP:
+ if (hdr->hop_count == 0) {
+ nhrp_packet_send_error(&pp, NHRP_ERROR_HOP_COUNT_EXCEEDED, 0);
+ info = "hop count exceeded";
+ goto drop;
+ }
nhrp_peer_forward(peer, &pp);
break;
case NHRP_ROUTE_BLACKHOLE:
diff --git a/nhrpd/nhrp_route.c b/nhrpd/nhrp_route.c
index 7adc4a6399..2e4c7b1eec 100644
--- a/nhrpd/nhrp_route.c
+++ b/nhrpd/nhrp_route.c
@@ -16,7 +16,7 @@
DEFINE_MTYPE_STATIC(NHRPD, NHRP_ROUTE, "NHRP routing entry");
-static struct zclient *zclient;
+static struct zclient *nhrp_zclient;
static struct route_table *zebra_rib[AFI_MAX];
struct route_info {
@@ -95,7 +95,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type,
struct zapi_route api;
struct zapi_nexthop *api_nh;
- if (zclient->sock < 0)
+ if (nhrp_zclient->sock < 0)
return;
memset(&api, 0, sizeof(api));
@@ -196,7 +196,7 @@ void nhrp_route_announce(int add, enum nhrp_cache_type type,
api.metric, api.nexthop_num, ifp ? ifp->name : "none");
}
- zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient,
+ zclient_route_send(add ? ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, nhrp_zclient,
&api);
}
@@ -374,10 +374,10 @@ void nhrp_zebra_init(void)
zebra_rib[AFI_IP] = route_table_init();
zebra_rib[AFI_IP6] = route_table_init();
- zclient = zclient_new(master, &zclient_options_default, nhrp_handlers,
- array_size(nhrp_handlers));
- zclient->zebra_connected = nhrp_zebra_connected;
- zclient_init(zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs);
+ nhrp_zclient = zclient_new(master, &zclient_options_default, nhrp_handlers,
+ array_size(nhrp_handlers));
+ nhrp_zclient->zebra_connected = nhrp_zebra_connected;
+ zclient_init(nhrp_zclient, ZEBRA_ROUTE_NHRP, 0, &nhrpd_privs);
}
static void nhrp_table_node_cleanup(struct route_table *table,
@@ -393,18 +393,18 @@ void nhrp_send_zebra_configure_arp(struct interface *ifp, int family)
{
struct stream *s;
- if (!zclient || zclient->sock < 0) {
+ if (!nhrp_zclient || nhrp_zclient->sock < 0) {
debugf(NHRP_DEBUG_COMMON, "%s() : zclient not ready",
__func__);
return;
}
- s = zclient->obuf;
+ s = nhrp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_CONFIGURE_ARP, ifp->vrf->vrf_id);
stream_putc(s, family);
stream_putl(s, ifp->ifindex);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ zclient_send_message(nhrp_zclient);
}
void nhrp_send_zebra_gre_source_set(struct interface *ifp,
@@ -413,7 +413,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp,
{
struct stream *s;
- if (!zclient || zclient->sock < 0) {
+ if (!nhrp_zclient || nhrp_zclient->sock < 0) {
zlog_err("%s : zclient not ready", __func__);
return;
}
@@ -421,7 +421,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp,
/* silently ignore */
return;
}
- s = zclient->obuf;
+ s = nhrp_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_GRE_SOURCE_SET, ifp->vrf->vrf_id);
stream_putl(s, ifp->ifindex);
@@ -429,7 +429,7 @@ void nhrp_send_zebra_gre_source_set(struct interface *ifp,
stream_putl(s, link_vrf_id);
stream_putl(s, 0); /* mtu provisioning */
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ zclient_send_message(nhrp_zclient);
}
void nhrp_send_zebra_nbr(union sockunion *in,
@@ -438,9 +438,9 @@ void nhrp_send_zebra_nbr(union sockunion *in,
{
struct stream *s;
- if (!zclient || zclient->sock < 0)
+ if (!nhrp_zclient || nhrp_zclient->sock < 0)
return;
- s = zclient->obuf;
+ s = nhrp_zclient->obuf;
stream_reset(s);
zclient_neigh_ip_encode(s, out ? ZEBRA_NEIGH_IP_ADD : ZEBRA_NEIGH_IP_DEL,
in, out, ifp,
@@ -448,26 +448,26 @@ void nhrp_send_zebra_nbr(union sockunion *in,
: ZEBRA_NEIGH_STATE_FAILED,
0);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ zclient_send_message(nhrp_zclient);
}
int nhrp_send_zebra_gre_request(struct interface *ifp)
{
- return zclient_send_zebra_gre_request(zclient, ifp);
+ return zclient_send_zebra_gre_request(nhrp_zclient, ifp);
}
void nhrp_interface_update_arp(struct interface *ifp, bool arp_enable)
{
- zclient_interface_set_arp(zclient, ifp, arp_enable);
+ zclient_interface_set_arp(nhrp_zclient, ifp, arp_enable);
}
void nhrp_zebra_terminate(void)
{
- zclient_register_neigh(zclient, VRF_DEFAULT, AFI_IP, false);
- zclient_register_neigh(zclient, VRF_DEFAULT, AFI_IP6, false);
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_register_neigh(nhrp_zclient, VRF_DEFAULT, AFI_IP, false);
+ zclient_register_neigh(nhrp_zclient, VRF_DEFAULT, AFI_IP6, false);
+ zclient_stop(nhrp_zclient);
+ zclient_free(nhrp_zclient);
zebra_rib[AFI_IP]->cleanup = nhrp_table_node_cleanup;
zebra_rib[AFI_IP6]->cleanup = nhrp_table_node_cleanup;
diff --git a/ospf6d/ospf6_abr.c b/ospf6d/ospf6_abr.c
index 343dfefcec..2cb63d8a29 100644
--- a/ospf6d/ospf6_abr.c
+++ b/ospf6d/ospf6_abr.c
@@ -515,8 +515,6 @@ int ospf6_abr_originate_summary_to_area(struct ospf6_route *route,
summary->path.origin.id =
ADV_ROUTER_IN_PREFIX(&route->prefix);
} else {
- struct ospf6_lsa *old;
-
summary->path.origin.type =
htons(OSPF6_LSTYPE_INTER_PREFIX);
diff --git a/ospf6d/ospf6_area.h b/ospf6d/ospf6_area.h
index 2ed69cc597..16049427ac 100644
--- a/ospf6d/ospf6_area.h
+++ b/ospf6d/ospf6_area.h
@@ -123,16 +123,16 @@ struct ospf6_area {
#define OSPF6_CMD_AREA_GET(str, oa, ospf6) \
{ \
- uint32_t area_id; \
- int format, ret; \
- ret = str2area_id(str, &area_id, &format); \
- if (ret) { \
+ uint32_t _area_id; \
+ int _format, _ret; \
+ _ret = str2area_id(str, &_area_id, &_format); \
+ if (_ret) { \
vty_out(vty, "Malformed Area-ID: %s\n", str); \
return CMD_WARNING; \
} \
- oa = ospf6_area_lookup(area_id, ospf6); \
+ oa = ospf6_area_lookup(_area_id, ospf6); \
if (oa == NULL) \
- oa = ospf6_area_create(area_id, ospf6, format); \
+ oa = ospf6_area_create(_area_id, ospf6, _format); \
}
/* prototypes */
diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c
index 8fa85badbe..df2758b081 100644
--- a/ospf6d/ospf6_asbr.c
+++ b/ospf6d/ospf6_asbr.c
@@ -1899,7 +1899,7 @@ static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate)
break;
case DEFAULT_ORIGINATE_ZEBRA:
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
- zclient, AFI_IP6, ospf6->vrf_id);
+ ospf6_zclient, AFI_IP6, ospf6->vrf_id);
ospf6_asbr_redistribute_remove(DEFAULT_ROUTE, 0,
(struct prefix *)&p, ospf6);
@@ -1915,7 +1915,7 @@ static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate)
break;
case DEFAULT_ORIGINATE_ZEBRA:
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- zclient, AFI_IP6, ospf6->vrf_id);
+ ospf6_zclient, AFI_IP6, ospf6->vrf_id);
break;
case DEFAULT_ORIGINATE_ALWAYS:
diff --git a/ospf6d/ospf6_bfd.c b/ospf6d/ospf6_bfd.c
index 6379f9d992..0b00558572 100644
--- a/ospf6d/ospf6_bfd.c
+++ b/ospf6d/ospf6_bfd.c
@@ -27,8 +27,6 @@
#include "ospf6_zebra.h"
#include "ospf6_bfd.h"
-extern struct zclient *zclient;
-
/*
* ospf6_bfd_trigger_event - Neighbor is registered/deregistered with BFD when
* neighbor state is changed to/from 2way.
@@ -280,7 +278,7 @@ DEFUN (no_ipv6_ospf6_bfd,
void ospf6_bfd_init(void)
{
- bfd_protocol_integration_init(zclient, master);
+ bfd_protocol_integration_init(ospf6_zclient, master);
/* Install BFD command */
install_element(INTERFACE_NODE, &ipv6_ospf6_bfd_cmd);
diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c
index 8320f11f6c..e94f2a1c47 100644
--- a/ospf6d/ospf6_main.c
+++ b/ospf6d/ospf6_main.c
@@ -104,9 +104,9 @@ static void __attribute__((noreturn)) ospf6_exit(int status)
vrf_terminate();
- if (zclient) {
- zclient_stop(zclient);
- zclient_free(zclient);
+ if (ospf6_zclient) {
+ zclient_stop(ospf6_zclient);
+ zclient_free(ospf6_zclient);
}
ospf6_master_delete();
diff --git a/ospf6d/ospf6_snmp.c b/ospf6d/ospf6_snmp.c
index 9ac8b6c1af..037ca9bc0b 100644
--- a/ospf6d/ospf6_snmp.c
+++ b/ospf6d/ospf6_snmp.c
@@ -1382,9 +1382,9 @@ static int ospf6TrapIfStateChange(struct ospf6_interface *oi, int next_state,
}
/* Register OSPFv3-MIB. */
-static int ospf6_snmp_init(struct event_loop *master)
+static int ospf6_snmp_init(struct event_loop *mstr)
{
- smux_init(master);
+ smux_init(mstr);
REGISTER_MIB("OSPFv3MIB", ospfv3_variables, variable, ospfv3_oid);
return 0;
}
diff --git a/ospf6d/ospf6_top.c b/ospf6d/ospf6_top.c
index ad487f3565..9755cc44cc 100644
--- a/ospf6d/ospf6_top.c
+++ b/ospf6d/ospf6_top.c
@@ -142,20 +142,20 @@ static void ospf6_set_redist_vrf_bitmaps(struct ospf6 *ospf6, bool set)
"%s: setting redist vrf %d bitmap for type %d",
__func__, ospf6->vrf_id, type);
if (set)
- vrf_bitmap_set(&zclient->redist[AFI_IP6][type],
+ vrf_bitmap_set(&ospf6_zclient->redist[AFI_IP6][type],
ospf6->vrf_id);
else
- vrf_bitmap_unset(&zclient->redist[AFI_IP6][type],
+ vrf_bitmap_unset(&ospf6_zclient->redist[AFI_IP6][type],
ospf6->vrf_id);
}
red_list = ospf6->redist[DEFAULT_ROUTE];
if (red_list) {
if (set)
- vrf_bitmap_set(&zclient->default_information[AFI_IP6],
+ vrf_bitmap_set(&ospf6_zclient->default_information[AFI_IP6],
ospf6->vrf_id);
else
- vrf_bitmap_unset(&zclient->default_information[AFI_IP6],
+ vrf_bitmap_unset(&ospf6_zclient->default_information[AFI_IP6],
ospf6->vrf_id);
}
}
@@ -566,13 +566,13 @@ static void ospf6_disable(struct ospf6 *o)
}
}
-void ospf6_master_init(struct event_loop *master)
+void ospf6_master_init(struct event_loop *mst)
{
memset(&ospf6_master, 0, sizeof(ospf6_master));
om6 = &ospf6_master;
om6->ospf6 = list_new();
- om6->master = master;
+ om6->master = mst;
}
void ospf6_master_delete(void)
diff --git a/ospf6d/ospf6_top.h b/ospf6d/ospf6_top.h
index 8288413c10..2b29eeae89 100644
--- a/ospf6d/ospf6_top.h
+++ b/ospf6d/ospf6_top.h
@@ -231,7 +231,6 @@ DECLARE_QOBJ_TYPE(ospf6);
#define OSPF6_STUB_ROUTER 0x02
/* global pointer for OSPF top data structure */
-extern struct ospf6 *ospf6;
extern struct ospf6_master *om6;
/* prototypes */
diff --git a/ospf6d/ospf6_zebra.c b/ospf6d/ospf6_zebra.c
index 466301309f..cfb9bc1c11 100644
--- a/ospf6d/ospf6_zebra.c
+++ b/ospf6d/ospf6_zebra.c
@@ -36,11 +36,11 @@ DEFINE_MTYPE_STATIC(OSPF6D, OSPF6_DISTANCE, "OSPF6 distance");
unsigned char conf_debug_ospf6_zebra = 0;
/* information about zebra. */
-struct zclient *zclient = NULL;
+struct zclient *ospf6_zclient = NULL;
void ospf6_zebra_vrf_register(struct ospf6 *ospf6)
{
- if (!zclient || zclient->sock < 0 || !ospf6)
+ if (!ospf6_zclient || ospf6_zclient->sock < 0 || !ospf6)
return;
if (ospf6->vrf_id != VRF_UNKNOWN) {
@@ -49,13 +49,13 @@ void ospf6_zebra_vrf_register(struct ospf6 *ospf6)
ospf6_vrf_id_to_name(ospf6->vrf_id),
ospf6->vrf_id);
}
- zclient_send_reg_requests(zclient, ospf6->vrf_id);
+ zclient_send_reg_requests(ospf6_zclient, ospf6->vrf_id);
}
}
void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6)
{
- if (!zclient || zclient->sock < 0 || !ospf6)
+ if (!ospf6_zclient || ospf6_zclient->sock < 0 || !ospf6)
return;
if (ospf6->vrf_id != VRF_DEFAULT && ospf6->vrf_id != VRF_UNKNOWN) {
@@ -67,7 +67,7 @@ void ospf6_zebra_vrf_deregister(struct ospf6 *ospf6)
}
/* Deregister for router-id, interfaces,
* redistributed routes. */
- zclient_send_dereg_requests(zclient, ospf6->vrf_id);
+ zclient_send_dereg_requests(ospf6_zclient, ospf6->vrf_id);
}
}
@@ -98,22 +98,22 @@ static int ospf6_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
/* redistribute function */
void ospf6_zebra_redistribute(int type, vrf_id_t vrf_id)
{
- if (vrf_bitmap_check(&zclient->redist[AFI_IP6][type], vrf_id))
+ if (vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][type], vrf_id))
return;
- vrf_bitmap_set(&zclient->redist[AFI_IP6][type], vrf_id);
+ vrf_bitmap_set(&ospf6_zclient->redist[AFI_IP6][type], vrf_id);
- if (zclient->sock > 0)
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
+ if (ospf6_zclient->sock > 0)
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ospf6_zclient,
AFI_IP6, type, 0, vrf_id);
}
void ospf6_zebra_no_redistribute(int type, vrf_id_t vrf_id)
{
- if (!vrf_bitmap_check(&zclient->redist[AFI_IP6][type], vrf_id))
+ if (!vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][type], vrf_id))
return;
- vrf_bitmap_unset(&zclient->redist[AFI_IP6][type], vrf_id);
- if (zclient->sock > 0)
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ vrf_bitmap_unset(&ospf6_zclient->redist[AFI_IP6][type], vrf_id);
+ if (ospf6_zclient->sock > 0)
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ospf6_zclient,
AFI_IP6, type, 0, vrf_id);
}
@@ -122,7 +122,7 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
struct prefix prefix = {};
int command;
- if (zclient->sock < 0) {
+ if (ospf6_zclient->sock < 0) {
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug(" Not connected to Zebra");
return;
@@ -141,7 +141,7 @@ void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg)
zserv_command_string(command), &prefix,
ospf6->vrf_id);
- if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false,
+ if (zclient_send_rnh(ospf6_zclient, command, &prefix, SAFI_UNICAST, false,
true, ospf6->vrf_id)
== ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_send_rnh() failed",
@@ -216,7 +216,7 @@ static int ospf6_zebra_gr_update(struct ospf6 *ospf6, int command,
{
struct zapi_cap api;
- if (!zclient || zclient->sock < 0 || !ospf6)
+ if (!ospf6_zclient || ospf6_zclient->sock < 0 || !ospf6)
return 1;
memset(&api, 0, sizeof(api));
@@ -224,7 +224,7 @@ static int ospf6_zebra_gr_update(struct ospf6 *ospf6, int command,
api.stale_removal_time = stale_time;
api.vrf_id = ospf6->vrf_id;
- (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient,
+ (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, ospf6_zclient,
&api);
return 0;
@@ -313,7 +313,7 @@ DEFUN(show_zebra,
json_object *json_zebra;
json_object *json_array;
- if (zclient == NULL) {
+ if (ospf6_zclient == NULL) {
vty_out(vty, "Not connected to zebra\n");
return CMD_SUCCESS;
}
@@ -323,13 +323,13 @@ DEFUN(show_zebra,
json_zebra = json_object_new_object();
json_array = json_object_new_array();
- json_object_int_add(json_zebra, "fail", zclient->fail);
+ json_object_int_add(json_zebra, "fail", ospf6_zclient->fail);
json_object_int_add(
json_zebra, "redistributeDefault",
- vrf_bitmap_check(&zclient->default_information[AFI_IP6],
+ vrf_bitmap_check(&ospf6_zclient->default_information[AFI_IP6],
VRF_DEFAULT));
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (vrf_bitmap_check(&zclient->redist[AFI_IP6][i],
+ if (vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][i],
VRF_DEFAULT))
json_object_array_add(
json_array,
@@ -342,13 +342,13 @@ DEFUN(show_zebra,
vty_json(vty, json);
} else {
vty_out(vty, "Zebra Information\n");
- vty_out(vty, " fail: %d\n", zclient->fail);
+ vty_out(vty, " fail: %d\n", ospf6_zclient->fail);
vty_out(vty, " redistribute default: %d\n",
- vrf_bitmap_check(&zclient->default_information[AFI_IP6],
+ vrf_bitmap_check(&ospf6_zclient->default_information[AFI_IP6],
VRF_DEFAULT));
vty_out(vty, " redistribute:");
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (vrf_bitmap_check(&zclient->redist[AFI_IP6][i],
+ if (vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][i],
VRF_DEFAULT))
vty_out(vty, " %s", zebra_route_string(i));
}
@@ -403,7 +403,7 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
zlog_debug("Zebra Send %s route: %pFX",
(type == REM ? "remove" : "add"), &request->prefix);
- if (zclient->sock < 0) {
+ if (ospf6_zclient->sock < 0) {
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug(" Not connected to Zebra");
return;
@@ -487,9 +487,9 @@ static void ospf6_zebra_route_update(int type, struct ospf6_route *request,
ospf6_zebra_append_opaque_attr(request, &api);
if (type == REM)
- ret = zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ ret = zclient_route_send(ZEBRA_ROUTE_DELETE, ospf6_zclient, &api);
else
- ret = zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ ret = zclient_route_send(ZEBRA_ROUTE_ADD, ospf6_zclient, &api);
if (ret == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET,
@@ -552,7 +552,7 @@ void ospf6_zebra_add_discard(struct ospf6_route *request, struct ospf6 *ospf6)
api.prefix = *dest;
zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, ospf6_zclient, &api);
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug("Zebra: Route add discard %pFX", dest);
@@ -589,7 +589,7 @@ void ospf6_zebra_delete_discard(struct ospf6_route *request,
api.prefix = *dest;
zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, ospf6_zclient, &api);
if (IS_OSPF6_DEBUG_ZEBRA(SEND))
zlog_debug("Zebra: Route delete discard %pFX", dest);
@@ -758,14 +758,14 @@ static zclient_handler *const ospf6_handlers[] = {
[ZEBRA_REDISTRIBUTE_ROUTE_DEL] = ospf6_zebra_read_route,
};
-void ospf6_zebra_init(struct event_loop *master)
+void ospf6_zebra_init(struct event_loop *mst)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master, &zclient_options_default, ospf6_handlers,
- array_size(ospf6_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
- zclient->zebra_connected = ospf6_zebra_connected;
- zclient->nexthop_update = ospf6_zebra_import_check_update;
+ ospf6_zclient = zclient_new(mst, &zclient_options_default, ospf6_handlers,
+ array_size(ospf6_handlers));
+ zclient_init(ospf6_zclient, ZEBRA_ROUTE_OSPF6, 0, &ospf6d_privs);
+ ospf6_zclient->zebra_connected = ospf6_zebra_connected;
+ ospf6_zclient->nexthop_update = ospf6_zebra_import_check_update;
/* Install command element for zebra node. */
install_element(VIEW_NODE, &show_ospf6_zebra_cmd);
diff --git a/ospf6d/ospf6_zebra.h b/ospf6d/ospf6_zebra.h
index 7669b5e2c0..0ad86e8c9a 100644
--- a/ospf6d/ospf6_zebra.h
+++ b/ospf6d/ospf6_zebra.h
@@ -27,7 +27,7 @@ struct ospf6_distance {
char *access_list;
};
-extern struct zclient *zclient;
+extern struct zclient *ospf6_zclient;
struct ospf6;
extern void ospf6_zebra_route_update_add(struct ospf6_route *request,
@@ -38,7 +38,7 @@ extern void ospf6_zebra_route_update_remove(struct ospf6_route *request,
extern void ospf6_zebra_redistribute(int, vrf_id_t vrf_id);
extern void ospf6_zebra_no_redistribute(int, vrf_id_t vrf_id);
#define ospf6_zebra_is_redistribute(type, vrf_id) \
- vrf_bitmap_check(&zclient->redist[AFI_IP6][type], vrf_id)
+ vrf_bitmap_check(&ospf6_zclient->redist[AFI_IP6][type], vrf_id)
extern void ospf6_zebra_init(struct event_loop *tm);
extern void ospf6_zebra_import_default_route(struct ospf6 *ospf6, bool unreg);
extern void ospf6_zebra_add_discard(struct ospf6_route *request,
diff --git a/ospf6d/ospf6d.c b/ospf6d/ospf6d.c
index e4e0354fc9..ddb8a461d5 100644
--- a/ospf6d/ospf6d.c
+++ b/ospf6d/ospf6d.c
@@ -1408,13 +1408,13 @@ static void install_element_ospf6_debug_event(void)
}
/* Install ospf related commands. */
-void ospf6_init(struct event_loop *master)
+void ospf6_init(struct event_loop *mst)
{
ospf6_top_init();
ospf6_area_init();
ospf6_interface_init();
ospf6_neighbor_init();
- ospf6_zebra_init(master);
+ ospf6_zebra_init(mst);
ospf6_lsa_init();
ospf6_spf_init();
diff --git a/ospfclient/ospfclient.c b/ospfclient/ospfclient.c
index 24ff08561d..315da6bb0a 100644
--- a/ospfclient/ospfclient.c
+++ b/ospfclient/ospfclient.c
@@ -54,7 +54,7 @@ struct zebra_privs_t ospfd_privs = {.user = NULL,
struct event_loop *master;
/* Global variables */
-struct ospf_apiclient *oclient;
+struct ospf_apiclient *g_oclient;
char **args;
/* Our opaque LSAs have the following format. */
@@ -209,13 +209,13 @@ static void ready_callback(uint8_t lsa_type, uint8_t opaque_type,
lsa_type, opaque_type, &addr);
/* Schedule opaque LSA originate in 5 secs */
- event_add_timer(master, lsa_inject, oclient, 5, NULL);
+ event_add_timer(master, lsa_inject, g_oclient, 5, NULL);
/* Schedule opaque LSA update with new value */
- event_add_timer(master, lsa_inject, oclient, 10, NULL);
+ event_add_timer(master, lsa_inject, g_oclient, 10, NULL);
/* Schedule delete */
- event_add_timer(master, lsa_delete, oclient, 30, NULL);
+ event_add_timer(master, lsa_delete, g_oclient, 30, NULL);
}
static void new_if_callback(struct in_addr ifaddr, struct in_addr area_id)
@@ -296,27 +296,27 @@ int main(int argc, char *argv[])
master = event_master_create(NULL);
/* Open connection to OSPF daemon */
- oclient = ospf_apiclient_connect(args[1], ASYNCPORT);
- if (!oclient) {
+ g_oclient = ospf_apiclient_connect(args[1], ASYNCPORT);
+ if (!g_oclient) {
printf("Connecting to OSPF daemon on %s failed!\n", args[1]);
exit(1);
}
/* Register callback functions. */
ospf_apiclient_register_callback(
- oclient, ready_callback, new_if_callback, del_if_callback,
+ g_oclient, ready_callback, new_if_callback, del_if_callback,
ism_change_callback, nsm_change_callback, lsa_update_callback,
lsa_delete_callback);
/* Register LSA type and opaque type. */
- ospf_apiclient_register_opaque_type(oclient, atoi(args[2]),
+ ospf_apiclient_register_opaque_type(g_oclient, atoi(args[2]),
atoi(args[3]));
/* Synchronize database with OSPF daemon. */
- ospf_apiclient_sync_lsdb(oclient);
+ ospf_apiclient_sync_lsdb(g_oclient);
/* Schedule thread that handles asynchronous messages */
- event_add_read(master, lsa_read, oclient, oclient->fd_async, NULL);
+ event_add_read(master, lsa_read, g_oclient, g_oclient->fd_async, NULL);
/* Now connection is established, run loop */
while (1) {
diff --git a/ospfd/ospf_bfd.c b/ospfd/ospf_bfd.c
index 7d4c7c06b8..ceab63540e 100644
--- a/ospfd/ospf_bfd.c
+++ b/ospfd/ospf_bfd.c
@@ -312,7 +312,7 @@ DEFUN (no_ip_ospf_bfd,
void ospf_bfd_init(struct event_loop *tm)
{
- bfd_protocol_integration_init(zclient, tm);
+ bfd_protocol_integration_init(ospf_zclient, tm);
/* Install BFD command */
install_element(INTERFACE_NODE, &ip_ospf_bfd_cmd);
diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c
index bcb35315d8..6184d1352c 100644
--- a/ospfd/ospf_flood.c
+++ b/ospfd/ospf_flood.c
@@ -33,8 +33,6 @@
#include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_dump.h"
-extern struct zclient *zclient;
-
/** @brief Function to refresh type-5 and type-7 DNA
* LSAs when we receive an indication LSA.
* @param Ospf instance.
@@ -172,11 +170,11 @@ struct external_info *ospf_external_info_check(struct ospf *ospf,
redist_on =
is_default_prefix4(&p)
? vrf_bitmap_check(
- &zclient->default_information[AFI_IP],
+ &ospf_zclient->default_information[AFI_IP],
ospf->vrf_id)
- : (zclient->mi_redist[AFI_IP][type].enabled ||
+ : (ospf_zclient->mi_redist[AFI_IP][type].enabled ||
vrf_bitmap_check(
- &zclient->redist[AFI_IP][type],
+ &ospf_zclient->redist[AFI_IP][type],
ospf->vrf_id));
// Pending: check for MI above.
if (redist_on) {
diff --git a/ospfd/ospf_ldp_sync.c b/ospfd/ospf_ldp_sync.c
index 496ae5b4bd..99f81f5663 100644
--- a/ospfd/ospf_ldp_sync.c
+++ b/ospfd/ospf_ldp_sync.c
@@ -28,8 +28,6 @@
#include "ospf_dump.h"
#include "ospf_ism.h"
-extern struct zclient *zclient;
-
/*
* LDP-SYNC msg between IGP and LDP
*/
@@ -98,8 +96,8 @@ void ospf_ldp_sync_state_req_msg(struct interface *ifp)
request.proto = LDP_IGP_SYNC_IF_STATE_REQUEST;
request.ifindex = ifp->ifindex;
- zclient_send_opaque(zclient, LDP_IGP_SYNC_IF_STATE_REQUEST,
- (uint8_t *)&request, sizeof(request));
+ zclient_send_opaque(ospf_zclient, LDP_IGP_SYNC_IF_STATE_REQUEST,
+ (uint8_t *)&request, sizeof(request));
}
/*
@@ -400,9 +398,9 @@ void ospf_ldp_sync_gbl_exit(struct ospf *ospf, bool remove)
*/
if (CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
/* unregister with opaque client to recv LDP-IGP Sync msgs */
- zclient_unregister_opaque(zclient,
+ zclient_unregister_opaque(ospf_zclient,
LDP_IGP_SYNC_IF_STATE_UPDATE);
- zclient_unregister_opaque(zclient,
+ zclient_unregister_opaque(ospf_zclient,
LDP_IGP_SYNC_ANNOUNCE_UPDATE);
/* disable LDP globally */
@@ -754,8 +752,8 @@ DEFPY (ospf_mpls_ldp_sync,
}
/* register with opaque client to recv LDP-IGP Sync msgs */
- zclient_register_opaque(zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
- zclient_register_opaque(zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
+ zclient_register_opaque(ospf_zclient, LDP_IGP_SYNC_IF_STATE_UPDATE);
+ zclient_register_opaque(ospf_zclient, LDP_IGP_SYNC_ANNOUNCE_UPDATE);
if (!CHECK_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE)) {
SET_FLAG(ospf->ldp_sync_cmd.flags, LDP_SYNC_FLAG_ENABLE);
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c
index d35f0a1372..13bf947994 100644
--- a/ospfd/ospf_packet.c
+++ b/ospfd/ospf_packet.c
@@ -4055,11 +4055,11 @@ void ospf_ls_ack_send_direct(struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
* ignored.
*/
if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT && !oi->p2mp_non_broadcast) {
- struct ospf_lsa_list_entry *ls_ack_list_entry;
+ struct ospf_lsa_list_entry *ack_list_entry;
struct ospf_lsa *ack_queue_lsa;
- frr_each (ospf_lsa_list, &oi->ls_ack_direct, ls_ack_list_entry) {
- ack_queue_lsa = ls_ack_list_entry->lsa;
+ frr_each (ospf_lsa_list, &oi->ls_ack_direct, ack_list_entry) {
+ ack_queue_lsa = ack_list_entry->lsa;
if ((lsa == ack_queue_lsa) ||
((lsa->data->type == ack_queue_lsa->data->type) &&
(lsa->data->id.s_addr ==
diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c
index b6f432b1bb..d187485b9f 100644
--- a/ospfd/ospf_te.c
+++ b/ospfd/ospf_te.c
@@ -1709,15 +1709,15 @@ static int ospf_te_export(uint8_t type, void *link_state)
switch (type) {
case LS_MSG_TYPE_NODE:
ls_vertex2msg(&msg, (struct ls_vertex *)link_state);
- rc = ls_send_msg(zclient, &msg, NULL);
+ rc = ls_send_msg(ospf_zclient, &msg, NULL);
break;
case LS_MSG_TYPE_ATTRIBUTES:
ls_edge2msg(&msg, (struct ls_edge *)link_state);
- rc = ls_send_msg(zclient, &msg, NULL);
+ rc = ls_send_msg(ospf_zclient, &msg, NULL);
break;
case LS_MSG_TYPE_PREFIX:
ls_subnet2msg(&msg, (struct ls_subnet *)link_state);
- rc = ls_send_msg(zclient, &msg, NULL);
+ rc = ls_send_msg(ospf_zclient, &msg, NULL);
break;
default:
rc = -1;
@@ -3113,7 +3113,7 @@ int ospf_te_sync_ted(struct zapi_opaque_reg_info dst)
if (!OspfMplsTE.enabled || !OspfMplsTE.export)
return rc;
- rc = ls_sync_ted(OspfMplsTE.ted, zclient, &dst);
+ rc = ls_sync_ted(OspfMplsTE.ted, ospf_zclient, &dst);
return rc;
}
@@ -4306,7 +4306,7 @@ DEFUN (ospf_mpls_te_export,
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
if (OspfMplsTE.enabled) {
- if (ls_register(zclient, true) != 0) {
+ if (ls_register(ospf_zclient, true) != 0) {
vty_out(vty, "Unable to register Link State\n");
return CMD_WARNING;
}
@@ -4330,7 +4330,7 @@ DEFUN (no_ospf_mpls_te_export,
VTY_DECLVAR_INSTANCE_CONTEXT(ospf, ospf);
if (OspfMplsTE.export) {
- if (ls_unregister(zclient, true) != 0) {
+ if (ls_unregister(ospf_zclient, true) != 0) {
vty_out(vty, "Unable to unregister Link State\n");
return CMD_WARNING;
}
diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c
index 95e8b179d8..3263d0a5f8 100644
--- a/ospfd/ospf_vty.c
+++ b/ospfd/ospf_vty.c
@@ -12308,8 +12308,6 @@ static int config_write_interface_one(struct vty *vty, struct vrf *vrf)
else
vty_out(vty, " ip ospf");
- char buf[INET_ADDRSTRLEN];
-
area_id2str(buf, sizeof(buf), &params->if_area,
params->if_area_id_fmt);
vty_out(vty, " area %s", buf);
diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c
index f45135f44f..cac8a5762f 100644
--- a/ospfd/ospf_zebra.c
+++ b/ospfd/ospf_zebra.c
@@ -45,7 +45,7 @@ DEFINE_MTYPE_STATIC(OSPFD, OSPF_REDISTRIBUTE, "OSPF Redistriute");
/* Zebra structure to hold current status. */
-struct zclient *zclient = NULL;
+struct zclient *ospf_zclient;
/* and for the Synchronous connection to the Label Manager */
struct zclient *zclient_sync;
@@ -342,7 +342,7 @@ void ospf_zebra_add(struct ospf *ospf, struct prefix_ipv4 *p,
if (CHECK_FLAG(ospf->config, OSPF_SEND_EXTRA_DATA_TO_ZEBRA))
ospf_zebra_append_opaque_attr(or, &api);
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, ospf_zclient, &api);
}
void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
@@ -368,7 +368,7 @@ void ospf_zebra_delete(struct ospf *ospf, struct prefix_ipv4 *p,
zlog_debug("Zebra: Route delete %pFX(%s)", p,
ospf_vrf_id_to_name(ospf->vrf_id));
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, ospf_zclient, &api);
}
void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
@@ -390,7 +390,7 @@ void ospf_zebra_add_discard(struct ospf *ospf, struct prefix_ipv4 *p)
memcpy(&api.prefix, p, sizeof(*p));
zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, ospf_zclient, &api);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Zebra: Route add discard %pFX(%s)", p,
@@ -416,7 +416,7 @@ void ospf_zebra_delete_discard(struct ospf *ospf, struct prefix_ipv4 *p)
memcpy(&api.prefix, p, sizeof(*p));
zapi_route_set_blackhole(&api, BLACKHOLE_NULL);
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, ospf_zclient, &api);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
zlog_debug("Zebra: Route delete discard %pFX(%s)", p,
@@ -695,7 +695,7 @@ void ospf_zebra_update_prefix_sid(const struct sr_prefix *srp)
}
/* Finally, send message to zebra. */
- (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
+ (void)zebra_send_mpls_labels(ospf_zclient, ZEBRA_MPLS_LABELS_REPLACE, &zl);
}
/* Remove NHLFE for Prefix-SID */
@@ -722,7 +722,7 @@ void ospf_zebra_delete_prefix_sid(const struct sr_prefix *srp)
}
/* Send message to zebra. */
- (void)zebra_send_mpls_labels(zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
+ (void)zebra_send_mpls_labels(ospf_zclient, ZEBRA_MPLS_LABELS_DELETE, &zl);
}
/* Send MPLS Label entry to Zebra for installation or deletion */
@@ -746,7 +746,7 @@ void ospf_zebra_send_adjacency_sid(int cmd, struct sr_nhlfe nhlfe)
znh->label_num = 1;
znh->labels[0] = nhlfe.label_out;
- (void)zebra_send_mpls_labels(zclient, cmd, &zl);
+ (void)zebra_send_mpls_labels(ospf_zclient, cmd, &zl);
}
struct ospf_redist *ospf_redist_lookup(struct ospf *ospf, uint8_t type,
@@ -815,14 +815,14 @@ int ospf_is_type_redistributed(struct ospf *ospf, int type,
{
return (DEFAULT_ROUTE_TYPE(type)
? vrf_bitmap_check(
- &zclient->default_information[AFI_IP],
+ &ospf_zclient->default_information[AFI_IP],
ospf->vrf_id)
: ((instance &&
redist_check_instance(
- &zclient->mi_redist[AFI_IP][type],
+ &ospf_zclient->mi_redist[AFI_IP][type],
instance)) ||
(!instance &&
- vrf_bitmap_check(&zclient->redist[AFI_IP][type],
+ vrf_bitmap_check(&ospf_zclient->redist[AFI_IP][type],
ospf->vrf_id))));
}
@@ -861,7 +861,7 @@ int ospf_redistribute_set(struct ospf *ospf, struct ospf_redist *red, int type,
ospf_external_add(ospf, type, instance);
- zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP, type,
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_ADD, ospf_zclient, AFI_IP, type,
instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
@@ -879,10 +879,10 @@ int ospf_redistribute_set(struct ospf *ospf, struct ospf_redist *red, int type,
int ospf_redistribute_unset(struct ospf *ospf, int type,
unsigned short instance)
{
- if (type == zclient->redist_default && instance == zclient->instance)
+ if (type == ospf_zclient->redist_default && instance == ospf_zclient->instance)
return CMD_SUCCESS;
- zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, zclient, AFI_IP, type,
+ zclient_redistribute(ZEBRA_REDISTRIBUTE_DELETE, ospf_zclient, AFI_IP, type,
instance, ospf->vrf_id);
if (IS_DEBUG_OSPF(zebra, ZEBRA_REDISTRIBUTE))
@@ -933,7 +933,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
break;
case DEFAULT_ORIGINATE_ZEBRA:
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
- zclient, AFI_IP, ospf->vrf_id);
+ ospf_zclient, AFI_IP, ospf->vrf_id);
ospf->redistribute--;
break;
case DEFAULT_ORIGINATE_ALWAYS:
@@ -951,7 +951,7 @@ int ospf_redistribute_default_set(struct ospf *ospf, int originate, int mtype,
type_str = "normal";
ospf->redistribute++;
zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
- zclient, AFI_IP, ospf->vrf_id);
+ ospf_zclient, AFI_IP, ospf->vrf_id);
break;
case DEFAULT_ORIGINATE_ALWAYS:
type_str = "always";
@@ -1242,7 +1242,7 @@ static int ospf_zebra_gr_update(struct ospf *ospf, int command,
{
struct zapi_cap api;
- if (!zclient || zclient->sock < 0 || !ospf)
+ if (!ospf_zclient || ospf_zclient->sock < 0 || !ospf)
return 1;
memset(&api, 0, sizeof(api));
@@ -1250,7 +1250,7 @@ static int ospf_zebra_gr_update(struct ospf *ospf, int command,
api.stale_removal_time = stale_time;
api.vrf_id = ospf->vrf_id;
- (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, zclient,
+ (void)zclient_capabilities_send(ZEBRA_CLIENT_CAPABILITIES, ospf_zclient,
&api);
return 0;
@@ -1495,7 +1495,7 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
struct prefix prefix = {};
int command;
- if (zclient->sock < 0) {
+ if (ospf_zclient->sock < 0) {
if (IS_DEBUG_OSPF(zebra, ZEBRA))
zlog_debug(" Not connected to Zebra vrf: %s",
ospf_vrf_id_to_name(ospf->vrf_id));
@@ -1515,7 +1515,7 @@ void ospf_zebra_import_default_route(struct ospf *ospf, bool unreg)
zserv_command_string(command), &prefix,
ospf_vrf_id_to_name(ospf->vrf_id));
- if (zclient_send_rnh(zclient, command, &prefix, SAFI_UNICAST, false,
+ if (zclient_send_rnh(ospf_zclient, command, &prefix, SAFI_UNICAST, false,
true, ospf->vrf_id) == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "%s(%s): zclient_send_rnh() failed",
__func__, ospf_vrf_id_to_name(ospf->vrf_id));
@@ -2011,7 +2011,7 @@ uint8_t ospf_distance_apply(struct ospf *ospf, struct prefix_ipv4 *p,
void ospf_zebra_vrf_register(struct ospf *ospf)
{
- if (!zclient || zclient->sock < 0 || !ospf)
+ if (!ospf_zclient || ospf_zclient->sock < 0 || !ospf)
return;
if (ospf->vrf_id != VRF_UNKNOWN) {
@@ -2019,13 +2019,13 @@ void ospf_zebra_vrf_register(struct ospf *ospf)
zlog_debug("%s: Register VRF %s id %u", __func__,
ospf_vrf_id_to_name(ospf->vrf_id),
ospf->vrf_id);
- zclient_send_reg_requests(zclient, ospf->vrf_id);
+ zclient_send_reg_requests(ospf_zclient, ospf->vrf_id);
}
}
void ospf_zebra_vrf_deregister(struct ospf *ospf)
{
- if (!zclient || zclient->sock < 0 || !ospf)
+ if (!ospf_zclient || ospf_zclient->sock < 0 || !ospf)
return;
if (ospf->vrf_id != VRF_DEFAULT && ospf->vrf_id != VRF_UNKNOWN) {
@@ -2035,7 +2035,7 @@ void ospf_zebra_vrf_deregister(struct ospf *ospf)
ospf->vrf_id);
/* Deregister for router-id, interfaces,
* redistributed routes. */
- zclient_send_dereg_requests(zclient, ospf->vrf_id);
+ zclient_send_dereg_requests(ospf_zclient, ospf->vrf_id);
}
}
@@ -2230,17 +2230,17 @@ static zclient_handler *const ospf_handlers[] = {
[ZEBRA_CLIENT_CLOSE_NOTIFY] = ospf_zebra_client_close_notify,
};
-void ospf_zebra_init(struct event_loop *master, unsigned short instance)
+void ospf_zebra_init(struct event_loop *mst, unsigned short instance)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master, &zclient_options_default, ospf_handlers,
- array_size(ospf_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
- zclient->zebra_connected = ospf_zebra_connected;
- zclient->nexthop_update = ospf_zebra_import_check_update;
+ ospf_zclient = zclient_new(mst, &zclient_options_default, ospf_handlers,
+ array_size(ospf_handlers));
+ zclient_init(ospf_zclient, ZEBRA_ROUTE_OSPF, instance, &ospfd_privs);
+ ospf_zclient->zebra_connected = ospf_zebra_connected;
+ ospf_zclient->nexthop_update = ospf_zebra_import_check_update;
/* Initialize special zclient for synchronous message exchanges. */
- zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
+ zclient_sync = zclient_new(mst, &zclient_options_sync, NULL, 0);
zclient_sync->sock = -1;
zclient_sync->redist_default = ZEBRA_ROUTE_OSPF;
zclient_sync->instance = instance;
@@ -2259,5 +2259,5 @@ void ospf_zebra_init(struct event_loop *master, unsigned short instance)
void ospf_zebra_send_arp(const struct interface *ifp, const struct prefix *p)
{
- zclient_send_neigh_discovery_req(zclient, ifp, p);
+ zclient_send_neigh_discovery_req(ospf_zclient, ifp, p);
}
diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c
index 90330d368d..1d2078469d 100644
--- a/ospfd/ospfd.c
+++ b/ospfd/ospfd.c
@@ -59,9 +59,6 @@ struct ospf_master *om;
unsigned short ospf_instance;
-extern struct zclient *zclient;
-extern struct zclient *zclient_sync;
-
/* OSPF config processing timer thread */
struct event *t_ospf_cfg;
@@ -648,8 +645,8 @@ void ospf_terminate(void)
* One or more ospf_finish()'s may have deferred shutdown to a timer
* thread
*/
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(ospf_zclient);
+ zclient_free(ospf_zclient);
zclient_stop(zclient_sync);
zclient_free(zclient_sync);
@@ -2214,13 +2211,13 @@ void ospf_update_bufsize(struct ospf *ospf, uint32_t recvsize,
ospf_sock_bufsize_update(ospf, ospf->fd, type);
}
-void ospf_master_init(struct event_loop *master)
+void ospf_master_init(struct event_loop *mst)
{
memset(&ospf_master, 0, sizeof(ospf_master));
om = &ospf_master;
om->ospf = list_new();
- om->master = master;
+ om->master = mst;
}
/* Link OSPF instance to VRF. */
@@ -2273,20 +2270,20 @@ static void ospf_set_redist_vrf_bitmaps(struct ospf *ospf, bool set)
"%s: setting redist vrf %d bitmap for type %d",
__func__, ospf->vrf_id, type);
if (set)
- vrf_bitmap_set(&zclient->redist[AFI_IP][type],
+ vrf_bitmap_set(&ospf_zclient->redist[AFI_IP][type],
ospf->vrf_id);
else
- vrf_bitmap_unset(&zclient->redist[AFI_IP][type],
+ vrf_bitmap_unset(&ospf_zclient->redist[AFI_IP][type],
ospf->vrf_id);
}
red_list = ospf->redist[DEFAULT_ROUTE];
if (red_list) {
if (set)
- vrf_bitmap_set(&zclient->default_information[AFI_IP],
+ vrf_bitmap_set(&ospf_zclient->default_information[AFI_IP],
ospf->vrf_id);
else
- vrf_bitmap_unset(&zclient->default_information[AFI_IP],
+ vrf_bitmap_unset(&ospf_zclient->default_information[AFI_IP],
ospf->vrf_id);
}
}
diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h
index 6051dff709..460ff0f6ae 100644
--- a/ospfd/ospfd.h
+++ b/ospfd/ospfd.h
@@ -695,7 +695,8 @@ struct ospf_nbr_nbma {
extern struct ospf_master *om;
extern unsigned short ospf_instance;
extern const int ospf_redistributed_proto_max;
-extern struct zclient *zclient;
+extern struct zclient *ospf_zclient;
+extern struct zclient *zclient_sync;
extern struct event_loop *master;
extern int ospf_zlog;
extern struct zebra_privs_t ospfd_privs;
diff --git a/pathd/path_cli.c b/pathd/path_cli.c
index bf8a9ea028..27236667b1 100644
--- a/pathd/path_cli.c
+++ b/pathd/path_cli.c
@@ -234,7 +234,7 @@ DEFPY_NOSH(
/*
* XPath: /frr-pathd:pathd/srte/segment-list
*/
-DEFPY_NOSH(
+DEFPY_YANG_NOSH(
srte_segment_list,
srte_segment_list_cmd,
"segment-list WORD$name",
@@ -267,7 +267,7 @@ DEFPY_NOSH(
return ret;
}
-DEFPY(srte_no_segment_list,
+DEFPY_YANG(srte_no_segment_list,
srte_no_segment_list_cmd,
"no segment-list WORD$name",
NO_STR
@@ -463,7 +463,7 @@ int segment_list_has_prefix(
* XPath: /frr-pathd:pathd/srte/segment-list/segment
*/
/* clang-format off */
-DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd,
+DEFPY_YANG(srte_segment_list_segment, srte_segment_list_segment_cmd,
"index (0-4294967295)$index <[mpls$has_mpls_label label (16-1048575)$label] "
"|"
"[nai$has_nai <"
@@ -527,7 +527,7 @@ DEFPY(srte_segment_list_segment, srte_segment_list_segment_cmd,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_segment_list_no_segment,
+DEFPY_YANG(srte_segment_list_no_segment,
srte_segment_list_no_segment_cmd,
"no index (0-4294967295)$index",
NO_STR
@@ -607,7 +607,7 @@ void cli_show_srte_segment_list_segment(struct vty *vty,
/*
* XPath: /frr-pathd:pathd/policy
*/
-DEFPY_NOSH(
+DEFPY_YANG_NOSH(
srte_policy,
srte_policy_cmd,
"policy color (0-4294967295)$num endpoint <A.B.C.D|X:X::X:X>$endpoint",
@@ -633,7 +633,7 @@ DEFPY_NOSH(
return ret;
}
-DEFPY(srte_no_policy,
+DEFPY_YANG(srte_no_policy,
srte_no_policy_cmd,
"no policy color (0-4294967295)$num endpoint <A.B.C.D|X:X::X:X>$endpoint",
NO_STR
@@ -670,7 +670,7 @@ void cli_show_srte_policy_end(struct vty *vty, const struct lyd_node *dnode)
/*
* XPath: /frr-pathd:pathd/srte/policy/name
*/
-DEFPY(srte_policy_name,
+DEFPY_YANG(srte_policy_name,
srte_policy_name_cmd,
"name WORD$name",
"Segment Routing Policy name\n"
@@ -681,7 +681,7 @@ DEFPY(srte_policy_name,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_policy_no_name,
+DEFPY_YANG(srte_policy_no_name,
srte_policy_no_name_cmd,
"no name [WORD]",
NO_STR
@@ -703,7 +703,7 @@ void cli_show_srte_policy_name(struct vty *vty, const struct lyd_node *dnode,
/*
* XPath: /frr-pathd:pathd/srte/policy/binding-sid
*/
-DEFPY(srte_policy_binding_sid,
+DEFPY_YANG(srte_policy_binding_sid,
srte_policy_binding_sid_cmd,
"binding-sid (16-1048575)$label",
"Segment Routing Policy Binding-SID\n"
@@ -714,7 +714,7 @@ DEFPY(srte_policy_binding_sid,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_policy_no_binding_sid,
+DEFPY_YANG(srte_policy_no_binding_sid,
srte_policy_no_binding_sid_cmd,
"no binding-sid [(16-1048575)]",
NO_STR
@@ -736,7 +736,7 @@ void cli_show_srte_policy_binding_sid(struct vty *vty,
/*
* XPath: /frr-pathd:pathd/srte/policy/candidate-path
*/
-DEFPY(srte_policy_candidate_exp,
+DEFPY_YANG(srte_policy_candidate_exp,
srte_policy_candidate_exp_cmd,
"candidate-path preference (0-4294967295)$preference name WORD$name \
explicit segment-list WORD$list_name",
@@ -760,7 +760,7 @@ DEFPY(srte_policy_candidate_exp,
preference_str);
}
-DEFPY_NOSH(
+DEFPY_YANG_NOSH(
srte_policy_candidate_dyn,
srte_policy_candidate_dyn_cmd,
"candidate-path preference (0-4294967295)$preference name WORD$name dynamic",
@@ -791,7 +791,7 @@ DEFPY_NOSH(
return ret;
}
-DEFPY(srte_candidate_bandwidth,
+DEFPY_YANG(srte_candidate_bandwidth,
srte_candidate_bandwidth_cmd,
"bandwidth BANDWIDTH$value [required$required]",
"Define a bandwidth constraint\n"
@@ -805,7 +805,7 @@ DEFPY(srte_candidate_bandwidth,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_candidate_no_bandwidth,
+DEFPY_YANG(srte_candidate_no_bandwidth,
srte_candidate_no_bandwidth_cmd,
"no bandwidth [BANDWIDTH$value] [required$required]",
NO_STR
@@ -818,7 +818,7 @@ DEFPY(srte_candidate_no_bandwidth,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_candidate_affinity_filter, srte_candidate_affinity_filter_cmd,
+DEFPY_YANG(srte_candidate_affinity_filter, srte_candidate_affinity_filter_cmd,
"affinity <exclude-any|include-any|include-all>$type BITPATTERN$value",
"Affinity constraint\n"
"Exclude any matching link\n"
@@ -842,7 +842,7 @@ DEFPY(srte_candidate_affinity_filter, srte_candidate_affinity_filter_cmd,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd,
+DEFPY_YANG(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd,
"no affinity <exclude-any|include-any|include-all>$type [BITPATTERN$value]",
NO_STR
"Affinity constraint\n"
@@ -858,7 +858,7 @@ DEFPY(srte_candidate_no_affinity_filter, srte_candidate_no_affinity_filter_cmd,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_candidate_metric,
+DEFPY_YANG(srte_candidate_metric,
srte_candidate_metric_cmd,
"metric [bound$bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type METRIC$value [required$required] [computed$computed]",
"Define a metric constraint\n"
@@ -907,7 +907,7 @@ DEFPY(srte_candidate_metric,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_candidate_no_metric,
+DEFPY_YANG(srte_candidate_no_metric,
srte_candidate_no_metric_cmd,
"no metric [bound] <igp|te|hc|abc|lmll|cigp|cte|pigp|pte|phc|msd|pd|pdv|pl|ppd|ppdv|ppl|nap|nlp|dc|bnc>$type [METRIC$value] [required$required] [computed$computed]",
NO_STR
@@ -945,7 +945,7 @@ DEFPY(srte_candidate_no_metric,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_policy_no_candidate,
+DEFPY_YANG(srte_policy_no_candidate,
srte_policy_no_candidate_cmd,
"no candidate-path\
preference (0-4294967295)$preference\
@@ -971,7 +971,7 @@ DEFPY(srte_policy_no_candidate,
preference_str);
}
-DEFPY(srte_candidate_objfun,
+DEFPY_YANG(srte_candidate_objfun,
srte_candidate_objfun_cmd,
"objective-function <mcp|mlp|mbp|mbc|mll|mcc|spt|mct|mplp|mup|mrup|mtd|mbn|mctd|msl|mss|msn>$type [required$required]",
"Define an objective function constraint\n"
@@ -1006,7 +1006,7 @@ DEFPY(srte_candidate_objfun,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(srte_candidate_no_objfun,
+DEFPY_YANG(srte_candidate_no_objfun,
srte_candidate_no_objfun_cmd,
"no objective-function [<mcp|mlp|mbp|mbc|mll|mcc|spt|mct|mplp|mup|mrup|mtd|mbn|mctd|msl|mss|msn>] [required$required]",
NO_STR
diff --git a/pathd/path_ted.c b/pathd/path_ted.c
index 0f8d3827ff..f9dff1f019 100644
--- a/pathd/path_ted.c
+++ b/pathd/path_ted.c
@@ -31,7 +31,7 @@ static enum zclient_send_status path_ted_link_state_sync(void);
static void path_ted_timer_handler_sync(struct event *thread);
static void path_ted_timer_handler_refresh(struct event *thread);
-extern struct zclient *zclient;
+extern struct zclient *pathd_zclient;
struct ted_state ted_state_g = { .dbg = { .conf = "debug pathd mpls-te",
.desc = "Pathd TED" } };
@@ -40,9 +40,9 @@ struct ted_state ted_state_g = { .dbg = { .conf = "debug pathd mpls-te",
* path_path_ted public API function implementations
*/
-void path_ted_init(struct event_loop *master)
+void path_ted_init(struct event_loop *loop)
{
- ted_state_g.main = master;
+ ted_state_g.main = loop;
ted_state_g.link_state_delay_interval = TIMER_RETRY_DELAY;
ted_state_g.segment_list_refresh_interval = TIMER_RETRY_DELAY;
path_ted_register_vty();
@@ -82,7 +82,7 @@ uint32_t path_ted_start_importing_igp(const char *daemon_str)
return 1;
}
- if (ls_register(zclient, false /*client*/) != 0) {
+ if (ls_register(pathd_zclient, false /*client*/) != 0) {
PATH_TED_ERROR("%s: PATHD-TED: Unable to register Link State",
__func__);
ted_state_g.import = IMPORT_UNKNOWN;
@@ -113,7 +113,7 @@ uint32_t path_ted_stop_importing_igp(void)
uint32_t status = 0;
if (ted_state_g.import != IMPORT_UNKNOWN) {
- if (ls_unregister(zclient, false /*client*/) != 0) {
+ if (ls_unregister(pathd_zclient, false /*client*/) != 0) {
PATH_TED_ERROR(
"%s: PATHD-TED: Unable to unregister Link State",
__func__);
@@ -382,7 +382,7 @@ DEFUN (no_path_ted,
ted_state_g.enabled = false;
PATH_TED_DEBUG("%s: PATHD-TED: ON -> OFF", __func__);
ted_state_g.import = IMPORT_UNKNOWN;
- if (ls_unregister(zclient, false /*client*/) != 0) {
+ if (ls_unregister(pathd_zclient, false /*client*/) != 0) {
vty_out(vty, "Unable to unregister Link State\n");
return CMD_WARNING;
}
@@ -538,7 +538,7 @@ enum zclient_send_status path_ted_link_state_sync(void)
{
enum zclient_send_status status;
- status = ls_request_sync(zclient);
+ status = ls_request_sync(pathd_zclient);
if (status == -1) {
PATH_TED_ERROR(
"%s: PATHD-TED: Opaque error asking for TED sync ",
diff --git a/pathd/path_zebra.c b/pathd/path_zebra.c
index ba03315c82..1078b37dd6 100644
--- a/pathd/path_zebra.c
+++ b/pathd/path_zebra.c
@@ -26,7 +26,7 @@
static int path_zebra_opaque_msg_handler(ZAPI_CALLBACK_ARGS);
-struct zclient *zclient;
+struct zclient *pathd_zclient;
static struct zclient *zclient_sync;
/* Event to retry synch zapi setup for label-manager */
@@ -189,7 +189,7 @@ void path_zebra_add_sr_policy(struct srte_policy *policy,
segment->sid_value;
policy->status = SRTE_POLICY_STATUS_GOING_UP;
- (void)zebra_send_sr_policy(zclient, ZEBRA_SR_POLICY_SET, &zp);
+ (void)zebra_send_sr_policy(pathd_zclient, ZEBRA_SR_POLICY_SET, &zp);
}
/**
@@ -209,7 +209,7 @@ void path_zebra_delete_sr_policy(struct srte_policy *policy)
zp.segment_list.label_num = 0;
policy->status = SRTE_POLICY_STATUS_DOWN;
- (void)zebra_send_sr_policy(zclient, ZEBRA_SR_POLICY_DELETE, &zp);
+ (void)zebra_send_sr_policy(pathd_zclient, ZEBRA_SR_POLICY_DELETE, &zp);
}
/**
@@ -351,13 +351,13 @@ static zclient_handler *const path_handlers[] = {
*
* @param master The master thread
*/
-void path_zebra_init(struct event_loop *master)
+void path_zebra_init(struct event_loop *loop)
{
/* Initialize asynchronous zclient. */
- zclient = zclient_new(master, &zclient_options_default, path_handlers,
- array_size(path_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_SRTE, 0, &pathd_privs);
- zclient->zebra_connected = path_zebra_connected;
+ pathd_zclient = zclient_new(loop, &zclient_options_default, path_handlers,
+ array_size(path_handlers));
+ zclient_init(pathd_zclient, ZEBRA_ROUTE_SRTE, 0, &pathd_privs);
+ pathd_zclient->zebra_connected = path_zebra_connected;
/* Initialize special zclient for synchronous message exchanges. */
zclient_sync = zclient_new(master, &zclient_options_sync, NULL, 0);
@@ -373,8 +373,8 @@ void path_zebra_init(struct event_loop *master)
void path_zebra_stop(void)
{
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(pathd_zclient);
+ zclient_free(pathd_zclient);
event_cancel(&t_sync_connect);
zclient_stop(zclient_sync);
zclient_free(zclient_sync);
diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c
index 277271c6b6..dc8cbc56bf 100644
--- a/pbrd/pbr_zebra.c
+++ b/pbrd/pbr_zebra.c
@@ -35,7 +35,7 @@
DEFINE_MTYPE_STATIC(PBRD, PBR_INTERFACE, "PBR Interface");
/* Zebra structure to hold current status. */
-struct zclient *zclient;
+struct zclient *pbr_zclient;
struct pbr_interface *pbr_if_new(struct interface *ifp)
{
@@ -272,7 +272,7 @@ static void route_add_helper(struct zapi_route *api, struct nexthop_group nhg,
}
api->nexthop_num = i;
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, pbr_zclient, api);
}
/*
@@ -342,17 +342,17 @@ void route_delete(struct pbr_nexthop_group_cache *pnhgc, afi_t afi)
switch (afi) {
case AFI_IP:
api.prefix.family = AF_INET;
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api);
break;
case AFI_IP6:
api.prefix.family = AF_INET6;
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api);
break;
case AFI_MAX:
api.prefix.family = AF_INET;
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api);
api.prefix.family = AF_INET6;
- zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_DELETE, pbr_zclient, &api);
break;
case AFI_L2VPN:
DEBUGD(&pbr_dbg_zebra,
@@ -403,22 +403,22 @@ static zclient_handler *const pbr_handlers[] = {
void pbr_zebra_init(void)
{
- zclient = zclient_new(master, &zclient_options_default, pbr_handlers,
- array_size(pbr_handlers));
+ pbr_zclient = zclient_new(master, &zclient_options_default, pbr_handlers,
+ array_size(pbr_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
- zclient->zebra_connected = zebra_connected;
- zclient->nexthop_update = pbr_zebra_nexthop_update;
+ zclient_init(pbr_zclient, ZEBRA_ROUTE_PBR, 0, &pbr_privs);
+ pbr_zclient->zebra_connected = zebra_connected;
+ pbr_zclient->nexthop_update = pbr_zebra_nexthop_update;
}
void pbr_zebra_destroy(void)
{
- if (zclient == NULL)
+ if (pbr_zclient == NULL)
return;
- zclient_stop(zclient);
- zclient_free(zclient);
- zclient = NULL;
+ zclient_stop(pbr_zclient);
+ zclient_free(pbr_zclient);
+ pbr_zclient = NULL;
}
void pbr_send_rnh(struct nexthop *nhop, bool reg)
@@ -454,7 +454,7 @@ void pbr_send_rnh(struct nexthop *nhop, bool reg)
break;
}
- if (zclient_send_rnh(zclient, command, &p, SAFI_UNICAST, false, false,
+ if (zclient_send_rnh(pbr_zclient, command, &p, SAFI_UNICAST, false, false,
nhop->vrf_id)
== ZCLIENT_SEND_FAILURE) {
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
@@ -608,7 +608,7 @@ bool pbr_send_pbr_map(struct pbr_map_sequence *pbrms,
if (!install && !is_installed)
return false;
- s = zclient->obuf;
+ s = pbr_zclient->obuf;
stream_reset(s);
zclient_create_header(s,
@@ -621,7 +621,7 @@ bool pbr_send_pbr_map(struct pbr_map_sequence *pbrms,
if (pbr_encode_pbr_map_sequence(s, pbrms, pmi->ifp)) {
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ zclient_send_message(pbr_zclient);
} else {
DEBUGD(&pbr_dbg_zebra, "%s: %s seq %u encode failed, skipped",
__func__, pbrm->name, pbrms->seqno);
diff --git a/pceplib/pcep_pcc.c b/pceplib/pcep_pcc.c
index 92a968ef78..d53469e7cd 100644
--- a/pceplib/pcep_pcc.c
+++ b/pceplib/pcep_pcc.c
@@ -47,11 +47,11 @@ struct cmd_line_args {
};
bool pcc_active_ = true;
-pcep_session *session = NULL;
-struct cmd_line_args *cmd_line_args = NULL;
+pcep_session *g_session = NULL;
+struct cmd_line_args *g_cmd_line_args = NULL;
/* pcep_event callback variables */
bool pcep_event_condition = false;
-struct pcep_event *event = NULL;
+struct pcep_event *g_event = NULL;
pthread_mutex_t pcep_event_mutex;
pthread_cond_t pcep_event_cond_var;
@@ -180,7 +180,7 @@ void handle_signal_action(int sig_number)
if (sig_number == SIGINT) {
pcep_log(LOG_INFO, "%s: SIGINT was caught!", __func__);
pcc_active_ = false;
- if (cmd_line_args->eventpoll == false) {
+ if (g_cmd_line_args->eventpoll == false) {
pthread_mutex_lock(&pcep_event_mutex);
pcep_event_condition = true;
pthread_cond_signal(&pcep_event_cond_var);
@@ -189,12 +189,12 @@ void handle_signal_action(int sig_number)
} else if (sig_number == SIGUSR1) {
pcep_log(LOG_INFO, "%s: SIGUSR1 was caught, dumping counters",
__func__);
- dump_pcep_session_counters(session);
+ dump_pcep_session_counters(g_session);
pceplib_memory_dump();
} else if (sig_number == SIGUSR2) {
pcep_log(LOG_INFO, "%s: SIGUSR2 was caught, reseting counters",
__func__);
- reset_pcep_session_counters(session);
+ reset_pcep_session_counters(g_session);
}
}
@@ -377,7 +377,7 @@ void pcep_event_callback(void *cb_data, pcep_event *e)
pcep_log(LOG_NOTICE, "%s: [%ld-%ld] pcep_event_callback", __func__,
time(NULL), pthread_self());
pthread_mutex_lock(&pcep_event_mutex);
- event = e;
+ g_event = e;
pcep_event_condition = true;
pthread_cond_signal(&pcep_event_cond_var);
pthread_mutex_unlock(&pcep_event_mutex);
@@ -388,14 +388,14 @@ int main(int argc, char **argv)
pcep_log(LOG_NOTICE, "%s: [%ld-%ld] starting pcc_pcep example client",
__func__, time(NULL), pthread_self());
- cmd_line_args = get_cmdline_args(argc, argv);
- if (cmd_line_args == NULL) {
+ g_cmd_line_args = get_cmdline_args(argc, argv);
+ if (g_cmd_line_args == NULL) {
return -1;
}
setup_signals();
- if (cmd_line_args->eventpoll == false) {
+ if (g_cmd_line_args->eventpoll == false) {
struct pceplib_infra_config infra_config;
memset(&infra_config, 0, sizeof(infra_config));
infra_config.pcep_event_func = pcep_event_callback;
@@ -415,31 +415,31 @@ int main(int argc, char **argv)
pcep_configuration *config = create_default_pcep_configuration();
config->pcep_msg_versioning->draft_ietf_pce_segment_routing_07 = true;
- config->src_pcep_port = cmd_line_args->src_tcp_port;
+ config->src_pcep_port = g_cmd_line_args->src_tcp_port;
config->is_tcp_auth_md5 = true;
- strlcpy(config->tcp_authentication_str, cmd_line_args->tcp_md5_str,
+ strlcpy(config->tcp_authentication_str, g_cmd_line_args->tcp_md5_str,
sizeof(config->tcp_authentication_str));
- int af = (cmd_line_args->is_ipv6 ? AF_INET6 : AF_INET);
+ int af = (g_cmd_line_args->is_ipv6 ? AF_INET6 : AF_INET);
struct hostent *host_info =
- gethostbyname2(cmd_line_args->dest_ip_str, af);
+ gethostbyname2(g_cmd_line_args->dest_ip_str, af);
if (host_info == NULL) {
pcep_log(LOG_ERR, "%s: Error getting IP address.", __func__);
return -1;
}
- if (cmd_line_args->is_ipv6) {
+ if (g_cmd_line_args->is_ipv6) {
struct in6_addr host_address;
memcpy(&host_address, host_info->h_addr, host_info->h_length);
- session = connect_pce_ipv6(config, &host_address);
+ g_session = connect_pce_ipv6(config, &host_address);
} else {
struct in_addr host_address;
memcpy(&host_address, host_info->h_addr, host_info->h_length);
- session = connect_pce(config, &host_address);
+ g_session = connect_pce(config, &host_address);
}
- if (session == NULL) {
+ if (g_session == NULL) {
pcep_log(LOG_WARNING, "%s: Error in connect_pce.", __func__);
destroy_pcep_configuration(config);
return -1;
@@ -447,12 +447,12 @@ int main(int argc, char **argv)
sleep(2);
- send_pce_report_message(session);
+ send_pce_report_message(g_session);
/*send_pce_path_request_message(session);*/
/* Wait for pcep_event's either by polling the event queue or by
* callback */
- if (cmd_line_args->eventpoll == true) {
+ if (g_cmd_line_args->eventpoll == true) {
/* Poll the pcep_event queue*/
while (pcc_active_) {
if (event_queue_is_empty() == false) {
@@ -479,8 +479,8 @@ int main(int argc, char **argv)
/* Check if we have been interrupted by SIGINT */
if (pcc_active_) {
- print_queue_event(event);
- destroy_pcep_event(event);
+ print_queue_event(g_event);
+ destroy_pcep_event(g_event);
}
pcep_event_condition = false;
@@ -492,9 +492,9 @@ int main(int argc, char **argv)
}
pcep_log(LOG_NOTICE, "%s: Disconnecting from PCE", __func__);
- disconnect_pce(session);
+ disconnect_pce(g_session);
destroy_pcep_configuration(config);
- free(cmd_line_args);
+ free(g_cmd_line_args);
if (!destroy_pcc()) {
pcep_log(LOG_NOTICE, "%s: Error stopping PCC.", __func__);
diff --git a/pceplib/pcep_utils_memory.c b/pceplib/pcep_utils_memory.c
index c3a2ab90cd..225c058711 100644
--- a/pceplib/pcep_utils_memory.c
+++ b/pceplib/pcep_utils_memory.c
@@ -44,15 +44,15 @@ void *PCEPLIB_INFRA = &pceplib_infra_mt;
void *PCEPLIB_MESSAGES = &pceplib_messages_mt;
/* Initialize memory function pointers and memory type pointers */
-bool pceplib_memory_initialize(void *pceplib_infra_mt,
- void *pceplib_messages_mt,
+bool pceplib_memory_initialize(void *infra_mt,
+ void *messages_mt,
pceplib_malloc_func mf, pceplib_calloc_func cf,
pceplib_realloc_func rf, pceplib_strdup_func sf,
pceplib_free_func ff)
{
- PCEPLIB_INFRA = (pceplib_infra_mt ? pceplib_infra_mt : PCEPLIB_INFRA);
+ PCEPLIB_INFRA = (infra_mt ? infra_mt : PCEPLIB_INFRA);
PCEPLIB_MESSAGES =
- (pceplib_messages_mt ? pceplib_messages_mt : PCEPLIB_MESSAGES);
+ (messages_mt ? messages_mt : PCEPLIB_MESSAGES);
mfunc = (mf ? mf : mfunc);
cfunc = (cf ? cf : cfunc);
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index 8297911828..ad11bb1822 100644
--- a/pimd/pim6_cmd.c
+++ b/pimd/pim6_cmd.c
@@ -999,6 +999,20 @@ DEFPY (interface_no_ipv6_mroute,
source_str);
}
+DEFPY_YANG(interface_ipv6_pim_use_source,
+ interface_ipv6_pim_use_source_cmd,
+ "[no] ipv6 pim use-source X:X::X:X$source",
+ NO_STR
+ IPV6_STR
+ PIM_STR
+ "Configure primary IPv6 address\n"
+ "Source IPv6 address\n")
+{
+ nb_cli_enqueue_change(vty, "./use-source", NB_OP_MODIFY, no ? "::" : source_str);
+
+ return nb_cli_apply_changes(vty, FRR_PIM_INTERFACE_XPATH, "frr-routing:ipv6");
+}
+
DEFPY (pim6_rp,
pim6_rp_cmd,
"rp X:X::X:X$rp [X:X::X:X/M]$gp",
@@ -2972,6 +2986,8 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE, &interface_ipv6_mld_limits_cmd);
install_element(INTERFACE_NODE, &no_interface_ipv6_mld_limits_cmd);
+ install_element(INTERFACE_NODE, &interface_ipv6_pim_use_source_cmd);
+
/* Install BSM command */
install_element(INTERFACE_NODE, &ipv6_pim_bsm_cmd);
install_element(INTERFACE_NODE, &no_ipv6_pim_bsm_cmd);
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index f838c401e3..2dcea57051 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -3181,7 +3181,7 @@ DEFPY (clear_ip_mroute_count,
return clear_ip_mroute_count_command(vty, name);
}
-DEFPY(clear_ip_msdp_peer, clear_ip_msdp_peer_cmd,
+DEFPY_YANG(clear_ip_msdp_peer, clear_ip_msdp_peer_cmd,
"clear ip msdp peer A.B.C.D$peer [vrf WORD$vrfname]",
CLEAR_STR
IP_STR
@@ -3399,7 +3399,7 @@ DEFPY_NOSH (router_pim,
return CMD_SUCCESS;
}
-DEFPY (no_router_pim,
+DEFPY_YANG (no_router_pim,
no_router_pim_cmd,
"no router pim [vrf NAME]",
NO_STR
@@ -3424,7 +3424,7 @@ DEFPY (no_router_pim,
}
-DEFPY (pim_spt_switchover_infinity,
+DEFPY_YANG (pim_spt_switchover_infinity,
pim_spt_switchover_infinity_cmd,
"spt-switchover infinity-and-beyond",
"SPT-Switchover\n"
@@ -3632,7 +3632,7 @@ DEFPY_ATTR(no_ip_pim_spt_switchover_infinity_plist,
return ret;
}
-DEFPY (pim_register_accept_list,
+DEFPY_YANG (pim_register_accept_list,
pim_register_accept_list_cmd,
"[no] register-accept-list PREFIXLIST4_NAME$word",
NO_STR
@@ -4237,7 +4237,7 @@ DEFPY (no_ip_igmp_group_watermark,
return CMD_SUCCESS;
}
-DEFPY (pim_v6_secondary,
+DEFPY_YANG (pim_v6_secondary,
pim_v6_secondary_cmd,
"send-v6-secondary",
"Send v6 secondary addresses\n")
@@ -4297,7 +4297,7 @@ DEFPY_ATTR(ip_pim_v6_secondary,
return ret;
}
-DEFPY (no_pim_v6_secondary,
+DEFPY_YANG (no_pim_v6_secondary,
no_pim_v6_secondary_cmd,
"no send-v6-secondary",
NO_STR
@@ -4716,7 +4716,7 @@ DEFPY (pim_bsr_candidate_rp_group,
return pim_process_bsr_crp_grp_cmd(vty, group_str, no);
}
-DEFPY (pim_ssm_prefix_list,
+DEFPY_YANG (pim_ssm_prefix_list,
pim_ssm_prefix_list_cmd,
"ssm prefix-list PREFIXLIST4_NAME$plist",
"Source Specific Multicast\n"
@@ -4776,7 +4776,7 @@ DEFPY_ATTR(ip_pim_ssm_prefix_list,
return ret;
}
-DEFPY (no_pim_ssm_prefix_list,
+DEFPY_YANG (no_pim_ssm_prefix_list,
no_pim_ssm_prefix_list_cmd,
"no ssm prefix-list",
NO_STR
@@ -4836,7 +4836,7 @@ DEFPY_ATTR(no_ip_pim_ssm_prefix_list,
return ret;
}
-DEFPY (no_pim_ssm_prefix_list_name,
+DEFPY_YANG (no_pim_ssm_prefix_list_name,
no_pim_ssm_prefix_list_name_cmd,
"no ssm prefix-list PREFIXLIST4_NAME$plist",
NO_STR
@@ -5128,7 +5128,7 @@ DEFPY_ATTR(no_ip_pim_ssmpingd,
return ret;
}
-DEFPY (pim_ecmp,
+DEFPY_YANG (pim_ecmp,
pim_ecmp_cmd,
"ecmp",
"Enable PIM ECMP \n")
@@ -5183,7 +5183,7 @@ DEFPY_ATTR(ip_pim_ecmp,
return ret;
}
-DEFPY (no_pim_ecmp,
+DEFPY_YANG (no_pim_ecmp,
no_pim_ecmp_cmd,
"no ecmp",
NO_STR
@@ -5240,7 +5240,7 @@ DEFPY_ATTR(no_ip_pim_ecmp,
return ret;
}
-DEFPY (pim_ecmp_rebalance,
+DEFPY_YANG (pim_ecmp_rebalance,
pim_ecmp_rebalance_cmd,
"ecmp rebalance",
"Enable PIM ECMP \n"
@@ -5306,7 +5306,7 @@ DEFPY_ATTR(ip_pim_ecmp_rebalance,
return ret;
}
-DEFPY (no_pim_ecmp_rebalance,
+DEFPY_YANG (no_pim_ecmp_rebalance,
no_pim_ecmp_rebalance_cmd,
"no ecmp rebalance",
NO_STR
@@ -5368,7 +5368,7 @@ DEFPY_ATTR(no_ip_pim_ecmp_rebalance,
return ret;
}
-DEFUN (interface_ip_igmp,
+DEFUN_YANG (interface_ip_igmp,
interface_ip_igmp_cmd,
"ip igmp",
IP_STR
@@ -5380,7 +5380,7 @@ DEFUN (interface_ip_igmp,
"frr-routing:ipv4");
}
-DEFUN (interface_no_ip_igmp,
+DEFUN_YANG (interface_no_ip_igmp,
interface_no_ip_igmp_cmd,
"no ip igmp",
NO_STR
@@ -5464,7 +5464,7 @@ DEFPY_YANG (interface_ip_igmp_static_group,
(src_str ? src_str : "0.0.0.0"));
}
-DEFUN (interface_ip_igmp_query_interval,
+DEFUN_YANG (interface_ip_igmp_query_interval,
interface_ip_igmp_query_interval_cmd,
"ip igmp query-interval (1-65535)",
IP_STR
@@ -5494,7 +5494,7 @@ DEFUN (interface_ip_igmp_query_interval,
"frr-routing:ipv4");
}
-DEFUN (interface_no_ip_igmp_query_interval,
+DEFUN_YANG (interface_no_ip_igmp_query_interval,
interface_no_ip_igmp_query_interval_cmd,
"no ip igmp query-interval [(1-65535)]",
NO_STR
@@ -5509,7 +5509,7 @@ DEFUN (interface_no_ip_igmp_query_interval,
"frr-routing:ipv4");
}
-DEFUN (interface_ip_igmp_version,
+DEFUN_YANG (interface_ip_igmp_version,
interface_ip_igmp_version_cmd,
"ip igmp version (2-3)",
IP_STR
@@ -5526,7 +5526,7 @@ DEFUN (interface_ip_igmp_version,
"frr-routing:ipv4");
}
-DEFUN (interface_no_ip_igmp_version,
+DEFUN_YANG (interface_no_ip_igmp_version,
interface_no_ip_igmp_version_cmd,
"no ip igmp version (2-3)",
NO_STR
@@ -5541,7 +5541,7 @@ DEFUN (interface_no_ip_igmp_version,
"frr-routing:ipv4");
}
-DEFPY (interface_ip_igmp_query_max_response_time,
+DEFPY_YANG (interface_ip_igmp_query_max_response_time,
interface_ip_igmp_query_max_response_time_cmd,
"ip igmp query-max-response-time (1-65535)$qmrt",
IP_STR
@@ -5552,7 +5552,7 @@ DEFPY (interface_ip_igmp_query_max_response_time,
return gm_process_query_max_response_time_cmd(vty, qmrt_str);
}
-DEFUN (interface_no_ip_igmp_query_max_response_time,
+DEFUN_YANG (interface_no_ip_igmp_query_max_response_time,
interface_no_ip_igmp_query_max_response_time_cmd,
"no ip igmp query-max-response-time [(1-65535)]",
NO_STR
@@ -5564,7 +5564,7 @@ DEFUN (interface_no_ip_igmp_query_max_response_time,
return gm_process_no_query_max_response_time_cmd(vty);
}
-DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
+DEFUN_YANG_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
interface_ip_igmp_query_max_response_time_dsec_cmd,
"ip igmp query-max-response-time-dsec (1-65535)",
IP_STR
@@ -5594,7 +5594,7 @@ DEFUN_HIDDEN (interface_ip_igmp_query_max_response_time_dsec,
"frr-routing:ipv4");
}
-DEFUN_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
+DEFUN_YANG_HIDDEN (interface_no_ip_igmp_query_max_response_time_dsec,
interface_no_ip_igmp_query_max_response_time_dsec_cmd,
"no ip igmp query-max-response-time-dsec [(1-65535)]",
NO_STR
@@ -5904,7 +5904,7 @@ DEFPY (interface_no_ip_pim,
}
/* boundaries */
-DEFUN(interface_ip_pim_boundary_oil,
+DEFUN_YANG(interface_ip_pim_boundary_oil,
interface_ip_pim_boundary_oil_cmd,
"ip multicast boundary oil WORD",
IP_STR
@@ -5916,7 +5916,7 @@ DEFUN(interface_ip_pim_boundary_oil,
return pim_process_ip_pim_boundary_oil_cmd(vty, argv[4]->arg);
}
-DEFUN(interface_no_ip_pim_boundary_oil,
+DEFUN_YANG(interface_no_ip_pim_boundary_oil,
interface_no_ip_pim_boundary_oil_cmd,
"no ip multicast boundary oil [WORD]",
NO_STR
@@ -6653,7 +6653,7 @@ DEFUN_NOSH (show_debugging_pim,
return CMD_SUCCESS;
}
-DEFUN (interface_pim_use_source,
+DEFUN_YANG (interface_pim_use_source,
interface_pim_use_source_cmd,
"ip pim use-source A.B.C.D",
IP_STR
@@ -6668,7 +6668,7 @@ DEFUN (interface_pim_use_source,
"frr-routing:ipv4");
}
-DEFUN (interface_no_pim_use_source,
+DEFUN_YANG (interface_no_pim_use_source,
interface_no_pim_use_source_cmd,
"no ip pim use-source [A.B.C.D]",
NO_STR
@@ -6684,7 +6684,7 @@ DEFUN (interface_no_pim_use_source,
"frr-routing:ipv4");
}
-DEFPY (ip_pim_bfd,
+DEFPY_YANG (ip_pim_bfd,
ip_pim_bfd_cmd,
"ip pim bfd [profile BFDPROF$prof]",
IP_STR
@@ -6717,7 +6717,7 @@ DEFPY (ip_pim_bfd,
"frr-routing:ipv4");
}
-DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
+DEFPY_YANG(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
"no ip pim bfd profile [BFDPROF]",
NO_STR
IP_STR
@@ -6733,7 +6733,7 @@ DEFPY(no_ip_pim_bfd_profile, no_ip_pim_bfd_profile_cmd,
"frr-routing:ipv4");
}
-DEFUN (no_ip_pim_bfd,
+DEFUN_YANG (no_ip_pim_bfd,
no_ip_pim_bfd_cmd,
"no ip pim bfd",
NO_STR
@@ -6748,7 +6748,7 @@ DEFUN (no_ip_pim_bfd,
"frr-routing:ipv4");
}
-DEFUN (ip_pim_bsm,
+DEFUN_YANG (ip_pim_bsm,
ip_pim_bsm_cmd,
"ip pim bsm",
IP_STR
@@ -6757,7 +6757,7 @@ DEFUN (ip_pim_bsm,
{
return pim_process_bsm_cmd(vty);
}
-DEFUN (no_ip_pim_bsm,
+DEFUN_YANG (no_ip_pim_bsm,
no_ip_pim_bsm_cmd,
"no ip pim bsm",
NO_STR
@@ -6768,7 +6768,7 @@ DEFUN (no_ip_pim_bsm,
return pim_process_no_bsm_cmd(vty);
}
-DEFUN (ip_pim_ucast_bsm,
+DEFUN_YANG (ip_pim_ucast_bsm,
ip_pim_ucast_bsm_cmd,
"ip pim unicast-bsm",
IP_STR
@@ -6778,7 +6778,7 @@ DEFUN (ip_pim_ucast_bsm,
return pim_process_unicast_bsm_cmd(vty);
}
-DEFUN (no_ip_pim_ucast_bsm,
+DEFUN_YANG (no_ip_pim_ucast_bsm,
no_ip_pim_ucast_bsm_cmd,
"no ip pim unicast-bsm",
NO_STR
@@ -6790,7 +6790,7 @@ DEFUN (no_ip_pim_ucast_bsm,
}
#if HAVE_BFDD > 0
-DEFUN_HIDDEN (
+DEFUN_YANG_HIDDEN (
ip_pim_bfd_param,
ip_pim_bfd_param_cmd,
"ip pim bfd (2-255) (1-65535) (1-65535)",
@@ -6801,7 +6801,7 @@ DEFUN_HIDDEN (
"Required min receive interval\n"
"Desired min transmit interval\n")
#else
- DEFUN(
+ DEFUN_YANG(
ip_pim_bfd_param,
ip_pim_bfd_param_cmd,
"ip pim bfd (2-255) (1-65535) (1-65535)",
@@ -6855,7 +6855,7 @@ ALIAS(no_ip_pim_bfd, no_ip_pim_bfd_param_cmd,
"Desired min transmit interval\n")
#endif /* !HAVE_BFDD */
-DEFPY(pim_msdp_peer, pim_msdp_peer_cmd,
+DEFPY_YANG(pim_msdp_peer, pim_msdp_peer_cmd,
"msdp peer A.B.C.D$peer source A.B.C.D$source",
CFG_MSDP_STR
"Configure MSDP peer\n"
@@ -6920,7 +6920,7 @@ DEFPY_ATTR(ip_pim_msdp_peer,
return ret;
}
-DEFPY(msdp_peer_md5, msdp_peer_md5_cmd,
+DEFPY_YANG(msdp_peer_md5, msdp_peer_md5_cmd,
"msdp peer A.B.C.D$peer password WORD$psk",
CFG_MSDP_STR
"Configure MSDP peer\n"
@@ -6945,7 +6945,7 @@ DEFPY(msdp_peer_md5, msdp_peer_md5_cmd,
return nb_cli_apply_changes(vty, "%s", xpath);
}
-DEFPY(no_msdp_peer_md5, no_msdp_peer_md5_cmd,
+DEFPY_YANG(no_msdp_peer_md5, no_msdp_peer_md5_cmd,
"no msdp peer A.B.C.D$peer password [WORD]",
NO_STR
CFG_MSDP_STR
@@ -6971,7 +6971,7 @@ DEFPY(no_msdp_peer_md5, no_msdp_peer_md5_cmd,
return nb_cli_apply_changes(vty, "%s", xpath);
}
-DEFPY(pim_msdp_timers, pim_msdp_timers_cmd,
+DEFPY_YANG(pim_msdp_timers, pim_msdp_timers_cmd,
"msdp timers (1-65535)$keepalive (1-65535)$holdtime [(1-65535)$connretry]",
CFG_MSDP_STR
"MSDP timers configuration\n"
@@ -7046,7 +7046,7 @@ DEFPY_ATTR(ip_pim_msdp_timers,
return ret;
}
-DEFPY(no_pim_msdp_timers, no_pim_msdp_timers_cmd,
+DEFPY_YANG(no_pim_msdp_timers, no_pim_msdp_timers_cmd,
"no msdp timers [(1-65535) (1-65535) [(1-65535)]]",
NO_STR
CFG_MSDP_STR
@@ -7110,7 +7110,7 @@ DEFPY_ATTR(no_ip_pim_msdp_timers,
return ret;
}
-DEFPY (no_pim_msdp_peer,
+DEFPY_YANG (no_pim_msdp_peer,
no_pim_msdp_peer_cmd,
"no msdp peer A.B.C.D",
NO_STR
@@ -7172,7 +7172,7 @@ DEFPY_ATTR(no_ip_pim_msdp_peer,
return ret;
}
-DEFPY(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd,
+DEFPY_YANG(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd,
"msdp peer A.B.C.D$peer sa-filter ACL_NAME$acl_name <in|out>$dir",
CFG_MSDP_STR
"Configure MSDP peer\n"
@@ -7203,7 +7203,7 @@ DEFPY(msdp_peer_sa_filter, msdp_peer_sa_filter_cmd,
return nb_cli_apply_changes(vty, "%s", xpath);
}
-DEFPY(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd,
+DEFPY_YANG(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd,
"no msdp peer A.B.C.D$peer sa-filter ACL_NAME <in|out>$dir",
NO_STR
CFG_MSDP_STR
@@ -7235,7 +7235,7 @@ DEFPY(no_msdp_peer_sa_filter, no_ip_msdp_peer_sa_filter_cmd,
return nb_cli_apply_changes(vty, "%s", xpath);
}
-DEFPY(pim_msdp_mesh_group_member,
+DEFPY_YANG(pim_msdp_mesh_group_member,
pim_msdp_mesh_group_member_cmd,
"msdp mesh-group WORD$gname member A.B.C.D$maddr",
CFG_MSDP_STR
@@ -7313,7 +7313,7 @@ DEFPY_ATTR(ip_pim_msdp_mesh_group_member,
return ret;
}
-DEFPY(no_pim_msdp_mesh_group_member,
+DEFPY_YANG(no_pim_msdp_mesh_group_member,
no_pim_msdp_mesh_group_member_cmd,
"no msdp mesh-group WORD$gname member A.B.C.D$maddr",
NO_STR
@@ -7432,7 +7432,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group_member,
return ret;
}
-DEFPY(pim_msdp_mesh_group_source,
+DEFPY_YANG(pim_msdp_mesh_group_source,
pim_msdp_mesh_group_source_cmd,
"msdp mesh-group WORD$gname source A.B.C.D$saddr",
CFG_MSDP_STR
@@ -7505,7 +7505,7 @@ DEFPY_ATTR(ip_pim_msdp_mesh_group_source,
return ret;
}
-DEFPY(no_pim_msdp_mesh_group_source,
+DEFPY_YANG(no_pim_msdp_mesh_group_source,
no_pim_msdp_mesh_group_source_cmd,
"no msdp mesh-group WORD$gname source [A.B.C.D]",
NO_STR
@@ -7593,7 +7593,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group_source,
return ret;
}
-DEFPY(no_pim_msdp_mesh_group,
+DEFPY_YANG(no_pim_msdp_mesh_group,
no_pim_msdp_mesh_group_cmd,
"no msdp mesh-group WORD$gname",
NO_STR
@@ -7661,7 +7661,7 @@ DEFPY_ATTR(no_ip_pim_msdp_mesh_group,
return ret;
}
-DEFPY(msdp_shutdown,
+DEFPY_YANG(msdp_shutdown,
msdp_shutdown_cmd,
"[no] msdp shutdown",
NO_STR
@@ -7679,7 +7679,7 @@ DEFPY(msdp_shutdown,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd,
+DEFPY_YANG(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd,
"[no] msdp peer A.B.C.D$peer sa-limit ![(1-4294967294)$sa_limit]",
NO_STR
CFG_MSDP_STR
@@ -7702,7 +7702,7 @@ DEFPY(msdp_peer_sa_limit, msdp_peer_sa_limit_cmd,
return nb_cli_apply_changes(vty, "%s", xpath);
}
-DEFPY(msdp_originator_id, msdp_originator_id_cmd,
+DEFPY_YANG(msdp_originator_id, msdp_originator_id_cmd,
"[no] msdp originator-id ![A.B.C.D$originator_id]",
NO_STR
CFG_MSDP_STR
@@ -8448,7 +8448,7 @@ DEFUN (show_ip_msdp_sa_sg_vrf_all,
return CMD_SUCCESS;
}
-DEFPY(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd,
+DEFPY_YANG(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd,
"[no] msdp log neighbor-events",
NO_STR
MSDP_STR
@@ -8463,7 +8463,7 @@ DEFPY(msdp_log_neighbor_changes, msdp_log_neighbor_changes_cmd,
return nb_cli_apply_changes(vty, NULL);
}
-DEFPY(msdp_log_sa_changes, msdp_log_sa_changes_cmd,
+DEFPY_YANG(msdp_log_sa_changes, msdp_log_sa_changes_cmd,
"[no] msdp log sa-events",
NO_STR
MSDP_STR
@@ -8751,7 +8751,7 @@ DEFUN_HIDDEN (show_ip_pim_vxlan_sg_work,
return CMD_SUCCESS;
}
-DEFPY_HIDDEN (no_pim_mlag,
+DEFPY_YANG_HIDDEN (no_pim_mlag,
no_pim_mlag_cmd,
"no mlag",
NO_STR
@@ -8808,7 +8808,7 @@ DEFPY_ATTR(no_ip_pim_mlag,
return ret;
}
-DEFPY_HIDDEN (pim_mlag,
+DEFPY_YANG_HIDDEN (pim_mlag,
pim_mlag_cmd,
"mlag INTERFACE$iface role [primary|secondary]$role state [up|down]$state addr A.B.C.D$addr",
"MLAG\n"
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 877470e461..510ca398ff 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -147,6 +147,7 @@ struct pim_interface *pim_if_new(struct interface *ifp, bool gm, bool pim,
pim_ifp->pim_enable = pim;
pim_ifp->pim_passive_enable = false;
pim_ifp->gm_enable = gm;
+ pim_ifp->gm_proxy = false;
pim_ifp->gm_join_list = NULL;
pim_ifp->static_group_list = NULL;
@@ -194,8 +195,17 @@ void pim_if_delete(struct interface *ifp)
assert(pim_ifp);
pim_ifp->pim->mcast_if_count--;
- if (pim_ifp->gm_join_list)
+ if (pim_ifp->gm_join_list) {
pim_if_gm_join_del_all(ifp);
+ /*
+ * Sometimes gm_join_del_all does not delete them all
+ * and as such it's not actually freed. Let's
+ * just clean this up if it wasn't to prevent
+ * the problem.
+ */
+ if (pim_ifp->gm_join_list)
+ list_delete(&pim_ifp->gm_join_list);
+ }
if (pim_ifp->static_group_list)
pim_if_static_group_del_all(ifp);
@@ -1436,10 +1446,8 @@ int pim_if_gm_join_del(struct interface *ifp, pim_addr group_addr,
}
listnode_delete(pim_ifp->gm_join_list, ij);
gm_join_free(ij);
- if (listcount(pim_ifp->gm_join_list) < 1) {
+ if (listcount(pim_ifp->gm_join_list) < 1)
list_delete(&pim_ifp->gm_join_list);
- pim_ifp->gm_join_list = 0;
- }
return 0;
}
diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c
index dcef2d0d33..3b4e71ecf4 100644
--- a/pimd/pim_mlag.c
+++ b/pimd/pim_mlag.c
@@ -15,7 +15,7 @@
#include "pim_upstream.h"
#include "pim_vxlan.h"
-extern struct zclient *zclient;
+extern struct zclient *pim_zclient;
#define PIM_MLAG_METADATA_LEN 4
@@ -925,7 +925,7 @@ static void pim_mlag_register_handler(struct event *thread)
{
uint32_t bit_mask = 0;
- if (!zclient)
+ if (!pim_zclient)
return;
SET_FLAG(bit_mask, (1 << MLAG_STATUS_UPDATE));
@@ -942,7 +942,7 @@ static void pim_mlag_register_handler(struct event *thread)
zlog_debug("%s: Posting Client Register to MLAG mask: 0x%x",
__func__, bit_mask);
- zclient_send_mlag_register(zclient, bit_mask);
+ zclient_send_mlag_register(pim_zclient, bit_mask);
}
void pim_mlag_register(void)
@@ -958,14 +958,14 @@ void pim_mlag_register(void)
static void pim_mlag_deregister_handler(struct event *thread)
{
- if (!zclient)
+ if (!pim_zclient)
return;
if (PIM_DEBUG_MLAG)
zlog_debug("%s: Posting Client De-Register to MLAG from PIM",
__func__);
router->connected_to_mlag = false;
- zclient_send_mlag_deregister(zclient);
+ zclient_send_mlag_deregister(pim_zclient);
}
void pim_mlag_deregister(void)
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 1e9ea24b26..d97b56e4d6 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -780,7 +780,6 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
*/
struct pim_zlookup_nexthop nexthop_tab[router->multipath];
ifindex_t i;
- struct interface *ifp = NULL;
int num_ifindex;
memset(nexthop_tab, 0, sizeof(nexthop_tab));
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index e4603ff946..aed9d2be90 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -1624,8 +1624,7 @@ void pim_upstream_set_sptbit(struct pim_upstream *up,
if (!starup
|| up->rpf.source_nexthop
.interface != starup->rpf.source_nexthop.interface) {
- struct pim_upstream *starup = up->parent;
-
+ starup = up->parent;
if (PIM_DEBUG_PIM_TRACE)
zlog_debug(
"%s: %s RPF_interface(S) != RPF_interface(RP(G))",
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index f0ec3c6b6e..1f7e2b255f 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -38,7 +38,7 @@
#undef PIM_DEBUG_IFADDR_DUMP
#define PIM_DEBUG_IFADDR_DUMP
-struct zclient *zclient;
+struct zclient *pim_zclient;
/* Router-id update message from zebra. */
@@ -349,16 +349,16 @@ static void pim_zebra_vxlan_replay(void)
struct stream *s = NULL;
/* Check socket. */
- if (!zclient || zclient->sock < 0)
+ if (!pim_zclient || pim_zclient->sock < 0)
return;
- s = zclient->obuf;
+ s = pim_zclient->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_VXLAN_SG_REPLAY, VRF_DEFAULT);
stream_putw_at(s, 0, stream_get_endp(s));
- zclient_send_message(zclient);
+ zclient_send_message(pim_zclient);
}
void pim_scan_oil(struct pim_instance *pim)
@@ -448,14 +448,14 @@ static zclient_handler *const pim_handlers[] = {
void pim_zebra_init(void)
{
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new(router->master, &zclient_options_default,
- pim_handlers, array_size(pim_handlers));
+ pim_zclient = zclient_new(router->master, &zclient_options_default,
+ pim_handlers, array_size(pim_handlers));
- zclient->zebra_capabilities = pim_zebra_capabilities;
- zclient->zebra_connected = pim_zebra_connected;
- zclient->nexthop_update = pim_nexthop_update;
+ pim_zclient->zebra_capabilities = pim_zebra_capabilities;
+ pim_zclient->zebra_connected = pim_zebra_connected;
+ pim_zclient->nexthop_update = pim_nexthop_update;
- zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
+ zclient_init(pim_zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
if (PIM_DEBUG_PIM_TRACE) {
zlog_notice("%s: zclient socket initialized", __func__);
}
@@ -508,8 +508,8 @@ void pim_zebra_zclient_update(struct vty *vty)
{
vty_out(vty, "Zclient update socket: ");
- if (zclient) {
- vty_out(vty, "%d failures=%d\n", zclient->sock, zclient->fail);
+ if (pim_zclient) {
+ vty_out(vty, "%d failures=%d\n", pim_zclient->sock, pim_zclient->fail);
} else {
vty_out(vty, "<null zclient>\n");
}
@@ -517,8 +517,8 @@ void pim_zebra_zclient_update(struct vty *vty)
struct zclient *pim_zebra_zclient_get(void)
{
- if (zclient)
- return zclient;
+ if (pim_zclient)
+ return pim_zclient;
else
return NULL;
}
@@ -526,5 +526,5 @@ struct zclient *pim_zebra_zclient_get(void)
void pim_zebra_interface_set_master(struct interface *vrf,
struct interface *ifp)
{
- zclient_interface_set_master(zclient, vrf, ifp);
+ zclient_interface_set_master(pim_zclient, vrf, ifp);
}
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 4ffb5bac17..b8f73f9183 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -26,7 +26,7 @@
#include "pim_zlookup.h"
#include "pim_addr.h"
-static struct zclient *zlookup = NULL;
+static struct zclient *pim_zlookup = NULL;
struct event *zlookup_read;
static void zclient_lookup_sched(struct zclient *zlookup, int delay);
@@ -115,25 +115,25 @@ static void zclient_lookup_failed(struct zclient *zlookup)
void zclient_lookup_free(void)
{
EVENT_OFF(zlookup_read);
- zclient_stop(zlookup);
- zclient_free(zlookup);
- zlookup = NULL;
+ zclient_stop(pim_zlookup);
+ zclient_free(pim_zlookup);
+ pim_zlookup = NULL;
}
void zclient_lookup_new(void)
{
- zlookup = zclient_new(router->master, &zclient_options_sync, NULL, 0);
- if (!zlookup) {
+ pim_zlookup = zclient_new(router->master, &zclient_options_sync, NULL, 0);
+ if (!pim_zlookup) {
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
__func__);
return;
}
- zlookup->sock = -1;
- zlookup->t_connect = NULL;
- zlookup->privs = &pimd_privs;
+ pim_zlookup->sock = -1;
+ pim_zlookup->t_connect = NULL;
+ pim_zlookup->privs = &pimd_privs;
- zclient_lookup_sched_now(zlookup);
+ zclient_lookup_sched_now(pim_zlookup);
zlog_notice("%s: zclient lookup socket initialized", __func__);
}
@@ -328,11 +328,11 @@ static int zclient_rib_lookup(struct pim_instance *pim, struct pim_zlookup_nexth
(safi == SAFI_MULTICAST ? "M" : "U"));
/* Check socket. */
- if (zlookup->sock < 0) {
+ if (pim_zlookup->sock < 0) {
flog_err(EC_LIB_ZAPI_SOCKET,
"%s: zclient lookup socket is not connected",
__func__);
- zclient_lookup_failed(zlookup);
+ zclient_lookup_failed(pim_zlookup);
return -1;
}
@@ -346,31 +346,31 @@ static int zclient_rib_lookup(struct pim_instance *pim, struct pim_zlookup_nexth
ipaddr.ipa_type = PIM_IPADDR;
ipaddr.ipaddr_pim = addr;
- s = zlookup->obuf;
+ s = pim_zlookup->obuf;
stream_reset(s);
zclient_create_header(s, ZEBRA_NEXTHOP_LOOKUP, pim->vrf->vrf_id);
stream_put_ipaddr(s, &ipaddr);
stream_putc(s, safi);
stream_putw_at(s, 0, stream_get_endp(s));
- ret = writen(zlookup->sock, s->data, stream_get_endp(s));
+ ret = writen(pim_zlookup->sock, s->data, stream_get_endp(s));
if (ret < 0) {
flog_err(
EC_LIB_SOCKET,
"%s: writen() failure: %d writing to zclient lookup socket",
__func__, errno);
- zclient_lookup_failed(zlookup);
+ zclient_lookup_failed(pim_zlookup);
return -2;
}
if (ret == 0) {
flog_err_sys(EC_LIB_SOCKET,
"%s: connection closed on zclient lookup socket",
__func__);
- zclient_lookup_failed(zlookup);
+ zclient_lookup_failed(pim_zlookup);
return -3;
}
- return zclient_read_nexthop(pim, zlookup, nexthop_tab, tab_size, addr);
+ return zclient_read_nexthop(pim, pim_zlookup, nexthop_tab, tab_size, addr);
}
static int zclient_lookup_nexthop_once(struct pim_instance *pim,
@@ -562,8 +562,8 @@ int zclient_lookup_nexthop(struct pim_instance *pim, struct pim_zlookup_nexthop
void pim_zlookup_show_ip_multicast(struct vty *vty)
{
vty_out(vty, "Zclient lookup socket: ");
- if (zlookup) {
- vty_out(vty, "%d failures=%d\n", zlookup->sock, zlookup->fail);
+ if (pim_zlookup) {
+ vty_out(vty, "%d failures=%d\n", pim_zlookup->sock, pim_zlookup->fail);
} else {
vty_out(vty, "<null zclient>\n");
}
@@ -571,7 +571,7 @@ void pim_zlookup_show_ip_multicast(struct vty *vty)
int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
{
- struct stream *s = zlookup->obuf;
+ struct stream *s = pim_zlookup->obuf;
uint16_t command = 0;
unsigned long long lastused;
pim_sgaddr sg;
@@ -602,7 +602,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
stream_putw_at(s, 0, stream_get_endp(s));
count = stream_get_endp(s);
- ret = writen(zlookup->sock, s->data, count);
+ ret = writen(pim_zlookup->sock, s->data, count);
if (ret <= 0) {
flog_err(
EC_LIB_SOCKET,
@@ -611,7 +611,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
return -1;
}
- s = zlookup->ibuf;
+ s = pim_zlookup->ibuf;
while (command != ZEBRA_IPMR_ROUTE_STATS) {
int err;
@@ -621,12 +621,12 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
uint8_t version;
stream_reset(s);
- err = zclient_read_header(s, zlookup->sock, &length, &marker,
+ err = zclient_read_header(s, pim_zlookup->sock, &length, &marker,
&version, &vrf_id, &command);
if (err < 0) {
flog_err(EC_LIB_ZAPI_MISSMATCH,
"%s: zclient_read_header() failed", __func__);
- zclient_lookup_failed(zlookup);
+ zclient_lookup_failed(pim_zlookup);
return -1;
}
}
@@ -642,7 +642,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
EC_LIB_ZAPI_MISSMATCH,
"%s: Received wrong %pSG(%s) information requested",
__func__, &more, c_oil->pim->vrf->name);
- zclient_lookup_failed(zlookup);
+ zclient_lookup_failed(pim_zlookup);
return -3;
}
diff --git a/pimd/pim_zpthread.c b/pimd/pim_zpthread.c
index d6b2621ff4..45d8868808 100644
--- a/pimd/pim_zpthread.c
+++ b/pimd/pim_zpthread.c
@@ -13,7 +13,7 @@
#include "pim_mlag.h"
#include "pim_zebra.h"
-extern struct zclient *zclient;
+extern struct zclient *pim_zclient;
#define PIM_MLAG_POST_LIMIT 100
@@ -96,7 +96,7 @@ static void pim_mlag_zebra_flush_buffer(void)
}
}
- zclient_send_mlag_data(zclient, router->mlag_stream);
+ zclient_send_mlag_data(pim_zclient, router->mlag_stream);
stream_failure:
stream_reset(router->mlag_stream);
mlag_bulk_cnt = 0;
diff --git a/ripd/rip_bfd.c b/ripd/rip_bfd.c
index b59db11a30..a1529d1360 100644
--- a/ripd/rip_bfd.c
+++ b/ripd/rip_bfd.c
@@ -15,7 +15,7 @@
DEFINE_MTYPE(RIPD, RIP_BFD_PROFILE, "RIP BFD profile name");
-extern struct zclient *zclient;
+extern struct zclient *ripd_zclient;
static const char *rip_bfd_interface_profile(struct rip_interface *ri)
{
@@ -117,5 +117,5 @@ void rip_bfd_instance_update(struct rip *rip)
void rip_bfd_init(struct event_loop *tm)
{
- bfd_protocol_integration_init(zclient, tm);
+ bfd_protocol_integration_init(ripd_zclient, tm);
}
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index cfe4a7e437..431e967131 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -94,6 +94,7 @@ static void sigint(void)
rip_zclient_stop();
route_map_finish();
+ prefix_list_reset();
keychain_terminate();
frr_fini();
diff --git a/ripd/rip_snmp.c b/ripd/rip_snmp.c
index f6a7a82831..118b08e527 100644
--- a/ripd/rip_snmp.c
+++ b/ripd/rip_snmp.c
@@ -553,11 +553,11 @@ static uint8_t *rip2PeerTable(struct variable *v, oid name[], size_t *length,
}
/* Register RIPv2-MIB. */
-static int rip_snmp_init(struct event_loop *master)
+static int rip_snmp_init(struct event_loop *mstr)
{
rip_ifaddr_table = route_table_init();
- smux_init(master);
+ smux_init(mstr);
REGISTER_MIB("mibII/rip", rip_variables, variable, rip_oid);
return 0;
}
diff --git a/ripd/rip_zebra.c b/ripd/rip_zebra.c
index ce94e8e754..4ba63e50e4 100644
--- a/ripd/rip_zebra.c
+++ b/ripd/rip_zebra.c
@@ -21,7 +21,7 @@
#include "ripd/rip_interface.h"
/* All information about zebra. */
-struct zclient *zclient = NULL;
+struct zclient *ripd_zclient = NULL;
/* Send ECMP routes to zebra. */
static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp,
@@ -72,7 +72,7 @@ static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp,
api.tag = rinfo->tag;
}
- zclient_route_send(cmd, zclient, &api);
+ zclient_route_send(cmd, ripd_zclient, &api);
if (IS_RIP_DEBUG_ZEBRA) {
if (rip->ecmp)
@@ -137,14 +137,14 @@ static int rip_zebra_read_route(ZAPI_CALLBACK_ARGS)
void rip_redistribute_conf_update(struct rip *rip, int type)
{
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripd_zclient, AFI_IP,
type, 0, rip->vrf->vrf_id);
}
void rip_redistribute_conf_delete(struct rip *rip, int type)
{
- if (zclient->sock > 0)
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ if (ripd_zclient->sock > 0)
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripd_zclient,
AFI_IP, type, 0, rip->vrf->vrf_id);
/* Remove the routes from RIP table. */
@@ -162,7 +162,7 @@ void rip_redistribute_enable(struct rip *rip)
if (!rip_redistribute_check(rip, i))
continue;
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripd_zclient, AFI_IP,
i, 0, rip->vrf->vrf_id);
}
}
@@ -173,7 +173,7 @@ void rip_redistribute_disable(struct rip *rip)
if (!rip_redistribute_check(rip, i))
continue;
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripd_zclient,
AFI_IP, i, 0, rip->vrf->vrf_id);
}
}
@@ -181,7 +181,7 @@ void rip_redistribute_disable(struct rip *rip)
void rip_show_redistribute_config(struct vty *vty, struct rip *rip)
{
for (int i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (i == zclient->redist_default
+ if (i == ripd_zclient->redist_default
|| !rip_redistribute_check(rip, i))
continue;
@@ -198,8 +198,8 @@ void rip_zebra_vrf_register(struct vrf *vrf)
zlog_debug("%s: register VRF %s(%u) to zebra", __func__,
vrf->name, vrf->vrf_id);
- zclient_send_reg_requests(zclient, vrf->vrf_id);
- bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf->vrf_id);
+ zclient_send_reg_requests(ripd_zclient, vrf->vrf_id);
+ bfd_client_sendmsg(ripd_zclient, ZEBRA_BFD_CLIENT_REGISTER, vrf->vrf_id);
}
void rip_zebra_vrf_deregister(struct vrf *vrf)
@@ -211,8 +211,8 @@ void rip_zebra_vrf_deregister(struct vrf *vrf)
zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__,
vrf->name, vrf->vrf_id);
- zclient_send_dereg_requests(zclient, vrf->vrf_id);
- bfd_client_sendmsg(zclient, ZEBRA_BFD_CLIENT_DEREGISTER, vrf->vrf_id);
+ zclient_send_dereg_requests(ripd_zclient, vrf->vrf_id);
+ bfd_client_sendmsg(ripd_zclient, ZEBRA_BFD_CLIENT_DEREGISTER, vrf->vrf_id);
}
static void rip_zebra_connected(struct zclient *zclient)
@@ -233,18 +233,18 @@ static void rip_zebra_capabilities(struct zclient_capabilities *cap)
zebra_ecmp_count = MIN(cap->ecmp, zebra_ecmp_count);
}
-void rip_zclient_init(struct event_loop *master)
+void rip_zclient_init(struct event_loop *mst)
{
/* Set default value to the zebra client structure. */
- zclient = zclient_new(master, &zclient_options_default, rip_handlers,
- array_size(rip_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
- zclient->zebra_connected = rip_zebra_connected;
- zclient->zebra_capabilities = rip_zebra_capabilities;
+ ripd_zclient = zclient_new(mst, &zclient_options_default, rip_handlers,
+ array_size(rip_handlers));
+ zclient_init(ripd_zclient, ZEBRA_ROUTE_RIP, 0, &ripd_privs);
+ ripd_zclient->zebra_connected = rip_zebra_connected;
+ ripd_zclient->zebra_capabilities = rip_zebra_capabilities;
}
void rip_zclient_stop(void)
{
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(ripd_zclient);
+ zclient_free(ripd_zclient);
}
diff --git a/ripd/ripd.c b/ripd/ripd.c
index 2d038507ab..c850df52ec 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -282,8 +282,14 @@ struct rip_info *rip_ecmp_replace(struct rip *rip, struct rip_info *rinfo_new)
*/
struct rip_info *rip_ecmp_delete(struct rip *rip, struct rip_info *rinfo)
{
- struct route_node *rp = rinfo->rp;
- struct list *list = (struct list *)rp->info;
+ struct route_node *rp;
+ struct list *list;
+
+ if (rinfo == NULL)
+ return NULL;
+
+ rp = rinfo->rp;
+ list = (struct list *)rp->info;
EVENT_OFF(rinfo->t_timeout);
diff --git a/ripngd/ripng_zebra.c b/ripngd/ripng_zebra.c
index bb5a880c02..87e275ad0d 100644
--- a/ripngd/ripng_zebra.c
+++ b/ripngd/ripng_zebra.c
@@ -19,7 +19,7 @@
#include "ripngd/ripng_debug.h"
/* All information about zebra. */
-struct zclient *zclient = NULL;
+struct zclient *ripng_zclient = NULL;
/* Send ECMP routes to zebra. */
static void ripng_zebra_ipv6_send(struct ripng *ripng, struct agg_node *rp,
@@ -67,7 +67,7 @@ static void ripng_zebra_ipv6_send(struct ripng *ripng, struct agg_node *rp,
api.tag = rinfo->tag;
}
- zclient_route_send(cmd, zclient, &api);
+ zclient_route_send(cmd, ripng_zclient, &api);
if (IS_RIPNG_DEBUG_ZEBRA) {
if (ripng->ecmp)
@@ -137,14 +137,14 @@ static int ripng_zebra_read_route(ZAPI_CALLBACK_ARGS)
void ripng_redistribute_conf_update(struct ripng *ripng, int type)
{
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient, AFI_IP6,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripng_zclient, AFI_IP6,
type, 0, ripng->vrf->vrf_id);
}
void ripng_redistribute_conf_delete(struct ripng *ripng, int type)
{
- if (zclient->sock > 0)
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ if (ripng_zclient->sock > 0)
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripng_zclient,
AFI_IP6, type, 0, ripng->vrf->vrf_id);
ripng_redistribute_withdraw(ripng, type);
@@ -161,7 +161,7 @@ void ripng_redistribute_enable(struct ripng *ripng)
if (!ripng_redistribute_check(ripng, i))
continue;
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, zclient,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_ADD, ripng_zclient,
AFI_IP6, i, 0, ripng->vrf->vrf_id);
}
}
@@ -172,7 +172,7 @@ void ripng_redistribute_disable(struct ripng *ripng)
if (!ripng_redistribute_check(ripng, i))
continue;
- zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, zclient,
+ zebra_redistribute_send(ZEBRA_REDISTRIBUTE_DELETE, ripng_zclient,
AFI_IP6, i, 0, ripng->vrf->vrf_id);
}
}
@@ -182,7 +182,7 @@ void ripng_redistribute_write(struct vty *vty, struct ripng *ripng)
int i;
for (i = 0; i < ZEBRA_ROUTE_MAX; i++) {
- if (i == zclient->redist_default
+ if (i == ripng_zclient->redist_default
|| !ripng_redistribute_check(ripng, i))
continue;
@@ -199,7 +199,7 @@ void ripng_zebra_vrf_register(struct vrf *vrf)
zlog_debug("%s: register VRF %s(%u) to zebra", __func__,
vrf->name, vrf->vrf_id);
- zclient_send_reg_requests(zclient, vrf->vrf_id);
+ zclient_send_reg_requests(ripng_zclient, vrf->vrf_id);
}
void ripng_zebra_vrf_deregister(struct vrf *vrf)
@@ -211,7 +211,7 @@ void ripng_zebra_vrf_deregister(struct vrf *vrf)
zlog_debug("%s: deregister VRF %s(%u) from zebra.", __func__,
vrf->name, vrf->vrf_id);
- zclient_send_dereg_requests(zclient, vrf->vrf_id);
+ zclient_send_dereg_requests(ripng_zclient, vrf->vrf_id);
}
static void ripng_zebra_connected(struct zclient *zclient)
@@ -232,19 +232,19 @@ static void ripng_zebra_capabilities(struct zclient_capabilities *cap)
}
/* Initialize zebra structure and it's commands. */
-void zebra_init(struct event_loop *master)
+void zebra_init(struct event_loop *mst)
{
/* Allocate zebra structure. */
- zclient = zclient_new(master, &zclient_options_default, ripng_handlers,
- array_size(ripng_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
+ ripng_zclient = zclient_new(mst, &zclient_options_default, ripng_handlers,
+ array_size(ripng_handlers));
+ zclient_init(ripng_zclient, ZEBRA_ROUTE_RIPNG, 0, &ripngd_privs);
- zclient->zebra_connected = ripng_zebra_connected;
- zclient->zebra_capabilities = ripng_zebra_capabilities;
+ ripng_zclient->zebra_connected = ripng_zebra_connected;
+ ripng_zclient->zebra_capabilities = ripng_zebra_capabilities;
}
void ripng_zebra_stop(void)
{
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(ripng_zclient);
+ zclient_free(ripng_zclient);
}
diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c
index 4447b69bf6..3a0877f8e8 100644
--- a/sharpd/sharp_zebra.c
+++ b/sharpd/sharp_zebra.c
@@ -23,7 +23,7 @@
#include "sharp_zebra.h"
/* Zebra structure to hold current status. */
-struct zclient *zclient = NULL;
+struct zclient *g_zclient = NULL;
/* For registering threads. */
extern struct event_loop *master;
@@ -34,23 +34,23 @@ extern struct zebra_privs_t sharp_privs;
DEFINE_MTYPE_STATIC(SHARPD, ZC, "Test zclients");
/* Struct to hold list of test zclients */
-struct sharp_zclient {
- struct sharp_zclient *prev;
- struct sharp_zclient *next;
+struct sharp_zclient_entry {
+ struct sharp_zclient_entry *prev;
+ struct sharp_zclient_entry *next;
struct zclient *client;
};
/* Head of test zclient list */
-static struct sharp_zclient *sharp_clients_head;
+static struct sharp_zclient_entry *sharp_clients_head;
static int sharp_opaque_handler(ZAPI_CALLBACK_ARGS);
/* Utility to add a test zclient struct to the list */
static void add_zclient(struct zclient *client)
{
- struct sharp_zclient *node;
+ struct sharp_zclient_entry *node;
- node = XCALLOC(MTYPE_ZC, sizeof(struct sharp_zclient));
+ node = XCALLOC(MTYPE_ZC, sizeof(struct sharp_zclient_entry));
node->client = client;
@@ -198,7 +198,7 @@ int sharp_install_lsps_helper(bool install_p, bool update_p,
cmd = ZEBRA_MPLS_LABELS_DELETE;
}
- if (zebra_send_mpls_labels(zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
+ if (zebra_send_mpls_labels(g_zclient, cmd, &zl) == ZCLIENT_SEND_FAILURE)
return -1;
return 0;
@@ -291,7 +291,7 @@ static bool route_add(const struct prefix *p, vrf_id_t vrf_id, uint8_t instance,
memcpy(api.opaque.data, opaque, api.opaque.length);
}
- if (zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api) ==
+ if (zclient_route_send(ZEBRA_ROUTE_ADD, g_zclient, &api) ==
ZCLIENT_SEND_BUFFERED)
return true;
else
@@ -315,7 +315,7 @@ static bool route_delete(struct prefix *p, vrf_id_t vrf_id, uint8_t instance)
api.instance = instance;
memcpy(&api.prefix, p, sizeof(*p));
- if (zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api) ==
+ if (zclient_route_send(ZEBRA_ROUTE_DELETE, g_zclient, &api) ==
ZCLIENT_SEND_BUFFERED)
return true;
else
@@ -471,7 +471,7 @@ static int route_notify_owner(ZAPI_CALLBACK_ARGS)
enum zapi_route_notify_owner note;
uint32_t table;
- if (!zapi_route_notify_decode(zclient->ibuf, &p, &table, &note, NULL,
+ if (!zapi_route_notify_decode(g_zclient->ibuf, &p, &table, &note, NULL,
NULL))
return -1;
@@ -526,7 +526,7 @@ static void zebra_connected(struct zclient *zclient)
void vrf_label_add(vrf_id_t vrf_id, afi_t afi, mpls_label_t label)
{
- zclient_send_vrf_label(zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
+ zclient_send_vrf_label(g_zclient, vrf_id, afi, label, ZEBRA_LSP_SHARP);
}
void nhg_add(uint32_t id, const struct nexthop_group *nhg,
@@ -565,7 +565,7 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg,
if (sharp_nhgroup_id_is_installed(id)) {
zlog_debug("%s: nhg %u: no nexthops, deleting nexthop group", __func__,
id);
- zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg);
+ zclient_nhg_send(g_zclient, ZEBRA_NHG_DEL, &api_nhg);
return;
}
zlog_debug("%s: nhg %u not sent: no valid nexthops", __func__,
@@ -606,7 +606,7 @@ void nhg_add(uint32_t id, const struct nexthop_group *nhg,
done:
if (is_valid)
- zclient_nhg_send(zclient, ZEBRA_NHG_ADD, &api_nhg);
+ zclient_nhg_send(g_zclient, ZEBRA_NHG_ADD, &api_nhg);
}
void nhg_del(uint32_t id)
@@ -615,7 +615,7 @@ void nhg_del(uint32_t id)
api_nhg.id = id;
- zclient_nhg_send(zclient, ZEBRA_NHG_DEL, &api_nhg);
+ zclient_nhg_send(g_zclient, ZEBRA_NHG_DEL, &api_nhg);
}
void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import, bool watch,
@@ -629,7 +629,7 @@ void sharp_zebra_nexthop_watch(struct prefix *p, vrf_id_t vrf_id, bool import, b
if (!watch)
command = ZEBRA_NEXTHOP_UNREGISTER;
- if (zclient_send_rnh(zclient, command, p, safi, connected, false, vrf_id) ==
+ if (zclient_send_rnh(g_zclient, command, p, safi, connected, false, vrf_id) ==
ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop to zebra", __func__);
}
@@ -709,7 +709,7 @@ void sharp_redistribute_vrf(struct vrf *vrf, int type, bool turn_on)
{
zebra_redistribute_send(turn_on ? ZEBRA_REDISTRIBUTE_ADD
: ZEBRA_REDISTRIBUTE_DELETE,
- zclient, AFI_IP, type, 0, vrf->vrf_id);
+ g_zclient, AFI_IP, type, 0, vrf->vrf_id);
}
static zclient_handler *const sharp_opaque_handlers[] = {
@@ -720,7 +720,7 @@ static zclient_handler *const sharp_opaque_handlers[] = {
int sharp_zclient_create(uint32_t session_id)
{
struct zclient *client;
- struct sharp_zclient *node;
+ struct sharp_zclient_entry *node;
/* Check for duplicates */
for (node = sharp_clients_head; node != NULL; node = node->next) {
@@ -745,7 +745,7 @@ int sharp_zclient_create(uint32_t session_id)
/* Delete one of the extra test zclients */
int sharp_zclient_delete(uint32_t session_id)
{
- struct sharp_zclient *node;
+ struct sharp_zclient_entry *node;
/* Search for session */
for (node = sharp_clients_head; node != NULL; node = node->next) {
@@ -848,10 +848,10 @@ void sharp_opaque_send(uint32_t type, uint32_t proto, uint32_t instance,
/* Send some messages - broadcast and unicast are supported */
for (i = 0; i < count; i++) {
if (proto == 0)
- ret = zclient_send_opaque(zclient, type, buf,
+ ret = zclient_send_opaque(g_zclient, type, buf,
sizeof(buf));
else
- ret = zclient_send_opaque_unicast(zclient, type, proto,
+ ret = zclient_send_opaque_unicast(g_zclient, type, proto,
instance, session_id,
buf, sizeof(buf));
if (ret == ZCLIENT_SEND_FAILURE) {
@@ -868,9 +868,9 @@ void sharp_opaque_send(uint32_t type, uint32_t proto, uint32_t instance,
void sharp_zebra_opaque_notif_reg(bool is_reg, uint32_t type)
{
if (is_reg)
- zclient_opaque_request_notify(zclient, type);
+ zclient_opaque_request_notify(g_zclient, type);
else
- zclient_opaque_drop_notify(zclient, type);
+ zclient_opaque_drop_notify(g_zclient, type);
}
/*
@@ -881,7 +881,7 @@ void sharp_opaque_reg_send(bool is_reg, uint32_t proto, uint32_t instance,
{
struct stream *s;
- s = zclient->obuf;
+ s = g_zclient->obuf;
stream_reset(s);
if (is_reg)
@@ -900,22 +900,22 @@ void sharp_opaque_reg_send(bool is_reg, uint32_t proto, uint32_t instance,
/* Put length at the first point of the stream. */
stream_putw_at(s, 0, stream_get_endp(s));
- (void)zclient_send_message(zclient);
+ (void)zclient_send_message(g_zclient);
}
/* Link State registration */
void sharp_zebra_register_te(void)
{
/* First register to received Link State Update messages */
- zclient_register_opaque(zclient, LINK_STATE_UPDATE);
+ zclient_register_opaque(g_zclient, LINK_STATE_UPDATE);
/* Then, request initial TED with SYNC message */
- ls_request_sync(zclient);
+ ls_request_sync(g_zclient);
}
void sharp_zebra_send_arp(const struct interface *ifp, const struct prefix *p)
{
- zclient_send_neigh_discovery_req(zclient, ifp, p);
+ zclient_send_neigh_discovery_req(g_zclient, ifp, p);
}
static int nhg_notify_owner(ZAPI_CALLBACK_ARGS)
@@ -948,12 +948,12 @@ static int nhg_notify_owner(ZAPI_CALLBACK_ARGS)
int sharp_zebra_srv6_manager_get_locator_chunk(const char *locator_name)
{
- return srv6_manager_get_locator_chunk(zclient, locator_name);
+ return srv6_manager_get_locator_chunk(g_zclient, locator_name);
}
int sharp_zebra_srv6_manager_release_locator_chunk(const char *locator_name)
{
- return srv6_manager_release_locator_chunk(zclient, locator_name);
+ return srv6_manager_release_locator_chunk(g_zclient, locator_name);
}
static int sharp_zebra_process_srv6_locator_chunk(ZAPI_CALLBACK_ARGS)
@@ -1031,7 +1031,7 @@ int sharp_zebra_send_interface_protodown(struct interface *ifp, bool down)
zlog_debug("Sending zebra to set %s protodown %s", ifp->name,
down ? "on" : "off");
- if (zclient_send_interface_protodown(zclient, ifp->vrf->vrf_id, ifp,
+ if (zclient_send_interface_protodown(g_zclient, ifp->vrf->vrf_id, ifp,
down) == ZCLIENT_SEND_FAILURE)
return -1;
@@ -1047,12 +1047,12 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
#define SHARPD_TC_HANDLE 0x0001
struct stream *s;
- s = zclient->obuf;
+ s = g_zclient->obuf;
struct tc_qdisc q = {.ifindex = ifp->ifindex, .kind = TC_QDISC_HTB};
zapi_tc_qdisc_encode(ZEBRA_TC_QDISC_INSTALL, s, &q);
- if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
+ if (zclient_send_message(g_zclient) == ZCLIENT_SEND_FAILURE)
return -1;
struct tc_class c = {.ifindex = ifp->ifindex,
@@ -1062,7 +1062,7 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
.u.htb.rate = rate};
zapi_tc_class_encode(ZEBRA_TC_CLASS_ADD, s, &c);
- if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
+ if (zclient_send_message(g_zclient) == ZCLIENT_SEND_FAILURE)
return -1;
struct tc_filter f = {.ifindex = ifp->ifindex,
@@ -1090,7 +1090,7 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
f.u.flower.classid = SHARPD_TC_HANDLE & 0xffff;
zapi_tc_filter_encode(ZEBRA_TC_FILTER_ADD, s, &f);
- if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
+ if (zclient_send_message(g_zclient) == ZCLIENT_SEND_FAILURE)
return -1;
return 0;
@@ -1098,7 +1098,7 @@ int sharp_zebra_send_tc_filter_rate(struct interface *ifp,
void sharp_zebra_register_neigh(vrf_id_t vrf_id, afi_t afi, bool reg)
{
- zclient_register_neigh(zclient, vrf_id, afi, reg);
+ zclient_register_neigh(g_zclient, vrf_id, afi, reg);
}
@@ -1124,18 +1124,18 @@ void sharp_zebra_init(void)
hook_register_prio(if_down, 0, sharp_ifp_down);
hook_register_prio(if_unreal, 0, sharp_ifp_destroy);
- zclient = zclient_new(master, &zclient_options_default, sharp_handlers,
- array_size(sharp_handlers));
+ g_zclient = zclient_new(master, &zclient_options_default, sharp_handlers,
+ array_size(sharp_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
- zclient->zebra_connected = zebra_connected;
- zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready;
- zclient->nexthop_update = sharp_nexthop_update;
+ zclient_init(g_zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs);
+ g_zclient->zebra_connected = zebra_connected;
+ g_zclient->zebra_buffer_write_ready = sharp_zclient_buffer_ready;
+ g_zclient->nexthop_update = sharp_nexthop_update;
}
void sharp_zebra_terminate(void)
{
- struct sharp_zclient *node = sharp_clients_head;
+ struct sharp_zclient_entry *node = sharp_clients_head;
while (node) {
sharp_zclient_delete(node->client->session_id);
@@ -1143,6 +1143,6 @@ void sharp_zebra_terminate(void)
node = sharp_clients_head;
}
- zclient_stop(zclient);
- zclient_free(zclient);
+ zclient_stop(g_zclient);
+ zclient_free(g_zclient);
}
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index ffa90d5352..087df8efa0 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -86,6 +86,7 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
uint8_t segs_stack_id = 0;
char *orig_label = NULL, *orig_seg = NULL;
const char *buf_gate_str;
+ struct ipaddr gate_ip;
uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
route_tag_t tag = 0;
uint32_t table_id = 0;
@@ -149,22 +150,27 @@ static int static_route_nb_run(struct vty *vty, struct static_route_args *args)
if (src.prefixlen)
prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
- if (args->gateway)
+
+ if (args->gateway) {
buf_gate_str = args->gateway;
- else
+ if (str2ipaddr(args->gateway, &gate_ip) != 0) {
+ vty_out(vty, "%% Invalid gateway address %s\n", args->gateway);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ } else
buf_gate_str = "";
if (args->gateway == NULL && args->interface_name == NULL)
type = STATIC_BLACKHOLE;
else if (args->gateway && args->interface_name) {
- if (args->afi == AFI_IP)
+ if (gate_ip.ipa_type == IPADDR_V4)
type = STATIC_IPV4_GATEWAY_IFNAME;
else
type = STATIC_IPV6_GATEWAY_IFNAME;
} else if (args->interface_name)
type = STATIC_IFNAME;
else {
- if (args->afi == AFI_IP)
+ if (gate_ip.ipa_type == IPADDR_V4)
type = STATIC_IPV4_GATEWAY;
else
type = STATIC_IPV6_GATEWAY;
@@ -552,7 +558,7 @@ DEFPY_YANG(ip_route_address_interface,
ip_route_address_interface_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
- A.B.C.D$gate \
+ <A.B.C.D|X:X::X:X>$gate \
<INTERFACE|Null0>$ifname \
[{ \
tag (1-4294967295) \
@@ -571,7 +577,8 @@ DEFPY_YANG(ip_route_address_interface,
"IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
- "IP gateway address\n"
+ "IPv4 gateway address\n"
+ "IPv6 gateway address\n"
"IP gateway interface name\n"
"Null interface\n"
"Set tag for this route\n"
@@ -624,7 +631,7 @@ DEFPY_YANG(ip_route_address_interface_vrf,
ip_route_address_interface_vrf_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
- A.B.C.D$gate \
+ <A.B.C.D|X:X::X:X>$gate \
<INTERFACE|Null0>$ifname \
[{ \
tag (1-4294967295) \
@@ -642,7 +649,8 @@ DEFPY_YANG(ip_route_address_interface_vrf,
"IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
- "IP gateway address\n"
+ "IPv4 gateway address\n"
+ "IPv6 gateway address\n"
"IP gateway interface name\n"
"Null interface\n"
"Set tag for this route\n"
@@ -693,16 +701,16 @@ DEFPY_YANG(ip_route_address_interface_vrf,
DEFPY_YANG(ip_route,
ip_route_cmd,
"[no] ip route\
- <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
- <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
- [{ \
- tag (1-4294967295) \
- |(1-255)$distance \
- |vrf NAME \
- |label WORD \
- |table (1-4294967295) \
- |nexthop-vrf NAME \
- |color (1-4294967295) \
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |vrf NAME \
+ |label WORD \
+ |table (1-4294967295) \
+ |nexthop-vrf NAME \
+ |color (1-4294967295) \
|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
|segments WORD \
}]",
@@ -711,7 +719,8 @@ DEFPY_YANG(ip_route,
"IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
- "IP gateway address\n"
+ "IPv4 gateway address\n"
+ "IPv6 gateway address\n"
"IP gateway interface name\n"
"Null interface\n"
"Set tag for this route\n"
@@ -761,15 +770,15 @@ DEFPY_YANG(ip_route,
DEFPY_YANG(ip_route_vrf,
ip_route_vrf_cmd,
"[no] ip route\
- <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
- <A.B.C.D$gate|<INTERFACE|Null0>$ifname> \
- [{ \
- tag (1-4294967295) \
- |(1-255)$distance \
- |label WORD \
- |table (1-4294967295) \
- |nexthop-vrf NAME \
- |color (1-4294967295) \
+ <A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
+ <<A.B.C.D|X:X::X:X>$gate|<INTERFACE|Null0>$ifname> \
+ [{ \
+ tag (1-4294967295) \
+ |(1-255)$distance \
+ |label WORD \
+ |table (1-4294967295) \
+ |nexthop-vrf NAME \
+ |color (1-4294967295) \
|bfd$bfd [{multi-hop$bfd_multi_hop|source A.B.C.D$bfd_source|profile BFDPROF$bfd_profile}] \
|segments WORD \
}]",
@@ -778,7 +787,8 @@ DEFPY_YANG(ip_route_vrf,
"IP destination prefix (e.g. 10.0.0.0/8)\n"
"IP destination prefix\n"
"IP destination prefix mask\n"
- "IP gateway address\n"
+ "IPv4 gateway address\n"
+ "IPv6 gateway address\n"
"IP gateway interface name\n"
"Null interface\n"
"Set tag for this route\n"
@@ -1752,6 +1762,9 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP:
vty_out(vty, " behavior End.X PSP");
break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ vty_out(vty, " behavior End.B6.Encaps");
+ break;
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
vty_out(vty, " behavior End.X PSP/USD");
break;
@@ -1764,6 +1777,9 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
case SRV6_ENDPOINT_BEHAVIOR_END_DT46:
vty_out(vty, " behavior End.DT46");
break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ vty_out(vty, " behavior End.B6.Encaps.Red");
+ break;
case SRV6_ENDPOINT_BEHAVIOR_END_NEXT_CSID:
vty_out(vty, " behavior uN");
break;
@@ -1791,6 +1807,12 @@ static void srv6_sid_cli_show(struct vty *vty, const struct lyd_node *sid, bool
case SRV6_ENDPOINT_BEHAVIOR_END_DT46_USID:
vty_out(vty, " behavior uDT46");
break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ vty_out(vty, " behavior uB6.Encaps");
+ break;
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
+ vty_out(vty, " behavior uB6.Encaps.Red");
+ break;
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
vty_out(vty, " behavior unknown");
diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c
index 3ed525f386..cc09b42836 100644
--- a/staticd/static_zebra.c
+++ b/staticd/static_zebra.c
@@ -75,7 +75,7 @@ DECLARE_HASH(static_nht_hash, struct static_nht_data, itm, static_nht_data_cmp,
static struct static_nht_hash_head static_nht_hash[1];
/* Zebra structure to hold current status. */
-struct zclient *zclient;
+struct zclient *static_zclient;
uint32_t zebra_ecmp_count = MULTIPATH_NUM;
/* Interface addition message from zebra. */
@@ -209,14 +209,10 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
struct zapi_route *nhr)
{
struct static_nht_data *nhtd, lookup;
- afi_t afi = AFI_IP;
- if (zclient->bfd_integration)
+ if (static_zclient->bfd_integration)
bfd_nht_update(matched, nhr);
- if (matched->family == AF_INET6)
- afi = AFI_IP6;
-
if (nhr->type == ZEBRA_ROUTE_CONNECT) {
if (static_nexthop_is_local(vrf->vrf_id, matched,
nhr->prefix.family))
@@ -233,8 +229,12 @@ static void static_zebra_nexthop_update(struct vrf *vrf, struct prefix *matched,
if (nhtd) {
nhtd->nh_num = nhr->nexthop_num;
- static_nht_reset_start(matched, afi, nhr->safi, nhtd->nh_vrf_id);
- static_nht_update(NULL, NULL, matched, nhr->nexthop_num, afi, nhr->safi,
+ /* The tracked nexthop might be used by IPv4 and IPv6 routes */
+ static_nht_reset_start(matched, AFI_IP, nhr->safi, nhtd->nh_vrf_id);
+ static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP, nhr->safi,
+ nhtd->nh_vrf_id);
+ static_nht_reset_start(matched, AFI_IP6, nhr->safi, nhtd->nh_vrf_id);
+ static_nht_update(NULL, NULL, matched, nhr->nexthop_num, AFI_IP6, nhr->safi,
nhtd->nh_vrf_id);
} else
zlog_err("No nhtd?");
@@ -361,7 +361,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
if (reg) {
if (nhtd->nh_num) {
/* refresh with existing data */
- afi_t afi = prefix_afi(&lookup.nh);
+ afi_t afi = prefix_afi(&rn->p);
if (nh->state == STATIC_NOT_INSTALLED ||
nh->state == STATIC_SENT_TO_ZEBRA)
@@ -395,7 +395,7 @@ void static_zebra_nht_register(struct static_nexthop *nh, bool reg)
"Unregistering nexthop(%pFX) for %pRN", &lookup.nh, rn);
}
- if (zclient_send_rnh(zclient, cmd, &lookup.nh, si->safi, false, false,
+ if (zclient_send_rnh(static_zclient, cmd, &lookup.nh, si->safi, false, false,
nh->nh_vrf_id) == ZCLIENT_SEND_FAILURE)
zlog_warn("%s: Failure to send nexthop %pFX for %pRN to zebra",
__func__, &lookup.nh, rn);
@@ -549,7 +549,7 @@ extern void static_zebra_route_add(struct static_path *pn, bool install)
zclient_route_send(install ?
ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE,
- zclient, &api);
+ static_zclient, &api);
}
/**
@@ -594,7 +594,7 @@ static void static_zebra_send_localsid(int cmd, const struct in6_addr *sid, uint
memcpy(&api.prefix, &p, sizeof(p));
if (cmd == ZEBRA_ROUTE_DELETE)
- return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, zclient, &api);
+ return (void)zclient_route_send(ZEBRA_ROUTE_DELETE, static_zclient, &api);
SET_FLAG(api.flags, ZEBRA_FLAG_ALLOW_RECURSION);
SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
@@ -611,7 +611,7 @@ static void static_zebra_send_localsid(int cmd, const struct in6_addr *sid, uint
api.nexthop_num = 1;
- zclient_route_send(ZEBRA_ROUTE_ADD, zclient, &api);
+ zclient_route_send(ZEBRA_ROUTE_ADD, static_zclient, &api);
}
/**
@@ -625,8 +625,6 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
struct seg6local_context ctx = {};
struct interface *ifp = NULL;
struct vrf *vrf;
- struct prefix_ipv6 sid_block = {};
- struct prefix_ipv6 locator_block = {};
struct prefix_ipv6 sid_locator = {};
if (!sid)
@@ -732,28 +730,17 @@ void static_zebra_srv6_sid_install(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP:
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
zlog_warn("unsupported behavior: %u", sid->behavior);
break;
}
- sid_block = sid->addr;
- sid_block.prefixlen = sid->locator->block_bits_length;
- apply_mask(&sid_block);
-
- locator_block = sid->locator->prefix;
- locator_block.prefixlen = sid->locator->block_bits_length;
- apply_mask(&locator_block);
-
- if (prefix_same(&sid_block, &locator_block))
- ctx.block_len = sid->locator->block_bits_length;
- else {
- zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block,
- &locator_block);
- return;
- }
-
+ ctx.block_len = sid->locator->block_bits_length;
sid_locator = sid->addr;
sid_locator.prefixlen = sid->locator->block_bits_length + sid->locator->node_bits_length;
apply_mask(&sid_locator);
@@ -870,6 +857,10 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
zlog_warn("unsupported behavior: %u", sid->behavior);
break;
}
@@ -915,6 +906,30 @@ void static_zebra_srv6_sid_uninstall(struct static_srv6_sid *sid)
UNSET_FLAG(sid->flags, STATIC_FLAG_SRV6_SID_SENT_TO_ZEBRA);
}
+/* Validate if the sid block and locator block are the same */
+static bool static_zebra_sid_locator_block_check(struct static_srv6_sid *sid)
+{
+ struct prefix_ipv6 sid_block = {};
+ struct prefix_ipv6 locator_block = {};
+
+ sid_block = sid->addr;
+ sid_block.prefixlen = sid->locator->block_bits_length;
+ apply_mask(&sid_block);
+
+ locator_block = sid->locator->prefix;
+ locator_block.prefixlen = sid->locator->block_bits_length;
+ apply_mask(&locator_block);
+
+ if (!prefix_same(&sid_block, &locator_block)) {
+ zlog_warn("SID block %pFX does not match locator block %pFX", &sid_block,
+ &locator_block);
+
+ return false;
+ }
+
+ return true;
+}
+
extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
{
struct srv6_sid_ctx ctx = {};
@@ -922,7 +937,7 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
struct vrf *vrf;
struct interface *ifp;
- if (!sid)
+ if (!sid || !static_zebra_sid_locator_block_check(sid))
return;
/* convert `srv6_endpoint_behavior_codepoint` to `seg6local_action_t` */
@@ -992,12 +1007,17 @@ extern void static_zebra_request_srv6_sid(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
zlog_warn("unsupported behavior: %u", sid->behavior);
return;
}
/* Request SRv6 SID from SID Manager */
- ret = srv6_manager_get_sid(zclient, &ctx, &sid->addr.prefix, sid->locator->name, NULL);
+ ret = srv6_manager_get_sid(static_zclient, &ctx, &sid->addr.prefix, sid->locator->name,
+ NULL);
if (ret < 0)
zlog_warn("%s: error getting SRv6 SID!", __func__);
}
@@ -1079,12 +1099,16 @@ extern void static_zebra_release_srv6_sid(struct static_srv6_sid *sid)
case SRV6_ENDPOINT_BEHAVIOR_END_X_NEXT_CSID_PSP_USD:
case SRV6_ENDPOINT_BEHAVIOR_OPAQUE:
case SRV6_ENDPOINT_BEHAVIOR_RESERVED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_NEXT_CSID:
+ case SRV6_ENDPOINT_BEHAVIOR_END_B6_ENCAPS_RED_NEXT_CSID:
zlog_warn("unsupported behavior: %u", sid->behavior);
return;
}
/* remove the SRv6 SID from the zebra RIB */
- ret = srv6_manager_release_sid(zclient, &ctx);
+ ret = srv6_manager_release_sid(static_zclient, &ctx);
if (ret == ZCLIENT_SEND_FAILURE)
flog_err(EC_LIB_ZAPI_SOCKET, "zclient_send_get_srv6_sid() delete failed: %s",
safe_strerror(errno));
@@ -1105,7 +1129,7 @@ int static_zebra_srv6_manager_get_locator(const char *name)
* Send the Get Locator request to the SRv6 Manager and return the
* result
*/
- return srv6_manager_get_locator(zclient, name);
+ return srv6_manager_get_locator(static_zclient, name);
}
static void request_srv6_sids(struct static_srv6_locator *locator)
@@ -1360,16 +1384,16 @@ void static_zebra_init(void)
hook_register_prio(if_down, 0, static_ifp_down);
hook_register_prio(if_unreal, 0, static_ifp_destroy);
- zclient = zclient_new(master, &zclient_options_default, static_handlers,
- array_size(static_handlers));
+ static_zclient = zclient_new(master, &zclient_options_default, static_handlers,
+ array_size(static_handlers));
- zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
- zclient->zebra_capabilities = static_zebra_capabilities;
- zclient->zebra_connected = zebra_connected;
- zclient->nexthop_update = static_zebra_nexthop_update;
+ zclient_init(static_zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs);
+ static_zclient->zebra_capabilities = static_zebra_capabilities;
+ static_zclient->zebra_connected = zebra_connected;
+ static_zclient->nexthop_update = static_zebra_nexthop_update;
static_nht_hash_init(static_nht_hash);
- static_bfd_initialize(zclient, master);
+ static_bfd_initialize(static_zclient, master);
}
/* static_zebra_stop used by tests/lib/test_grpc.cpp */
@@ -1378,23 +1402,23 @@ void static_zebra_stop(void)
static_nht_hash_clear();
static_nht_hash_fini(static_nht_hash);
- if (!zclient)
+ if (!static_zclient)
return;
- zclient_stop(zclient);
- zclient_free(zclient);
- zclient = NULL;
+ zclient_stop(static_zclient);
+ zclient_free(static_zclient);
+ static_zclient = NULL;
}
void static_zebra_vrf_register(struct vrf *vrf)
{
if (vrf->vrf_id == VRF_DEFAULT)
return;
- zclient_send_reg_requests(zclient, vrf->vrf_id);
+ zclient_send_reg_requests(static_zclient, vrf->vrf_id);
}
void static_zebra_vrf_unregister(struct vrf *vrf)
{
if (vrf->vrf_id == VRF_DEFAULT)
return;
- zclient_send_dereg_requests(zclient, vrf->vrf_id);
+ zclient_send_dereg_requests(static_zclient, vrf->vrf_id);
}
diff --git a/tests/.gitignore b/tests/.gitignore
index 681438f4a5..51909cd81d 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -22,6 +22,7 @@ frr_northbound*
/lib/cli/test_commands
/lib/cli/test_commands_defun.c
/lib/northbound/test_oper_data
+/lib/northbound/test_oper_exists
/lib/cxxcompat
/lib/fuzz_zlog
/lib/test_assert
diff --git a/tests/isisd/test_common.c b/tests/isisd/test_common.c
index e47456965e..e22ee21365 100644
--- a/tests/isisd/test_common.c
+++ b/tests/isisd/test_common.c
@@ -33,11 +33,11 @@ test_topology_find_node(const struct isis_topology *topology,
}
const struct isis_topology *
-test_topology_find(struct isis_topology *test_topologies, uint16_t number)
+test_topology_find(struct isis_topology *topologies, uint16_t number)
{
- for (size_t i = 0; test_topologies[i].number; i++)
- if (test_topologies[i].number == number)
- return &test_topologies[i];
+ for (size_t i = 0; topologies[i].number; i++)
+ if (topologies[i].number == number)
+ return &topologies[i];
return NULL;
}
diff --git a/tests/isisd/test_fuzz_isis_tlv.c b/tests/isisd/test_fuzz_isis_tlv.c
index 48a2caacce..2a8a5bc5d7 100644
--- a/tests/isisd/test_fuzz_isis_tlv.c
+++ b/tests/isisd/test_fuzz_isis_tlv.c
@@ -161,7 +161,7 @@ static int test(FILE *input, FILE *output)
struct listnode *node;
for (ALL_LIST_ELEMENTS_RO(fragments, node, tlvs)) {
stream_reset(s);
- int rv = isis_pack_tlvs(tlvs, s, (size_t)-1, false, false);
+ rv = isis_pack_tlvs(tlvs, s, (size_t)-1, false, false);
if (rv) {
fprintf(output, "Could not pack fragment, too large.\n");
assert(0);
diff --git a/tests/lib/northbound/test_oper_data.c b/tests/lib/northbound/test_oper_data.c
index a38325173a..7a3618f3bf 100644
--- a/tests/lib/northbound/test_oper_data.c
+++ b/tests/lib/northbound/test_oper_data.c
@@ -249,9 +249,10 @@ static enum nb_error frr_test_module_c2cont_c2value_get(const struct nb_node *nb
struct lyd_node *parent)
{
const struct lysc_node *snode = nb_node->snode;
- uint32_t value = 0xAB010203;
+ uint32_t value = htole32(0xAB010203);
LY_ERR err;
+ /* Note that this api expects 'value' to be in little-endian form */
err = lyd_new_term_bin(parent, snode->module, snode->name, &value, sizeof(value),
LYD_NEW_PATH_UPDATE, NULL);
assert(err == LY_SUCCESS);
diff --git a/tests/lib/test_darr.c b/tests/lib/test_darr.c
index be319db1c1..d980db505d 100644
--- a/tests/lib/test_darr.c
+++ b/tests/lib/test_darr.c
@@ -157,12 +157,17 @@ static void test_int(void)
assert(!memcmp(da2, a1, sizeof(a1)));
- assert(darr_pop(da2) == 4);
- assert(darr_pop(da2) == 3);
- assert(darr_pop(da2) == 2);
+ i = darr_pop(da2);
+ assert(i == 4);
+ i = darr_pop(da2);
+ assert(i == 3);
+ i = darr_pop(da2);
+ assert(i == 2);
assert(darr_len(da2) == 2);
- assert(darr_pop(da2) == 1);
- assert(darr_pop(da2) == 0);
+ i = darr_pop(da2);
+ assert(i == 1);
+ i = darr_pop(da2);
+ assert(i == 0);
assert(darr_len(da2) == 0);
darr_free(da2);
@@ -323,38 +328,47 @@ static void test_string(void)
char *da2 = NULL;
const char **strings = NULL;
uint sum = 0;
+ uint i;
- assert(darr_strlen(da1) == 0);
+ i = darr_strlen(da1);
+ assert(i == 0);
da1 = darr_strdup(src);
- assert(darr_strlen(da1) == strlen(da1));
- assert(darr_strlen(da1) == srclen);
+ i = darr_strlen(da1);
+ assert(i == strlen(da1));
+ i = darr_strlen(da1);
+ assert(i == srclen);
assert(darr_len(da1) == srclen + 1);
assert(darr_ilen(da1) == (int)srclen + 1);
assert(darr_cap(da1) >= 8);
assert(darr_last(da1) == darr_strnul(da1));
- assert(darr_strnul(da1) == da1 + darr_strlen(da1));
+ i = darr_strlen(da1);
+ assert(darr_strnul(da1) == da1 + i);
da2 = da1;
darr_in_strdup(da1, src);
assert(da1 == da2);
- assert(darr_strlen(da1) == strlen(da1));
- assert(darr_strlen(da1) == srclen);
+ i = darr_strlen(da1);
+ assert(i == strlen(da1));
+ assert(i == srclen);
assert(darr_len(da1) == srclen + 1);
darr_free(da1);
assert(da1 == NULL);
da1 = darr_strdup_cap(src, 128);
- assert(darr_strlen(da1) == srclen);
+ i = darr_strlen(da1);
+ assert(i == srclen);
assert(darr_cap(da1) >= 128);
darr_in_strdup_cap(da1, src, 256);
- assert(darr_strlen(da1) == srclen);
+ i = darr_strlen(da1);
+ assert(i == srclen);
assert(darr_cap(da1) >= 256);
darr_free(da1);
da1 = darr_strdup_cap(add, 2);
- assert(darr_strlen(da1) == addlen);
+ i = darr_strlen(da1);
+ assert(i == addlen);
assert(darr_cap(da1) >= 8);
darr_in_strdup(da1, "ab");
@@ -377,7 +391,8 @@ static void test_string(void)
da2 = darr_strdup(add);
darr_in_strcat_tail(da1, da2);
assert(!strcmp("abHIJ", da1));
- assert(darr_strlen(da1) == 5);
+ i = darr_strlen(da1);
+ assert(i == 5);
assert(darr_len(da1) == 6);
darr_free(da1);
darr_free(da2);
@@ -386,14 +401,16 @@ static void test_string(void)
da2 = darr_strdup(add);
darr_in_strcat_tail(da1, da2);
assert(!strcmp("abcde", da1));
- assert(darr_strlen(da1) == 5);
+ i = darr_strlen(da1);
+ assert(i == 5);
assert(darr_len(da1) == 6);
darr_free(da1);
darr_free(da2);
da1 = darr_sprintf("0123456789: %08X", 0xDEADBEEF);
assert(!strcmp(da1, "0123456789: DEADBEEF"));
- assert(darr_strlen(da1) == 20);
+ i = darr_strlen(da1);
+ assert(i == 20);
assert(darr_cap(da1) == 128);
da2 = da1;
darr_in_sprintf(da1, "9876543210: %08x", 0x0BADF00D);
@@ -405,11 +422,13 @@ static void test_string(void)
da1 = NULL;
darr_in_sprintf(da1, "0123456789: %08X", 0xDEADBEEF);
assert(!strcmp(da1, "0123456789: DEADBEEF"));
- assert(darr_strlen(da1) == 20);
+ i = darr_strlen(da1);
+ assert(i == 20);
assert(darr_cap(da1) == 128);
da1[5] = 0;
- assert(darr_strlen_fixup(da1) == 5);
+ i = darr_strlen_fixup(da1);
+ assert(i == 5);
darr_free(da1);
da1 = darr_sprintf("0123456789: %08x", 0xDEADBEEF);
diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c
index a81ebcdbcd..c915587c13 100644
--- a/tests/lib/test_printfrr.c
+++ b/tests/lib/test_printfrr.c
@@ -107,7 +107,7 @@ static int printchk(const char *ref, const char *fmt, ...)
errors++;
}
- for (size_t i = 0; i < fb.outpos_i; i++)
+ for (i = 0; i < fb.outpos_i; i++)
printf("\t[%zu: %u..%u] = \"%.*s\"\n", i,
outpos[i].off_start,
outpos[i].off_end,
diff --git a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
index 80903b134e..3cecf9d946 100644
--- a/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
+++ b/tests/topotests/all_protocol_startup/test_all_protocol_startup.py
@@ -38,7 +38,6 @@ from lib.topogen import Topogen, get_topogen
from lib.common_config import (
required_linux_kernel_version,
)
-from lib.topolog import logger
import json
import functools
@@ -420,9 +419,9 @@ def route_get_nhg_id(route_str):
test_func = functools.partial(get_func, route_str)
_, nhg_id = topotest.run_and_expect_type(test_func, int, count=30, wait=1)
- if nhg_id == None:
+ if nhg_id is None:
fatal_error = "Nexthop Group ID not found for route {}".format(route_str)
- assert nhg_id != None, fatal_error
+ assert nhg_id is not None, fatal_error
else:
return nhg_id
@@ -710,7 +709,8 @@ def test_rip_status():
refTableFile = "{}/r{}/rip_status.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -771,7 +771,8 @@ def test_ripng_status():
refTableFile = "{}/r{}/ripng_status.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -834,7 +835,8 @@ def test_ospfv2_interfaces():
refTableFile = "{}/r{}/show_ip_ospf_interface.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -916,7 +918,8 @@ def test_isis_interfaces():
refTableFile = "{}/r{}/show_isis_interface_detail.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -979,7 +982,8 @@ def test_bgp_summary():
refTableFile = "{}/r{}/show_ip_bgp_summary.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected_original = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected_original = file.read().rstrip()
for arguments in [
"",
@@ -1152,7 +1156,8 @@ def test_bgp_ipv6_summary():
refTableFile = "{}/r{}/show_bgp_ipv6_summary.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -1244,7 +1249,8 @@ def test_nht():
for i in range(1, 2):
nhtFile = "{}/r{}/ip_nht.ref".format(thisDir, i)
- expected = open(nhtFile).read().rstrip()
+ with open(nhtFile) as file:
+ expected = file.read().rstrip()
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
actual = (
@@ -1266,7 +1272,8 @@ def test_nht():
print("show ip nht is ok\n")
nhtFile = "{}/r{}/ipv6_nht.ref".format(thisDir, i)
- expected = open(nhtFile).read().rstrip()
+ with open(nhtFile) as file:
+ expected = file.read().rstrip()
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
actual = (
@@ -1306,7 +1313,8 @@ def test_bgp_ipv4():
for refTableFile in glob.glob("{}/r{}/show_bgp_ipv4*.ref".format(thisDir, i)):
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -1377,7 +1385,8 @@ def test_bgp_ipv6():
for refTableFile in glob.glob("{}/r{}/show_bgp_ipv6*.ref".format(thisDir, i)):
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
@@ -1444,7 +1453,8 @@ def test_route_map():
for i in range(1, 2):
refroutemap = "{}/r{}/show_route_map.ref".format(thisDir, i)
if os.path.isfile(refroutemap):
- expected = open(refroutemap).read().rstrip()
+ with open(refroutemap) as file:
+ expected = file.read().rstrip()
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
actual = (
@@ -1649,7 +1659,8 @@ def test_mpls_interfaces():
refTableFile = "{}/r{}/show_mpls_ldp_interface.ref".format(thisDir, i)
if os.path.isfile(refTableFile):
# Read expected result from file
- expected = open(refTableFile).read().rstrip()
+ with open(refTableFile) as file:
+ expected = file.read().rstrip()
# Fix newlines (make them all the same)
expected = ("\n".join(expected.splitlines()) + "\n").splitlines(1)
diff --git a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
index 874ad09264..e2bcd004d4 100644
--- a/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
+++ b/tests/topotests/bgp_gr_notification/test_bgp_gr_notification.py
@@ -195,14 +195,14 @@ def test_bgp_administrative_reset_gr():
step("Reset and delay the session establishement for R1")
r1.vtysh_cmd(
"""
- configure terminal"
+ configure terminal
router bgp
neighbor 192.168.255.2 timers delayopen 60
"""
)
r2.vtysh_cmd(
"""
- configure terminal"
+ configure terminal
router bgp
neighbor 192.168.255.1 timers delayopen 60
"""
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
index 2210f24589..e1c533c1f3 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity/r3/bgpd.conf
@@ -4,6 +4,7 @@ hostname r3
password zebra
log stdout notifications
log commands
+#debug bgp vnc verbose
router bgp 5226
bgp router-id 3.3.3.3
bgp cluster-id 3.3.3.3
diff --git a/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py b/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py
index 7201ac8111..aaa43d5a7e 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py
+++ b/tests/topotests/bgp_rfapi_basic_sanity/scripts/cleanup_all.py
@@ -91,10 +91,10 @@ luCommand(
)
num = "0 exist"
-luCommand("r1", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear")
-luCommand("r2", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear")
-luCommand("r3", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear")
-luCommand("r4", 'vtysh -c "show bgp ipv4 vpn"', num, "pass", "VPN SAFI clear")
+luCommand("r1", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear")
+luCommand("r2", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear")
+luCommand("r3", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear")
+luCommand("r4", 'vtysh -c "show bgp ipv4 vpn"', num, "wait", "VPN SAFI clear")
luCommand(
"r1",
diff --git a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
index e74fc0b3de..04b10b4d22 100644
--- a/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
+++ b/tests/topotests/bgp_rfapi_basic_sanity_config2/r3/bgpd.conf
@@ -4,6 +4,7 @@ hostname r3
password zebra
log stdout notifications
log commands
+#debug bgp vnc verbose
router bgp 5226
bgp router-id 3.3.3.3
bgp cluster-id 3.3.3.3
diff --git a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
index 5b775aa6cb..bdf905feba 100644
--- a/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
+++ b/tests/topotests/bgp_rpki_topo1/test_bgp_rpki_topo1.py
@@ -477,6 +477,121 @@ def test_bgp_ecommunity_rpki():
assert result is None, "Received RPKI extended community"
+def test_show_bgp_rpki_as_number():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r3"]:
+ logger.info("{}: checking if rtrd is running".format(rname))
+ if rtrd_process[rname].poll() is not None:
+ pytest.skip(tgen.errors)
+
+ step("Check RPKI prefixes for ASN 65531")
+
+ rname = "r2"
+ output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki as-number 65531 json"))
+
+ # Expected output should show no prefixes for this ASN
+ expected = {"ipv4PrefixCount": 0, "ipv6PrefixCount": 0, "prefixes": []}
+
+ assert output == expected, "Found unexpected RPKI prefixes for ASN 65531"
+
+
+def test_show_bgp_rpki_as_number_65530():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r3"]:
+ logger.info("{}: checking if rtrd is running".format(rname))
+ if rtrd_process[rname].poll() is not None:
+ pytest.skip(tgen.errors)
+
+ step("Check RPKI prefixes for ASN 65530")
+
+ rname = "r2"
+ output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki as-number 65530 json"))
+
+ expected = {
+ "prefixes": [
+ {
+ "prefix": "198.51.100.0",
+ "prefixLenMin": 24,
+ "prefixLenMax": 24,
+ "asn": 65530,
+ },
+ {
+ "prefix": "203.0.113.0",
+ "prefixLenMin": 24,
+ "prefixLenMax": 24,
+ "asn": 65530,
+ },
+ ],
+ "ipv4PrefixCount": 2,
+ "ipv6PrefixCount": 0,
+ }
+
+ assert (
+ output == expected
+ ), "RPKI prefixes for ASN 65530 do not match expected output"
+
+
+def test_rpki_stop_and_check_connection():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r3"]:
+ logger.info("{}: checking if rtrd is running".format(rname))
+ if rtrd_process[rname].poll() is not None:
+ pytest.skip(tgen.errors)
+
+ step("Stop RPKI on r2")
+ rname = "r2"
+ tgen.gears[rname].vtysh_cmd("rpki stop")
+
+ step("Check RPKI cache connection status")
+ output = json.loads(tgen.gears[rname].vtysh_cmd("show rpki cache-connection json"))
+
+ expected = {"error": "No connection to RPKI cache server."}
+ assert (
+ output == expected
+ ), "RPKI cache connection status does not show as disconnected"
+
+
+def test_rpki_start_and_check_connection():
+ tgen = get_topogen()
+
+ if tgen.routers_have_failure():
+ pytest.skip(tgen.errors)
+
+ for rname in ["r1", "r3"]:
+ logger.info("{}: checking if rtrd is running".format(rname))
+ if rtrd_process[rname].poll() is not None:
+ pytest.skip(tgen.errors)
+
+ step("Start RPKI on r2")
+ rname = "r2"
+ tgen.gears[rname].vtysh_cmd("rpki start")
+
+ def _check_rpki_connection():
+ output = json.loads(
+ tgen.gears[rname].vtysh_cmd("show rpki cache-connection json")
+ )
+ # We expect to see a connected group and at least one connection
+ return "connectedGroup" in output and "connections" in output
+
+ step("Check RPKI cache connection status")
+ _, result = topotest.run_and_expect(
+ _check_rpki_connection, True, count=60, wait=0.5
+ )
+ assert result, "RPKI cache connection did not establish after start"
+
+
if __name__ == "__main__":
args = ["-s"] + sys.argv[1:]
sys.exit(pytest.main(args))
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf
deleted file mode 100644
index 3459796629..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/bgpd.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-frr defaults traditional
-!
-hostname ce1
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf
new file mode 100644
index 0000000000..ca28d55409
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/frr.conf
@@ -0,0 +1,18 @@
+frr defaults traditional
+!
+interface eth0
+ ipv6 address 2001:1::2/64
+!
+ip forwarding
+ipv6 forwarding
+!
+router bgp 65500
+ bgp router-id 1.1.2.1
+ no bgp network import-check
+ neighbor 2001:1::1 remote-as 65500
+ address-family ipv6 unicast
+ network 2011:1::1/64
+ neighbor 2001:1::1 activate
+ exit-address-family
+exit
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json
index d19e315772..b68f1a1112 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/ipv6_rib.json
@@ -2,24 +2,23 @@
"::/0": [
{
"prefix": "::/0",
- "protocol": "static",
+ "protocol": "bgp",
"vrfId": 0,
"vrfName": "default",
"selected": true,
"destSelected": true,
- "distance": 1,
+ "distance": 200,
"metric": 0,
"installed": true,
"table": 254,
"internalStatus": 16,
- "internalFlags": 73,
+ "internalFlags": 13,
"internalNextHopNum": 1,
"internalNextHopActiveNum": 1,
"nexthops": [
{
"flags": 3,
"fib": true,
- "ip": "2001:1::1",
"afi": "ipv6",
"interfaceName": "eth0",
"active": true,
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf
deleted file mode 100644
index 665808a0e7..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce1/zebra.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-log file zebra.log
-!
-hostname ce1
-!
-interface eth0
- ipv6 address 2001:1::2/64
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route ::/0 2001:1::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf
deleted file mode 100644
index 8ed9978749..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/bgpd.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-frr defaults traditional
-!
-hostname ce2
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf
new file mode 100644
index 0000000000..a15c5b48e0
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/frr.conf
@@ -0,0 +1,17 @@
+frr defaults traditional
+!
+interface eth0
+ ipv6 address 2001:2::2/64
+!
+ip forwarding
+ipv6 forwarding
+!
+router bgp 65501
+ bgp router-id 1.1.20.1
+ neighbor 2001:2::1 remote-as 65501
+ address-family ipv6 unicast
+ neighbor 2001:2::1 activate
+ exit-address-family
+exit
+
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json
index 35ff14efad..51076ee194 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/ipv6_rib.json
@@ -2,24 +2,23 @@
"::/0": [
{
"prefix": "::/0",
- "protocol": "static",
+ "protocol": "bgp",
"vrfId": 0,
"vrfName": "default",
"selected": true,
"destSelected": true,
- "distance": 1,
+ "distance": 200,
"metric": 0,
"installed": true,
"table": 254,
"internalStatus": 16,
- "internalFlags": 73,
+ "internalFlags": 13,
"internalNextHopNum": 1,
"internalNextHopActiveNum": 1,
"nexthops": [
{
"flags": 3,
"fib": true,
- "ip": "2001:2::1",
"afi": "ipv6",
"interfaceName": "eth0",
"active": true,
@@ -54,5 +53,32 @@
}
]
}
+ ],
+ "2011:1::/64": [
+ {
+ "prefix": "2011:1::/64",
+ "protocol": "bgp",
+ "vrfId": 0,
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 200,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 13,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "active": true
+ }
+ ]
+ }
]
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf
deleted file mode 100644
index cc9b90a3b0..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce2/zebra.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-log file zebra.log
-!
-hostname ce2
-!
-interface eth0
- ipv6 address 2001:2::2/64
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route ::/0 2001:2::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf
deleted file mode 100644
index a85d9701c7..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/bgpd.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-frr defaults traditional
-!
-hostname ce3
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf
new file mode 100644
index 0000000000..947a4a2551
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/frr.conf
@@ -0,0 +1,16 @@
+frr defaults traditional
+!
+interface eth0
+ ipv6 address 2001:3::2/64
+!
+ip forwarding
+ipv6 forwarding
+!
+router bgp 65500
+ bgp router-id 1.1.3.1
+ neighbor 2001:3::1 remote-as 65500
+ address-family ipv6 unicast
+ neighbor 2001:3::1 activate
+ exit-address-family
+exit
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json
index 2f2931f80f..6a373a80b8 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/ipv6_rib.json
@@ -2,24 +2,23 @@
"::/0": [
{
"prefix": "::/0",
- "protocol": "static",
+ "protocol": "bgp",
"vrfId": 0,
"vrfName": "default",
"selected": true,
"destSelected": true,
- "distance": 1,
+ "distance": 200,
"metric": 0,
"installed": true,
"table": 254,
"internalStatus": 16,
- "internalFlags": 73,
+ "internalFlags": 13,
"internalNextHopNum": 1,
"internalNextHopActiveNum": 1,
"nexthops": [
{
"flags": 3,
"fib": true,
- "ip": "2001:3::1",
"afi": "ipv6",
"interfaceName": "eth0",
"active": true,
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf
deleted file mode 100644
index beca0b1211..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce3/zebra.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-log file zebra.log
-!
-hostname ce3
-!
-interface eth0
- ipv6 address 2001:3::2/64
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route ::/0 2001:3::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf
deleted file mode 100644
index 93fb32fd1b..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/bgpd.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-frr defaults traditional
-!
-hostname ce4
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf
new file mode 100644
index 0000000000..3eaf47961e
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/frr.conf
@@ -0,0 +1,16 @@
+frr defaults traditional
+!
+interface eth0
+ ipv6 address 2001:4::2/64
+!
+ip forwarding
+ipv6 forwarding
+!
+router bgp 65501
+ bgp router-id 1.1.4.1
+ neighbor 2001:4::1 remote-as 65501
+ address-family ipv6 unicast
+ neighbor 2001:4::1 activate
+ exit-address-family
+exit
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json
index 8a98768e0d..da6bd55231 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/ipv6_rib.json
@@ -2,24 +2,23 @@
"::/0": [
{
"prefix": "::/0",
- "protocol": "static",
+ "protocol": "bgp",
"vrfId": 0,
"vrfName": "default",
"selected": true,
"destSelected": true,
- "distance": 1,
+ "distance": 200,
"metric": 0,
"installed": true,
"table": 254,
"internalStatus": 16,
- "internalFlags": 73,
+ "internalFlags": 13,
"internalNextHopNum": 1,
"internalNextHopActiveNum": 1,
"nexthops": [
{
"flags": 3,
"fib": true,
- "ip": "2001:4::1",
"afi": "ipv6",
"interfaceName": "eth0",
"active": true,
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf
deleted file mode 100644
index 7b21074df0..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce4/zebra.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-log file zebra.log
-!
-hostname ce4
-!
-interface eth0
- ipv6 address 2001:4::2/64
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route ::/0 2001:4::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf
deleted file mode 100644
index 2ab6f2d2a7..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/bgpd.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-frr defaults traditional
-!
-hostname ce5
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf
new file mode 100644
index 0000000000..5adfc7cfeb
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/frr.conf
@@ -0,0 +1,16 @@
+frr defaults traditional
+!
+interface eth0
+ ipv6 address 2001:5::2/64
+!
+ip forwarding
+ipv6 forwarding
+!
+router bgp 65500
+ bgp router-id 1.1.5.1
+ neighbor 2001:5::1 remote-as 65500
+ address-family ipv6 unicast
+ neighbor 2001:5::1 activate
+ exit-address-family
+exit
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json
index 80ff52ad6e..f8ab84d17a 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/ipv6_rib.json
@@ -2,24 +2,23 @@
"::/0": [
{
"prefix": "::/0",
- "protocol": "static",
+ "protocol": "bgp",
"vrfId": 0,
"vrfName": "default",
"selected": true,
"destSelected": true,
- "distance": 1,
+ "distance": 200,
"metric": 0,
"installed": true,
"table": 254,
"internalStatus": 16,
- "internalFlags": 73,
+ "internalFlags": 13,
"internalNextHopNum": 1,
"internalNextHopActiveNum": 1,
"nexthops": [
{
"flags": 3,
"fib": true,
- "ip": "2001:5::1",
"afi": "ipv6",
"interfaceName": "eth0",
"active": true,
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf
deleted file mode 100644
index b5ad48e709..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce5/zebra.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-log file zebra.log
-!
-hostname ce5
-!
-interface eth0
- ipv6 address 2001:5::2/64
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route ::/0 2001:5::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf
deleted file mode 100644
index e0b6540514..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/bgpd.conf
+++ /dev/null
@@ -1,8 +0,0 @@
-frr defaults traditional
-!
-hostname ce6
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf
new file mode 100644
index 0000000000..3870bd84a3
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/frr.conf
@@ -0,0 +1,16 @@
+frr defaults traditional
+!
+interface eth0
+ ipv6 address 2001:6::2/64
+!
+ip forwarding
+ipv6 forwarding
+!
+router bgp 65501
+ bgp router-id 1.1.6.1
+ neighbor 2001:6::1 remote-as 65501
+ address-family ipv6 unicast
+ neighbor 2001:6::1 activate
+ exit-address-family
+exit
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json
index ace6136f06..71ca42e396 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/ipv6_rib.json
@@ -2,24 +2,23 @@
"::/0": [
{
"prefix": "::/0",
- "protocol": "static",
+ "protocol": "bgp",
"vrfId": 0,
"vrfName": "default",
"selected": true,
"destSelected": true,
- "distance": 1,
+ "distance": 200,
"metric": 0,
"installed": true,
"table": 254,
"internalStatus": 16,
- "internalFlags": 73,
+ "internalFlags": 13,
"internalNextHopNum": 1,
"internalNextHopActiveNum": 1,
"nexthops": [
{
"flags": 3,
"fib": true,
- "ip": "2001:6::1",
"afi": "ipv6",
"interfaceName": "eth0",
"active": true,
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf
deleted file mode 100644
index 7d19d9880b..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/ce6/zebra.conf
+++ /dev/null
@@ -1,14 +0,0 @@
-log file zebra.log
-!
-hostname ce6
-!
-interface eth0
- ipv6 address 2001:6::2/64
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route ::/0 2001:6::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf
new file mode 100644
index 0000000000..ef05460b22
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/frr.conf
@@ -0,0 +1,97 @@
+! debug zebra packet
+! debug zebra dplane
+! debug zebra kernel
+! debug bgp neighbor-events
+! debug bgp zebra
+! debug bgp vnc verbose
+! debug bgp update-groups
+! debug bgp updates in
+! debug bgp updates out
+! debug bgp vpn label
+! debug bgp vpn leak-from-vrf
+! debug bgp vpn leak-to-vrf
+! debug bgp vpn rmap-event
+!
+interface eth0
+ ipv6 address 2001::1/64
+!
+interface eth1 vrf vrf10
+ ipv6 address 2001:1::1/64
+!
+interface eth2 vrf vrf10
+ ipv6 address 2001:3::1/64
+!
+interface eth3 vrf vrf20
+ ipv6 address 2001:5::1/64
+!
+segment-routing
+ srv6
+ locators
+ locator loc1
+ prefix 2001:db8:1:1::/64 func-bits 8
+ !
+ !
+!
+ip forwarding
+ipv6 forwarding
+!
+ipv6 route 2001:db8:2:1::/64 2001::2
+ipv6 route 2001:db8:2:2::/64 2001::2
+ipv6 route 2001:db8:2:3::/64 2001::2
+!
+line vty
+!
+no bgp send-extra-data-zebra
+router bgp 65500
+ bgp router-id 1.1.1.1
+ no bgp ebgp-requires-policy
+ no bgp default ipv4-unicast
+ neighbor 2001::2 remote-as 65501
+ neighbor 2001::2 timers 3 10
+ neighbor 2001::2 timers connect 1
+ !
+ address-family ipv6 vpn
+ neighbor 2001::2 activate
+ exit-address-family
+ !
+ segment-routing srv6
+ locator loc1
+ !
+!
+router bgp 65500 vrf vrf10
+ bgp router-id 1.1.1.1
+ no bgp ebgp-requires-policy
+ no bgp default ipv4-unicast
+ !
+ neighbor 2001:1::2 remote-as 65500
+ neighbor 2001:3::2 remote-as 65500
+ address-family ipv6 unicast
+ neighbor 2001:1::2 activate
+ neighbor 2001:1::2 default-originate
+ neighbor 2001:3::2 activate
+ neighbor 2001:3::2 default-originate
+ sid vpn export auto
+ rd vpn export 1:10
+ rt vpn both 99:99
+ import vpn
+ export vpn
+ redistribute connected
+ exit-address-family
+!
+router bgp 65500 vrf vrf20
+ bgp router-id 1.1.1.1
+ no bgp ebgp-requires-policy
+ no bgp default ipv4-unicast
+ neighbor 2001:5::2 remote-as 65500
+ !
+ address-family ipv6 unicast
+ neighbor 2001:5::2 activate
+ neighbor 2001:5::2 default-originate
+ sid vpn export auto
+ rd vpn export 1:20
+ rt vpn both 88:88
+ import vpn
+ export vpn
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json
index 0fdd3d6dc0..afa713e37f 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib.json
@@ -3,7 +3,7 @@
"vrfName": "default",
"routerId": "1.1.1.1",
"defaultLocPrf": 100,
- "localAS": 1,
+ "localAS": 65500,
"routes": {
"routeDistinguishers": {
"1:10": {
@@ -58,6 +58,32 @@
}
]
}
+ ],
+ "2011:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2011:1::",
+ "prefixLen": 64,
+ "network": "2011:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "IGP",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001:1::2",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
]
},
"1:20": {
@@ -101,7 +127,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -127,7 +153,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -151,7 +177,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -165,5 +191,7 @@
]
}
}
- }
+ },
+ "totalRoutes": 7,
+ "totalPaths": 7
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json
index f2df9be49d..a3a5f0438a 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_deleted.json
@@ -3,7 +3,7 @@
"vrfName": "default",
"routerId": "1.1.1.1",
"defaultLocPrf": 100,
- "localAS": 1,
+ "localAS": 65500,
"routes": {
"routeDistinguishers": {
"1:10": {
@@ -52,6 +52,29 @@
}
]
}
+ ],
+ "2011:1::/64": [
+ {
+ "pathFrom": "external",
+ "prefix": "2011:1::",
+ "prefixLen": 64,
+ "network": "2011:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "IGP",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001:1::2",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
]
},
"1:20": {
@@ -92,7 +115,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -118,7 +141,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -142,7 +165,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -156,5 +179,7 @@
]
}
}
- }
+ },
+ "totalRoutes": 7,
+ "totalPaths": 7
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json
index 0fdd3d6dc0..afa713e37f 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vpnv6_rib_locator_recreated.json
@@ -3,7 +3,7 @@
"vrfName": "default",
"routerId": "1.1.1.1",
"defaultLocPrf": 100,
- "localAS": 1,
+ "localAS": 65500,
"routes": {
"routeDistinguishers": {
"1:10": {
@@ -58,6 +58,32 @@
}
]
}
+ ],
+ "2011:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2011:1::",
+ "prefixLen": 64,
+ "network": "2011:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "IGP",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001:1::2",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
]
},
"1:20": {
@@ -101,7 +127,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -127,7 +153,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -151,7 +177,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::2",
- "path": "2",
+ "path": "65501",
"origin": "incomplete",
"nexthops": [
{
@@ -165,5 +191,7 @@
]
}
}
- }
+ },
+ "totalRoutes": 7,
+ "totalPaths": 7
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json
index 141c1cb957..aee6905d95 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf10_rib.json
@@ -53,8 +53,7 @@
"segs": "2001:db8:2:2:100::"
}
}
- ],
- "asPath": "2"
+ ]
}
],
"2001:3::/64": [
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json
index e20998061f..0f3c970afe 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/vrf20_rib.json
@@ -27,8 +27,7 @@
"segs": "2001:db8:2:2:200::"
}
}
- ],
- "asPath": "2"
+ ]
}
],
"2001:5::/64": [
@@ -85,8 +84,7 @@
"segs": "2001:db8:2:2:200::"
}
}
- ],
- "asPath": "2"
+ ]
}
]
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf
deleted file mode 100644
index c84106f2bb..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/zebra.conf
+++ /dev/null
@@ -1,41 +0,0 @@
-log file zebra.log
-!
-hostname r1
-password zebra
-!
-log stdout notifications
-log commands
-!
-! debug zebra packet
-! debug zebra dplane
-! debug zebra kernel
-!
-interface eth0
- ipv6 address 2001::1/64
-!
-interface eth1 vrf vrf10
- ipv6 address 2001:1::1/64
-!
-interface eth2 vrf vrf10
- ipv6 address 2001:3::1/64
-!
-interface eth3 vrf vrf20
- ipv6 address 2001:5::1/64
-!
-segment-routing
- srv6
- locators
- locator loc1
- prefix 2001:db8:1:1::/64 func-bits 8
- !
- !
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route 2001:db8:2:1::/64 2001::2
-ipv6 route 2001:db8:2:2::/64 2001::2
-ipv6 route 2001:db8:2:3::/64 2001::2
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf
new file mode 100644
index 0000000000..1bef01d0b3
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/frr.conf
@@ -0,0 +1,98 @@
+! debug zebra packet
+! debug zebra dplane
+! debug zebra kernel
+! debug bgp neighbor-events
+! debug bgp zebra
+! debug bgp vnc verbose
+! debug bgp update-groups
+! debug bgp updates in
+! debug bgp updates out
+! debug bgp updates
+! debug bgp vpn label
+! debug bgp vpn leak-from-vrf
+! debug bgp vpn leak-to-vrf
+! debug bgp vpn rmap-event
+!
+interface eth0
+ ipv6 address 2001::2/64
+!
+interface eth1 vrf vrf10
+ ipv6 address 2001:2::1/64
+!
+interface eth2 vrf vrf20
+ ipv6 address 2001:4::1/64
+!
+interface eth3 vrf vrf20
+ ipv6 address 2001:6::1/64
+!
+segment-routing
+ srv6
+ locators
+ locator loc1
+ prefix 2001:db8:2:2::/64 func-bits 8
+ !
+ !
+!
+ip forwarding
+ipv6 forwarding
+!
+ipv6 route 2001:db8:1:1::/64 2001::1
+ipv6 route 2001:db8:1:2::/64 2001::1
+ipv6 route 2001:db8:1:3::/64 2001::1
+!
+line vty
+!
+no bgp send-extra-data-zebra
+router bgp 65501
+ bgp router-id 2.2.2.2
+ no bgp ebgp-requires-policy
+ no bgp default ipv4-unicast
+ neighbor 2001::1 remote-as 65500
+ neighbor 2001::1 timers 3 10
+ neighbor 2001::1 timers connect 1
+ !
+ address-family ipv6 vpn
+ neighbor 2001::1 activate
+ exit-address-family
+ !
+ segment-routing srv6
+ locator loc1
+ !
+!
+router bgp 65501 vrf vrf10
+ bgp router-id 2.2.2.2
+ no bgp ebgp-requires-policy
+ no bgp default ipv4-unicast
+ !
+ neighbor 2001:2::2 remote-as 65501
+ address-family ipv6 unicast
+ neighbor 2001:2::2 activate
+ neighbor 2001:2::2 default-originate
+ sid vpn export auto
+ rd vpn export 2:10
+ rt vpn both 99:99
+ import vpn
+ export vpn
+ redistribute connected
+ exit-address-family
+!
+router bgp 65501 vrf vrf20
+ bgp router-id 2.2.2.2
+ no bgp ebgp-requires-policy
+ no bgp default ipv4-unicast
+ neighbor 2001:4::2 remote-as 65501
+ neighbor 2001:6::2 remote-as 65501
+ !
+ address-family ipv6 unicast
+ neighbor 2001:4::2 activate
+ neighbor 2001:4::2 default-originate
+ neighbor 2001:6::2 activate
+ neighbor 2001:6::2 default-originate
+ sid vpn export auto
+ rd vpn export 2:20
+ rt vpn both 88:88
+ import vpn
+ export vpn
+ redistribute connected
+ exit-address-family
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json
index 03bbcc008d..e7695281d9 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib.json
@@ -3,7 +3,7 @@
"vrfName": "default",
"routerId": "2.2.2.2",
"defaultLocPrf": 100,
- "localAS": 2,
+ "localAS": 65501,
"routes": {
"routeDistinguishers": {
"1:10": {
@@ -19,7 +19,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::1",
- "path": "1",
+ "path": "65500",
"origin": "incomplete",
"nexthops": [
{
@@ -43,7 +43,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::1",
- "path": "1",
+ "path": "65500",
"origin": "incomplete",
"nexthops": [
{
@@ -54,6 +54,30 @@
}
]
}
+ ],
+ "2011:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2011:1::",
+ "prefixLen": 64,
+ "network": "2011:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "65500",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
]
},
"1:20": {
@@ -69,7 +93,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::1",
- "path": "1",
+ "path": "65500",
"origin": "incomplete",
"nexthops": [
{
@@ -165,5 +189,7 @@
]
}
}
- }
+ },
+ "totalRoutes": 7,
+ "totalPaths": 7
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json
index 25cdf031c3..caa5803bfe 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_deleted.json
@@ -3,7 +3,7 @@
"vrfName": "default",
"routerId": "2.2.2.2",
"defaultLocPrf": 100,
- "localAS": 2,
+ "localAS": 65501,
"routes": {
"routeDistinguishers": {
"2:10": {
@@ -89,5 +89,7 @@
]
}
}
- }
+ },
+ "totalRoutes": 3,
+ "totalPaths": 3
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json
index 03bbcc008d..e7695281d9 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vpnv6_rib_locator_recreated.json
@@ -3,7 +3,7 @@
"vrfName": "default",
"routerId": "2.2.2.2",
"defaultLocPrf": 100,
- "localAS": 2,
+ "localAS": 65501,
"routes": {
"routeDistinguishers": {
"1:10": {
@@ -19,7 +19,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::1",
- "path": "1",
+ "path": "65500",
"origin": "incomplete",
"nexthops": [
{
@@ -43,7 +43,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::1",
- "path": "1",
+ "path": "65500",
"origin": "incomplete",
"nexthops": [
{
@@ -54,6 +54,30 @@
}
]
}
+ ],
+ "2011:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2011:1::",
+ "prefixLen": 64,
+ "network": "2011:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "65500",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
]
},
"1:20": {
@@ -69,7 +93,7 @@
"metric": 0,
"weight": 0,
"peerId": "2001::1",
- "path": "1",
+ "path": "65500",
"origin": "incomplete",
"nexthops": [
{
@@ -165,5 +189,7 @@
]
}
}
- }
+ },
+ "totalRoutes": 7,
+ "totalPaths": 7
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json
index 7f8a930d00..407dfb9fb4 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf10_rib.json
@@ -27,8 +27,7 @@
"segs": "2001:db8:1:1:100::"
}
}
- ],
- "asPath": "1"
+ ]
}
],
"2001:2::/64": [
@@ -85,8 +84,38 @@
"segs": "2001:db8:1:1:100::"
}
}
- ],
- "asPath": "1"
+ ]
+ }
+ ],
+ "2011:1::/64": [
+ {
+ "prefix": "2011:1::/64",
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "vrf": "default",
+ "active": true,
+ "weight": 1,
+ "seg6": {
+ "segs": "2001:db8:1:1:100::"
+ }
+ }
+ ]
}
]
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json
index 104bdc30d2..90e0413db2 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/vrf20_rib.json
@@ -53,8 +53,7 @@
"segs": "2001:db8:1:1:200::"
}
}
- ],
- "asPath": "1"
+ ]
}
],
"2001:6::/64": [
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf
deleted file mode 100644
index 5c12429ff2..0000000000
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/zebra.conf
+++ /dev/null
@@ -1,41 +0,0 @@
-log file zebra.log
-!
-hostname r2
-password zebra
-!
-log stdout notifications
-log commands
-!
-! debug zebra packet
-! debug zebra dplane
-! debug zebra kernel
-!
-interface eth0
- ipv6 address 2001::2/64
-!
-interface eth1 vrf vrf10
- ipv6 address 2001:2::1/64
-!
-interface eth2 vrf vrf20
- ipv6 address 2001:4::1/64
-!
-interface eth3 vrf vrf20
- ipv6 address 2001:6::1/64
-!
-segment-routing
- srv6
- locators
- locator loc1
- prefix 2001:db8:2:2::/64 func-bits 8
- !
- !
-!
-ip forwarding
-ipv6 forwarding
-!
-ipv6 route 2001:db8:1:1::/64 2001::1
-ipv6 route 2001:db8:1:2::/64 2001::1
-ipv6 route 2001:db8:1:3::/64 2001::1
-!
-line vty
-!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
index a6938668ad..c30410d4dc 100755
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/test_bgp_srv6l3vpn_to_bgp_vrf.py
@@ -92,14 +92,8 @@ def setup_module(mod):
tgen.start_topology()
router_list = tgen.routers()
for rname, router in tgen.routers().items():
- if os.path.exists("{}/{}/setup.sh".format(CWD, rname)):
- router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
- 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))
- )
+ logger.info("Loading router %s" % rname)
+ router.load_frr_config(os.path.join(CWD, "{}/frr.conf".format(rname)))
tgen.gears["r1"].run("ip link add vrf10 type vrf table 10")
tgen.gears["r1"].run("ip link set vrf10 up")
@@ -218,7 +212,7 @@ def test_bgp_locator_unset():
get_topogen().gears["r1"].vtysh_cmd(
"""
configure terminal
- router bgp 1
+ router bgp 65500
segment-routing srv6
no locator loc1
"""
@@ -233,7 +227,7 @@ def test_bgp_locator_reset():
get_topogen().gears["r1"].vtysh_cmd(
"""
configure terminal
- router bgp 1
+ router bgp 65500
segment-routing srv6
locator loc1
"""
@@ -248,7 +242,7 @@ def test_bgp_srv6_unset():
get_topogen().gears["r1"].vtysh_cmd(
"""
configure terminal
- router bgp 1
+ router bgp 65500
no segment-routing srv6
"""
)
@@ -262,7 +256,7 @@ def test_bgp_srv6_reset():
get_topogen().gears["r1"].vtysh_cmd(
"""
configure terminal
- router bgp 1
+ router bgp 65500
segment-routing srv6
locator loc1
"""
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf
index 3459796629..188ec7a86c 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/bgpd.conf
@@ -1,8 +1,3 @@
frr defaults traditional
-!
-hostname ce1
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
+
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf
index 447d1b40c1..6c9abca36f 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce1/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce1
-!
interface eth0
ip address 192.168.1.2/24
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf
index 8ed9978749..05268f8878 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/bgpd.conf
@@ -1,8 +1,2 @@
frr defaults traditional
-!
-hostname ce2
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
+
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf
index 11652252a4..b0e6470307 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce2/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce2
-!
interface eth0
ip address 192.168.2.2/24
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf
index a85d9701c7..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce3
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf
index 299c6597c7..f0fd4f497a 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce3/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce3
-!
interface eth0
ip address 192.168.3.2/24
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf
index 93fb32fd1b..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce4
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf
index 30f3736fe3..da745f2bd0 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce4/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce4
-!
interface eth0
ip address 192.168.4.2/24
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf
index 2ab6f2d2a7..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce5
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf
index 208dcb1a7a..37391ebb49 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce5/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce5
-!
interface eth0
ip address 192.168.5.2/24
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf
index e0b6540514..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce6
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf
index d68a008e3a..9696993c33 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/ce6/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce6
-!
interface eth0
ip address 192.168.6.2/24
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf
index 12b9e8fd00..d4be6c7d6a 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/bgpd.conf
@@ -1,13 +1,5 @@
frr defaults traditional
-!
bgp send-extra-data zebra
-!
-hostname r1
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug bgp neighbor-events
!debug bgp zebra
!debug bgp vnc verbose
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf
index f202493c53..64e6af0c1b 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r1/zebra.conf
@@ -1,11 +1,3 @@
-log file zebra.log
-!
-hostname r1
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug zebra packet
!debug zebra dplane
!debug zebra kernel
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf
index db36c180a0..5ff570069c 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/bgpd.conf
@@ -1,13 +1,5 @@
frr defaults traditional
-!
bgp send-extra-data zebra
-!
-hostname r2
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug bgp neighbor-events
!debug bgp zebra
!debug bgp vnc verbose
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf
index 9dfed4f2d6..22b689d538 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf2/r2/zebra.conf
@@ -1,11 +1,3 @@
-log file zebra.log
-!
-hostname r2
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug zebra packet
!debug zebra dplane
!debug zebra kernel
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf
index 3459796629..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce1
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf
index 58e851d752..a6eab175f5 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce1/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce1
-!
interface eth0
ip address 192.168.1.2/24
ipv6 address 2001:1::2/64
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf
index 8ed9978749..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce2
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf
index 0612c53223..3be205a8c9 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce2/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce2
-!
interface eth0
ip address 192.168.2.2/24
ipv6 address 2001:2::2/64
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf
index a85d9701c7..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce3
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf
index d08fdadc3c..2fb86c74de 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce3/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce3
-!
interface eth0
ip address 192.168.3.2/24
ipv6 address 2001:3::2/64
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf
index 93fb32fd1b..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce4
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf
index 897ed46c27..3bbbd08558 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce4/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce4
-!
interface eth0
ip address 192.168.4.2/24
ipv6 address 2001:4::2/64
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf
index 2ab6f2d2a7..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce5/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce5
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf
index e0b6540514..cd72007f46 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/bgpd.conf
@@ -1,8 +1 @@
frr defaults traditional
-!
-hostname ce6
-password zebra
-!
-log stdout notifications
-log commands
-log file bgpd.log
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf
index 5a83e901e8..d39a6a6bcb 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/ce6/zebra.conf
@@ -1,7 +1,3 @@
-log file zebra.log
-!
-hostname ce6
-!
interface eth0
ip address 192.168.6.2/24
ipv6 address 2001:6::2/64
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf
index 57c19e25d7..5e78e5e1a1 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/bgpd.conf
@@ -1,13 +1,5 @@
frr defaults traditional
-!
bgp send-extra-data zebra
-!
-hostname r1
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug bgp neighbor-events
!debug bgp zebra
!debug bgp vnc verbose
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json
index 5645540fbb..4e803a0514 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_locator_deleted.json
@@ -9,9 +9,7 @@
"1:10": {
"192.168.1.0/24": [
{
- "valid": true,
- "bestpath": true,
- "selectionReason": "First path received",
+ "multipath": true,
"pathFrom": "external",
"prefix": "192.168.1.0",
"prefixLen": 24,
@@ -34,9 +32,7 @@
],
"192.168.3.0/24": [
{
- "valid": true,
- "bestpath": true,
- "selectionReason": "First path received",
+ "multipath": true,
"pathFrom": "external",
"prefix": "192.168.3.0",
"prefixLen": 24,
@@ -61,9 +57,7 @@
"1:20": {
"192.168.5.0/24": [
{
- "valid": true,
- "bestpath": true,
- "selectionReason": "First path received",
+ "multipath": true,
"pathFrom": "external",
"prefix": "192.168.5.0",
"prefixLen": 24,
@@ -84,6 +78,82 @@
]
}
]
+ },
+ "2:10": {
+ "192.168.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.2.0",
+ "prefixLen": 24,
+ "network": "192.168.2.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:20": {
+ "192.168.4.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.4.0",
+ "prefixLen": 24,
+ "network": "192.168.4.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "192.168.6.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.6.0",
+ "prefixLen": 24,
+ "network": "192.168.6.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2",
+ "origin": "incomplete",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
}
}
}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json
index 205079574c..d49c357432 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv4_rib_sid_vpn_export_disabled.json
@@ -6,6 +6,54 @@
"localAS": 1,
"routes": {
"routeDistinguishers": {
+ "1:10": {
+ "192.168.1.0/24": [
+ {
+ "multipath": true,
+ "pathFrom": "external",
+ "prefix": "192.168.1.0",
+ "prefixLen": 24,
+ "network": "192.168.1.0/24",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "192.168.3.0/24": [
+ {
+ "multipath": true,
+ "pathFrom": "external",
+ "prefix": "192.168.3.0",
+ "prefixLen": 24,
+ "network": "192.168.3.0/24",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
"1:20": {
"192.168.5.0/24": [
{
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json
index f2df9be49d..547b262d4b 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_locator_deleted.json
@@ -9,6 +9,7 @@
"1:10": {
"2001:1::/64": [
{
+ "multipath": true,
"pathFrom": "external",
"prefix": "2001:1::",
"prefixLen": 64,
@@ -32,6 +33,7 @@
],
"2001:3::/64": [
{
+ "multipath": true,
"pathFrom": "external",
"prefix": "2001:3::",
"prefixLen": 64,
@@ -57,6 +59,7 @@
"1:20": {
"2001:5::/64": [
{
+ "multipath": true,
"pathFrom": "external",
"prefix": "2001:5::",
"prefixLen": 64,
@@ -131,7 +134,7 @@
}
],
"2001:6::/64": [
- {
+ {
"valid": true,
"bestpath": true,
"selectionReason": "First path received",
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json
index e289df1d44..8cfe223101 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/vpnv6_rib_sid_vpn_export_disabled.json
@@ -6,6 +6,56 @@
"localAS": 1,
"routes": {
"routeDistinguishers": {
+ "1:10": {
+ "2001:1::/64": [
+ {
+ "multipath": true,
+ "pathFrom": "external",
+ "prefix": "2001:1::",
+ "prefixLen": 64,
+ "network": "2001:1::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ],
+ "2001:3::/64": [
+ {
+ "multipath": true,
+ "pathFrom": "external",
+ "prefix": "2001:3::",
+ "prefixLen": 64,
+ "network": "2001:3::/64",
+ "metric": 0,
+ "weight": 32768,
+ "peerId": "(unspec)",
+ "path": "",
+ "origin": "incomplete",
+ "announceNexthopSelf": true,
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "::",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
"1:20": {
"2001:5::/64": [
{
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf
index dd8a756a6e..a7515e12d3 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r1/zebra.conf
@@ -1,11 +1,3 @@
-log file zebra.log
-!
-hostname r1
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug zebra packet
!debug zebra dplane
!debug zebra kernel
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf
index abf4971a9b..bf04fbc7aa 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/bgpd.conf
@@ -1,13 +1,5 @@
frr defaults traditional
-!
bgp send-extra-data zebra
-!
-hostname r2
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug bgp neighbor-events
!debug bgp zebra
!debug bgp vnc verbose
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf
index 3c9e4e3b25..27919cc63f 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/r2/zebra.conf
@@ -1,11 +1,3 @@
-log file zebra.log
-!
-hostname r2
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug zebra packet
!debug zebra dplane
!debug zebra kernel
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
index 530537646b..9e588d1d71 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf3/test_bgp_srv6l3vpn_to_bgp_vrf3.py
@@ -18,6 +18,7 @@ sys.path.append(os.path.join(CWD, "../"))
# pylint: disable=C0413
# Import topogen and topotest helpers
from lib import topotest
+from lib.bgp import bgp_vpn_router_json_cmp_exact_filter
from lib.topogen import Topogen, TopoRouter, get_topogen
from lib.topolog import logger
from lib.common_config import required_linux_kernel_version
@@ -95,24 +96,29 @@ def open_json_file(filename):
assert False, "Could not read file {}".format(filename)
-def check_rib(name, cmd, expected_file, count=30, wait=0.5):
- def _check(name, dest_addr, match):
+def check_rib(name, cmd, expected_file, count=10, wait=0.5):
+ def _check(router, cmd, expected):
logger.info("polling")
tgen = get_topogen()
- router = tgen.gears[name]
output = json.loads(router.vtysh_cmd(cmd))
- expected = open_json_file("{}/{}".format(CWD, expected_file))
return topotest.json_cmp(output, expected)
logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file))
tgen = get_topogen()
- func = functools.partial(_check, name, cmd, expected_file)
+ router = tgen.gears[name]
+ expected = open_json_file("{}/{}".format(CWD, expected_file))
+ if "show bgp" in cmd and "vpn" in cmd:
+ func = functools.partial(
+ bgp_vpn_router_json_cmp_exact_filter, tgen.gears[name], cmd, expected
+ )
+ else:
+ func = functools.partial(_check, router, cmd, expected)
_, result = topotest.run_and_expect(func, None, count, wait)
assert result is None, "Failed"
def test_rib():
- check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 120, 1)
+ check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 10, 1)
check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json")
check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json")
check_rib("r1", "show ip route vrf vrf20 json", "r1/vrf20v4_rib.json")
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf
new file mode 100644
index 0000000000..a2f5aef51e
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/bgpd.conf
@@ -0,0 +1,35 @@
+frr defaults traditional
+bgp send-extra-data zebra
+!debug bgp neighbor-events
+!debug bgp zebra
+!debug bgp vnc verbose
+!debug bgp update-groups
+!debug bgp updates in
+!debug bgp updates out
+!debug bgp vpn label
+!debug bgp vpn leak-from-vrf
+!debug bgp vpn leak-to-vrf
+!debug bgp vpn rmap-event
+!
+router bgp 65001
+ bgp router-id 1.0.0.1
+ no bgp ebgp-requires-policy
+ !no bgp default ipv4-unicast
+ neighbor fd01::1 remote-as 1
+ neighbor fd01::1 timers 3 10
+ neighbor fd01::1 timers connect 1
+ neighbor fd01::1 interface eth0
+ neighbor fd01::1 update-source fd01::2
+ neighbor fd01::1 capability extended-nexthop
+ !
+ address-family ipv4 unicast
+ network 192.168.1.0 mask 255.255.255.0
+ neighbor fd01::1 activate
+ exit-address-family
+ !
+ address-family ipv6 unicast
+ network 2001:1::/64
+ neighbor fd01::1 activate
+ exit-address-family
+ !
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json
new file mode 100644
index 0000000000..352c48b1b2
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ip_rib.json
@@ -0,0 +1,59 @@
+{
+ "192.168.1.0/24": [
+ {
+ "prefix": "192.168.1.0/24",
+ "prefixLen": 24,
+ "protocol": "connected",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 0,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "directlyConnected": true,
+ "interfaceName": "dum0",
+ "active": true,
+ "weight": 1
+ }
+ ]
+ }
+ ],
+ "192.168.2.0/24": [
+ {
+ "prefix": "192.168.2.0/24",
+ "prefixLen": 24,
+ "protocol": "bgp",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "1 2 65002"
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json
new file mode 100644
index 0000000000..fd10ee326f
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/ipv6_rib.json
@@ -0,0 +1,59 @@
+{
+ "2001:1::/64": [
+ {
+ "prefix": "2001:1::/64",
+ "prefixLen": 64,
+ "protocol": "connected",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 0,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "directlyConnected": true,
+ "interfaceName": "dum0",
+ "active": true,
+ "weight": 1
+ }
+ ]
+ }
+ ],
+ "2001:2::/64": [
+ {
+ "prefix": "2001:2::/64",
+ "prefixLen": 64,
+ "protocol": "bgp",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "1 2 65002"
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh
new file mode 100644
index 0000000000..88bdcbda82
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/setup.sh
@@ -0,0 +1 @@
+ip link add dum0 type dummy
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf
new file mode 100644
index 0000000000..16102a055d
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce1/zebra.conf
@@ -0,0 +1,12 @@
+interface eth0
+ ipv6 address fd01::2/64
+!
+interface dum0
+ ip address 192.168.1.1/24
+ ipv6 address 2001:1::1/64
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf
new file mode 100644
index 0000000000..e6b40c4bfe
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/bgpd.conf
@@ -0,0 +1,35 @@
+frr defaults traditional
+bgp send-extra-data zebra
+!debug bgp neighbor-events
+!debug bgp zebra
+!debug bgp vnc verbose
+!debug bgp update-groups
+!debug bgp updates in
+!debug bgp updates out
+!debug bgp vpn label
+!debug bgp vpn leak-from-vrf
+!debug bgp vpn leak-to-vrf
+!debug bgp vpn rmap-event
+!
+router bgp 65002
+ bgp router-id 2.0.0.2
+ no bgp ebgp-requires-policy
+ !no bgp default ipv4-unicast
+ neighbor fd02::1 remote-as 2
+ neighbor fd02::1 timers 3 10
+ neighbor fd02::1 timers connect 1
+ neighbor fd02::1 interface eth0
+ neighbor fd02::1 update-source fd02::2
+ neighbor fd02::1 capability extended-nexthop
+ !
+ address-family ipv4 unicast
+ network 192.168.2.0 mask 255.255.255.0
+ neighbor fd02::1 activate
+ exit-address-family
+ !
+ address-family ipv6 unicast
+ network 2001:2::/64
+ neighbor fd02::1 activate
+ exit-address-family
+ !
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json
new file mode 100644
index 0000000000..936f239ea6
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ip_rib.json
@@ -0,0 +1,59 @@
+{
+ "192.168.1.0/24": [
+ {
+ "prefix": "192.168.1.0/24",
+ "prefixLen": 24,
+ "protocol": "bgp",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "2 1 65001"
+ }
+ ],
+ "192.168.2.0/24": [
+ {
+ "prefix": "192.168.2.0/24",
+ "prefixLen": 24,
+ "protocol": "connected",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 0,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "directlyConnected": true,
+ "interfaceName": "dum0",
+ "active": true,
+ "weight": 1
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json
new file mode 100644
index 0000000000..260adbc20c
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/ipv6_rib.json
@@ -0,0 +1,59 @@
+{
+ "2001:1::/64": [
+ {
+ "prefix": "2001:1::/64",
+ "prefixLen": 64,
+ "protocol": "bgp",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "2 1 65001"
+ }
+ ],
+ "2001:2::/64": [
+ {
+ "prefix": "2001:2::/64",
+ "prefixLen": 64,
+ "protocol": "connected",
+ "vrfName": "default",
+ "selected": true,
+ "destSelected": true,
+ "distance": 0,
+ "metric": 0,
+ "installed": true,
+ "table": 254,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "directlyConnected": true,
+ "interfaceName": "dum0",
+ "active": true,
+ "weight": 1
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh
new file mode 100644
index 0000000000..88bdcbda82
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/setup.sh
@@ -0,0 +1 @@
+ip link add dum0 type dummy
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf
new file mode 100644
index 0000000000..f17e96a0da
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/ce2/zebra.conf
@@ -0,0 +1,12 @@
+interface eth0
+ ipv6 address fd02::2/64
+!
+interface dum0
+ ip address 192.168.2.1/24
+ ipv6 address 2001:2::1/64
+!
+ip forwarding
+ipv6 forwarding
+!
+line vty
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/bgpd.conf
index 8079bb0c2a..d0be14f007 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r1/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/bgpd.conf
@@ -1,14 +1,7 @@
frr defaults traditional
-!
bgp send-extra-data zebra
-!
-hostname r1
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug bgp neighbor-events
+!debug bgp nht
!debug bgp zebra
!debug bgp vnc verbose
!debug bgp update-groups
@@ -21,11 +14,16 @@ log commands
!
router bgp 1
bgp router-id 1.1.1.1
- no bgp ebgp-requires-policy
no bgp default ipv4-unicast
+ no bgp ebgp-requires-policy
neighbor 2001::2 remote-as 2
neighbor 2001::2 timers 3 10
neighbor 2001::2 timers connect 1
+ neighbor 2001::2 capability extended-nexthop
+ !
+ address-family ipv4 vpn
+ neighbor 2001::2 activate
+ exit-address-family
!
address-family ipv6 vpn
neighbor 2001::2 activate
@@ -38,28 +36,28 @@ router bgp 1
router bgp 1 vrf vrf10
bgp router-id 1.1.1.1
no bgp ebgp-requires-policy
- no bgp default ipv4-unicast
+ sid vpn per-vrf export auto
+ neighbor fd01::2 remote-as 65001
+ neighbor fd01::2 capability extended-nexthop
+ neighbor fd01::2 description ce1
+ neighbor fd01::2 interface eth1
+ neighbor fd01::2 update-source fd01::1
!
- address-family ipv6 unicast
- sid vpn export auto
+ address-family ipv4 unicast
+ nexthop vpn export 2001::1
rd vpn export 1:10
rt vpn both 99:99
import vpn
export vpn
- redistribute connected
+ neighbor fd01::2 activate
exit-address-family
-!
-router bgp 1 vrf vrf20
- bgp router-id 1.1.1.1
- no bgp ebgp-requires-policy
- no bgp default ipv4-unicast
!
address-family ipv6 unicast
- sid vpn export auto
- rd vpn export 1:20
- rt vpn both 88:88
+ nexthop vpn export 2001::1
+ rd vpn export 1:10
+ rt vpn both 99:99
import vpn
export vpn
- redistribute connected
+ neighbor fd01::2 activate
exit-address-family
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh
new file mode 100644
index 0000000000..ac1844f733
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/setup.sh
@@ -0,0 +1,4 @@
+sysctl net.vrf.strict_mode=1
+ip link add vrf10 type vrf table 10
+ip link set vrf10 up
+ip link set eth1 master vrf10
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json
new file mode 100644
index 0000000000..6cdeac2991
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv4_rib.json
@@ -0,0 +1,64 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "1.1.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 1,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "192.168.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.1.0",
+ "prefixLen": 24,
+ "network": "192.168.1.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "65001",
+ "origin": "IGP",
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "192.168.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.2.0",
+ "prefixLen": 24,
+ "network": "192.168.2.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2 65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json
new file mode 100644
index 0000000000..77b272de65
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vpnv6_rib.json
@@ -0,0 +1,63 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "1.1.1.1",
+ "defaultLocPrf": 100,
+ "localAS": 1,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "2001:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:1::",
+ "prefixLen": 64,
+ "network": "2001:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "65001",
+ "origin": "IGP",
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "2001:2::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:2::",
+ "prefixLen": 64,
+ "network": "2001:2::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::2",
+ "path": "2 65002",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json
new file mode 100644
index 0000000000..f7da30637b
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v4_rib.json
@@ -0,0 +1,62 @@
+{
+ "192.168.1.0/24": [
+ {
+ "prefix": "192.168.1.0/24",
+ "prefixLen": 24,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth1",
+ "active": true
+ }
+ ],
+ "asPath": "65001"
+ }
+ ],
+ "192.168.2.0/24": [
+ {
+ "prefix": "192.168.2.0/24",
+ "prefixLen": 24,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "vrf": "default",
+ "active": true,
+ "seg6": {
+ "segs": "2001:db8:2:2:1::"
+ }
+ }
+ ],
+ "asPath": "2 65002"
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json
new file mode 100644
index 0000000000..12e7087060
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/vrf10v6_rib.json
@@ -0,0 +1,63 @@
+{
+ "2001:1::/64": [
+ {
+ "prefix": "2001:1::/64",
+ "prefixLen": 64,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth1",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "65001"
+ }
+ ],
+ "2001:2::/64": [
+ {
+ "prefix": "2001:2::/64",
+ "prefixLen": 64,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "vrf": "default",
+ "active": true,
+ "seg6": {
+ "segs": "2001:db8:2:2:1::"
+ }
+ }
+ ],
+ "asPath": "2 65002"
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf
new file mode 100644
index 0000000000..42e3f5bd89
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r1/zebra.conf
@@ -0,0 +1,21 @@
+interface eth0
+ ipv6 address 2001::1/64
+!
+interface eth1 vrf vrf10
+ ipv6 address fd01::1/64
+!
+segment-routing
+ srv6
+ locators
+ locator loc1
+ prefix 2001:db8:1:1::/64
+ !
+ !
+!
+ip forwarding
+ipv6 forwarding
+!
+ipv6 route 2001:db8:2:2::/64 2001::2
+!
+line vty
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/bgpd.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/bgpd.conf
index c2e8530273..31cf9f9b5d 100644
--- a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf/r2/bgpd.conf
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/bgpd.conf
@@ -1,20 +1,12 @@
frr defaults traditional
-!
bgp send-extra-data zebra
-!
-hostname r2
-password zebra
-!
-log stdout notifications
-log commands
-!
!debug bgp neighbor-events
+!debug bgp nht
!debug bgp zebra
!debug bgp vnc verbose
!debug bgp update-groups
!debug bgp updates in
!debug bgp updates out
-!debug bgp updates
!debug bgp vpn label
!debug bgp vpn leak-from-vrf
!debug bgp vpn leak-to-vrf
@@ -22,11 +14,16 @@ log commands
!
router bgp 2
bgp router-id 2.2.2.2
- no bgp ebgp-requires-policy
no bgp default ipv4-unicast
+ no bgp ebgp-requires-policy
neighbor 2001::1 remote-as 1
neighbor 2001::1 timers 3 10
neighbor 2001::1 timers connect 1
+ neighbor 2001::1 capability extended-nexthop
+ !
+ address-family ipv4 vpn
+ neighbor 2001::1 activate
+ exit-address-family
!
address-family ipv6 vpn
neighbor 2001::1 activate
@@ -39,28 +36,28 @@ router bgp 2
router bgp 2 vrf vrf10
bgp router-id 2.2.2.2
no bgp ebgp-requires-policy
- no bgp default ipv4-unicast
+ sid vpn per-vrf export auto
+ neighbor fd02::2 remote-as 65002
+ neighbor fd02::2 capability extended-nexthop
+ neighbor fd02::2 description ce2
+ neighbor fd02::2 interface eth1
+ neighbor fd02::2 update-source fd02::1
!
- address-family ipv6 unicast
- sid vpn export auto
+ address-family ipv4 unicast
+ nexthop vpn export 2001::2
rd vpn export 2:10
rt vpn both 99:99
import vpn
export vpn
- redistribute connected
+ neighbor fd02::2 activate
exit-address-family
-!
-router bgp 2 vrf vrf20
- bgp router-id 2.2.2.2
- no bgp ebgp-requires-policy
- no bgp default ipv4-unicast
!
address-family ipv6 unicast
- sid vpn export auto
- rd vpn export 2:20
- rt vpn both 88:88
+ nexthop vpn export 2001::2
+ rd vpn export 2:10
+ rt vpn both 99:99
import vpn
export vpn
- redistribute connected
+ neighbor fd02::2 activate
exit-address-family
!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh
new file mode 100644
index 0000000000..ac1844f733
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/setup.sh
@@ -0,0 +1,4 @@
+sysctl net.vrf.strict_mode=1
+ip link add vrf10 type vrf table 10
+ip link set vrf10 up
+ip link set eth1 master vrf10
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json
new file mode 100644
index 0000000000..c1f67a771c
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv4_rib.json
@@ -0,0 +1,64 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "2.2.2.2",
+ "defaultLocPrf": 100,
+ "localAS": 2,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "192.168.1.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.1.0",
+ "prefixLen": 24,
+ "network": "192.168.1.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "1 65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "192.168.2.0/24": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "192.168.2.0",
+ "prefixLen": 24,
+ "network": "192.168.2.0/24",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "65002",
+ "origin": "IGP",
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "ip": "2001::2",
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json
new file mode 100644
index 0000000000..da3ddd0699
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vpnv6_rib.json
@@ -0,0 +1,63 @@
+{
+ "vrfId": 0,
+ "vrfName": "default",
+ "routerId": "2.2.2.2",
+ "defaultLocPrf": 100,
+ "localAS": 2,
+ "routes": {
+ "routeDistinguishers": {
+ "1:10": {
+ "2001:1::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:1::",
+ "prefixLen": 64,
+ "network": "2001:1::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "2001::1",
+ "path": "1 65001",
+ "origin": "IGP",
+ "nexthops": [
+ {
+ "ip": "2001::1",
+ "hostname": "r1",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ },
+ "2:10": {
+ "2001:2::/64": [
+ {
+ "valid": true,
+ "bestpath": true,
+ "selectionReason": "First path received",
+ "pathFrom": "external",
+ "prefix": "2001:2::",
+ "prefixLen": 64,
+ "network": "2001:2::/64",
+ "metric": 0,
+ "weight": 0,
+ "peerId": "(unspec)",
+ "path": "65002",
+ "origin": "IGP",
+ "nhVrfName": "vrf10",
+ "nexthops": [
+ {
+ "hostname": "r2",
+ "afi": "ipv6",
+ "used": true
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json
new file mode 100644
index 0000000000..5cc093fea8
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v4_rib.json
@@ -0,0 +1,63 @@
+{
+ "192.168.1.0/24": [
+ {
+ "prefix": "192.168.1.0/24",
+ "prefixLen": 24,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "vrf": "default",
+ "active": true,
+ "seg6": {
+ "segs": "2001:db8:1:1:1::"
+ }
+ }
+ ],
+ "asPath": "1 65001"
+ }
+ ],
+ "192.168.2.0/24": [
+ {
+ "prefix": "192.168.2.0/24",
+ "prefixLen": 24,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth1",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "65002"
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json
new file mode 100644
index 0000000000..5e8114e17b
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/vrf10v6_rib.json
@@ -0,0 +1,63 @@
+{
+ "2001:1::/64": [
+ {
+ "prefix": "2001:1::/64",
+ "prefixLen": 64,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth0",
+ "vrf": "default",
+ "active": true,
+ "seg6": {
+ "segs": "2001:db8:1:1:1::"
+ }
+ }
+ ],
+ "asPath": "1 65001"
+ }
+ ],
+ "2001:2::/64": [
+ {
+ "prefix": "2001:2::/64",
+ "prefixLen": 64,
+ "protocol": "bgp",
+ "vrfName": "vrf10",
+ "selected": true,
+ "destSelected": true,
+ "distance": 20,
+ "metric": 0,
+ "installed": true,
+ "table": 10,
+ "internalStatus": 16,
+ "internalFlags": 8,
+ "internalNextHopNum": 1,
+ "internalNextHopActiveNum": 1,
+ "nexthops": [
+ {
+ "flags": 3,
+ "fib": true,
+ "afi": "ipv6",
+ "interfaceName": "eth1",
+ "active": true,
+ "weight": 1
+ }
+ ],
+ "asPath": "65002"
+ }
+ ]
+}
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf
new file mode 100644
index 0000000000..551e7d7692
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/r2/zebra.conf
@@ -0,0 +1,21 @@
+interface eth0
+ ipv6 address 2001::2/64
+!
+interface eth1 vrf vrf10
+ ipv6 address fd02::1/64
+!
+segment-routing
+ srv6
+ locators
+ locator loc1
+ prefix 2001:db8:2:2::/64
+ !
+ !
+!
+ip forwarding
+ipv6 forwarding
+!
+ipv6 route 2001:db8:1:1::/64 2001::1
+!
+line vty
+!
diff --git a/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py
new file mode 100644
index 0000000000..88bc9847f3
--- /dev/null
+++ b/tests/topotests/bgp_srv6l3vpn_to_bgp_vrf4/test_bgp_srv6l3vpn_to_bgp_vrf4.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: ISC
+
+# Copyright (c) 2025, Onvox LLC
+# Authored by Jonathan Voss <jvoss@onvox.net>
+#
+# Test SRv6 L3VPN with CE BGP peers within a VRF
+#
+
+import os
+import re
+import sys
+import json
+import functools
+import pytest
+
+CWD = os.path.dirname(os.path.realpath(__file__))
+sys.path.append(os.path.join(CWD, "../"))
+
+# pylint: disable=C0413
+# Import topogen and topotest helpers
+from lib import topotest
+from lib.topogen import Topogen, TopoRouter, get_topogen
+from lib.topolog import logger
+from lib.common_config import required_linux_kernel_version
+from lib.checkping import check_ping
+
+pytestmark = [pytest.mark.bgpd]
+
+
+def build_topo(tgen):
+ tgen.add_router("r1")
+ tgen.add_router("r2")
+ tgen.add_router("ce1")
+ tgen.add_router("ce2")
+
+ tgen.add_link(tgen.gears["r1"], tgen.gears["r2"], "eth0", "eth0")
+ tgen.add_link(tgen.gears["ce1"], tgen.gears["r1"], "eth0", "eth1")
+ tgen.add_link(tgen.gears["ce2"], tgen.gears["r2"], "eth0", "eth1")
+
+
+def setup_module(mod):
+ result = required_linux_kernel_version("5.14")
+ if result is not True:
+ pytest.skip("Kernel requirements are not met")
+
+ tgen = Topogen(build_topo, mod.__name__)
+ tgen.start_topology()
+ for rname, router in tgen.routers().items():
+ if os.path.exists("{}/{}/setup.sh".format(CWD, rname)):
+ router.run("/bin/bash {}/{}/setup.sh".format(CWD, rname))
+ 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 open_json_file(filename):
+ try:
+ with open(filename, "r") as f:
+ return json.load(f)
+ except IOError:
+ assert False, "Could not read file {}".format(filename)
+
+
+def check_rib(name, cmd, expected_file, count=30, wait=0.5):
+ def _check(name, dest_addr, match):
+ logger.info("polling")
+ tgen = get_topogen()
+ router = tgen.gears[name]
+ output = json.loads(router.vtysh_cmd(cmd))
+ expected = open_json_file("{}/{}".format(CWD, expected_file))
+ return topotest.json_cmp(output, expected)
+
+ logger.info('[+] check {} "{}" {}'.format(name, cmd, expected_file))
+ tgen = get_topogen()
+ func = functools.partial(_check, name, cmd, expected_file)
+ _, result = topotest.run_and_expect(func, None, count, wait)
+ assert result is None, "Failed"
+
+
+def test_rib():
+ check_rib("r1", "show bgp ipv4 vpn json", "r1/vpnv4_rib.json", 120, 1)
+ check_rib("r2", "show bgp ipv4 vpn json", "r2/vpnv4_rib.json")
+ check_rib("r1", "show ip route vrf vrf10 json", "r1/vrf10v4_rib.json")
+ check_rib("r2", "show ip route vrf vrf10 json", "r2/vrf10v4_rib.json")
+ check_rib("ce1", "show ip route json", "ce1/ip_rib.json")
+ check_rib("ce2", "show ip route json", "ce2/ip_rib.json")
+
+ check_rib("r1", "show bgp ipv6 vpn json", "r1/vpnv6_rib.json")
+ check_rib("r2", "show bgp ipv6 vpn json", "r2/vpnv6_rib.json")
+ check_rib("r1", "show ipv6 route vrf vrf10 json", "r1/vrf10v6_rib.json")
+ check_rib("r2", "show ipv6 route vrf vrf10 json", "r2/vrf10v6_rib.json")
+ check_rib("ce1", "show ipv6 route json", "ce1/ipv6_rib.json")
+ check_rib("ce2", "show ipv6 route json", "ce2/ipv6_rib.json")
+
+
+def test_ping():
+ # IPv4 CE1 to CE2
+ check_ping("ce1", "192.168.2.1", True, 10, 3, "192.168.1.1")
+ # IPv4 CE2 to CE1
+ check_ping("ce2", "192.168.1.1", True, 10, 3, "192.168.2.1")
+ # IPv6 CE1 to CE2
+ check_ping("ce1", "2001:2::1", True, 10, 3, "2001:1::1")
+ # IPv6 CE2 to CE1
+ check_ping("ce2", "2001:1::1", True, 10, 3, "2001:2::1")
+
+
+def test_ce_neighbor_reset():
+ # Clear CE to R peerings and ensure route exports after
+ # re-established propogate to VPNv4/VPNv6 and function correctly
+ tgen = get_topogen()
+
+ for router in ["ce1", "ce2"]:
+ tgen.gears[router].vtysh_cmd("clear bgp *")
+
+ test_ping()
+ test_rib()
+
+
+def test_pe_neighbor_reset():
+ # Clear R to R peering and ensure route exports after
+ # re-established propogate to VPNv4/VPNv6 and function correctly
+ tgen = get_topogen()
+
+ tgen.gears["r1"].vtysh_cmd("clear bgp *")
+
+ test_ping()
+ test_rib()
+
+
+if __name__ == "__main__":
+ args = ["-s"] + sys.argv[1:]
+ sys.exit(pytest.main(args))
diff --git a/tests/topotests/high_ecmp/r1/frr.conf b/tests/topotests/high_ecmp/r1/frr.conf
index 957e17e914..e64fb2e416 100644
--- a/tests/topotests/high_ecmp/r1/frr.conf
+++ b/tests/topotests/high_ecmp/r1/frr.conf
@@ -2577,3 +2577,8 @@ interface r1-eth514
ipv6 address 2001:db8:3:5::1/64
no shut
!
+router bgp 1001
+ timers bgp 5 60
+ no bgp ebgp-requires-policy
+ read-quanta 1
+!
diff --git a/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf b/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf
index df64a146bc..ad7b9df919 100644
--- a/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf
+++ b/tests/topotests/high_ecmp/r1/frr_ipv4_bgp.conf
@@ -1,7 +1,4 @@
router bgp 1001
- timers bgp 5 20
- no bgp ebgp-requires-policy
- read-quanta 1
neighbor 10.1.1.2 remote-as external
neighbor 10.1.2.2 remote-as external
neighbor 10.1.3.2 remote-as external
diff --git a/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf b/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf
index 15137a8715..9f4b961d82 100644
--- a/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf
+++ b/tests/topotests/high_ecmp/r1/frr_ipv6_bgp.conf
@@ -1,7 +1,4 @@
router bgp 1001
- timers bgp 5 20
- no bgp ebgp-requires-policy
- read-quanta 1
neighbor 2001:db8:1:1::2 remote-as external
neighbor 2001:db8:1:2::2 remote-as external
neighbor 2001:db8:1:3::2 remote-as external
diff --git a/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf b/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf
index 7985fe6e99..7f83c6a25c 100644
--- a/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf
+++ b/tests/topotests/high_ecmp/r1/frr_unnumbered_bgp.conf
@@ -1,7 +1,4 @@
router bgp 1001
- timers bgp 5 20
- no bgp ebgp-requires-policy
- read-quanta 1
neighbor r1-eth0 interface remote-as external
neighbor r1-eth1 interface remote-as external
neighbor r1-eth2 interface remote-as external
@@ -520,3 +517,209 @@ router bgp 1001
address-family ipv4 uni
redistribute sharp
+
+address-family ipv6 unicast
+ redistribute sharp
+ neighbor r1-eth0 activate
+ neighbor r1-eth1 activate
+ neighbor r1-eth2 activate
+ neighbor r1-eth3 activate
+ neighbor r1-eth4 activate
+ neighbor r1-eth5 activate
+ neighbor r1-eth6 activate
+ neighbor r1-eth7 activate
+ neighbor r1-eth8 activate
+ neighbor r1-eth9 activate
+ neighbor r1-eth10 activate
+ neighbor r1-eth11 activate
+ neighbor r1-eth12 activate
+ neighbor r1-eth13 activate
+ neighbor r1-eth14 activate
+ neighbor r1-eth15 activate
+ neighbor r1-eth16 activate
+ neighbor r1-eth17 activate
+ neighbor r1-eth18 activate
+ neighbor r1-eth19 activate
+ neighbor r1-eth20 activate
+ neighbor r1-eth21 activate
+ neighbor r1-eth22 activate
+ neighbor r1-eth23 activate
+ neighbor r1-eth24 activate
+ neighbor r1-eth25 activate
+ neighbor r1-eth26 activate
+ neighbor r1-eth27 activate
+ neighbor r1-eth28 activate
+ neighbor r1-eth29 activate
+ neighbor r1-eth30 activate
+ neighbor r1-eth31 activate
+ neighbor r1-eth32 activate
+ neighbor r1-eth33 activate
+ neighbor r1-eth34 activate
+ neighbor r1-eth35 activate
+ neighbor r1-eth36 activate
+ neighbor r1-eth37 activate
+ neighbor r1-eth38 activate
+ neighbor r1-eth39 activate
+ neighbor r1-eth40 activate
+ neighbor r1-eth41 activate
+ neighbor r1-eth42 activate
+ neighbor r1-eth43 activate
+ neighbor r1-eth44 activate
+ neighbor r1-eth45 activate
+ neighbor r1-eth46 activate
+ neighbor r1-eth47 activate
+ neighbor r1-eth48 activate
+ neighbor r1-eth49 activate
+ neighbor r1-eth50 activate
+ neighbor r1-eth51 activate
+ neighbor r1-eth52 activate
+ neighbor r1-eth53 activate
+ neighbor r1-eth54 activate
+ neighbor r1-eth55 activate
+ neighbor r1-eth56 activate
+ neighbor r1-eth57 activate
+ neighbor r1-eth58 activate
+ neighbor r1-eth59 activate
+ neighbor r1-eth60 activate
+ neighbor r1-eth61 activate
+ neighbor r1-eth62 activate
+ neighbor r1-eth63 activate
+ neighbor r1-eth64 activate
+ neighbor r1-eth65 activate
+ neighbor r1-eth66 activate
+ neighbor r1-eth67 activate
+ neighbor r1-eth68 activate
+ neighbor r1-eth69 activate
+ neighbor r1-eth70 activate
+ neighbor r1-eth71 activate
+ neighbor r1-eth72 activate
+ neighbor r1-eth73 activate
+ neighbor r1-eth74 activate
+ neighbor r1-eth75 activate
+ neighbor r1-eth76 activate
+ neighbor r1-eth77 activate
+ neighbor r1-eth78 activate
+ neighbor r1-eth79 activate
+ neighbor r1-eth80 activate
+ neighbor r1-eth81 activate
+ neighbor r1-eth82 activate
+ neighbor r1-eth83 activate
+ neighbor r1-eth84 activate
+ neighbor r1-eth85 activate
+ neighbor r1-eth86 activate
+ neighbor r1-eth87 activate
+ neighbor r1-eth88 activate
+ neighbor r1-eth89 activate
+ neighbor r1-eth90 activate
+ neighbor r1-eth91 activate
+ neighbor r1-eth92 activate
+ neighbor r1-eth93 activate
+ neighbor r1-eth94 activate
+ neighbor r1-eth95 activate
+ neighbor r1-eth96 activate
+ neighbor r1-eth97 activate
+ neighbor r1-eth98 activate
+ neighbor r1-eth99 activate
+ neighbor r1-eth100 activate
+ neighbor r1-eth101 activate
+ neighbor r1-eth102 activate
+ neighbor r1-eth103 activate
+ neighbor r1-eth104 activate
+ neighbor r1-eth105 activate
+ neighbor r1-eth106 activate
+ neighbor r1-eth107 activate
+ neighbor r1-eth108 activate
+ neighbor r1-eth109 activate
+ neighbor r1-eth110 activate
+ neighbor r1-eth111 activate
+ neighbor r1-eth112 activate
+ neighbor r1-eth113 activate
+ neighbor r1-eth114 activate
+ neighbor r1-eth115 activate
+ neighbor r1-eth116 activate
+ neighbor r1-eth117 activate
+ neighbor r1-eth118 activate
+ neighbor r1-eth119 activate
+ neighbor r1-eth120 activate
+ neighbor r1-eth121 activate
+ neighbor r1-eth122 activate
+ neighbor r1-eth123 activate
+ neighbor r1-eth124 activate
+ neighbor r1-eth125 activate
+ neighbor r1-eth126 activate
+ neighbor r1-eth127 activate
+ neighbor r1-eth128 activate
+ neighbor r1-eth129 activate
+ neighbor r1-eth130 activate
+ neighbor r1-eth131 activate
+ neighbor r1-eth132 activate
+ neighbor r1-eth133 activate
+ neighbor r1-eth134 activate
+ neighbor r1-eth135 activate
+ neighbor r1-eth136 activate
+ neighbor r1-eth137 activate
+ neighbor r1-eth138 activate
+ neighbor r1-eth139 activate
+ neighbor r1-eth140 activate
+ neighbor r1-eth141 activate
+ neighbor r1-eth142 activate
+ neighbor r1-eth143 activate
+ neighbor r1-eth144 activate
+ neighbor r1-eth145 activate
+ neighbor r1-eth146 activate
+ neighbor r1-eth147 activate
+ neighbor r1-eth148 activate
+ neighbor r1-eth149 activate
+ neighbor r1-eth150 activate
+ neighbor r1-eth151 activate
+ neighbor r1-eth152 activate
+ neighbor r1-eth153 activate
+ neighbor r1-eth154 activate
+ neighbor r1-eth155 activate
+ neighbor r1-eth156 activate
+ neighbor r1-eth157 activate
+ neighbor r1-eth158 activate
+ neighbor r1-eth159 activate
+ neighbor r1-eth160 activate
+ neighbor r1-eth161 activate
+ neighbor r1-eth162 activate
+ neighbor r1-eth163 activate
+ neighbor r1-eth164 activate
+ neighbor r1-eth165 activate
+ neighbor r1-eth166 activate
+ neighbor r1-eth167 activate
+ neighbor r1-eth168 activate
+ neighbor r1-eth169 activate
+ neighbor r1-eth170 activate
+ neighbor r1-eth171 activate
+ neighbor r1-eth172 activate
+ neighbor r1-eth173 activate
+ neighbor r1-eth174 activate
+ neighbor r1-eth175 activate
+ neighbor r1-eth176 activate
+ neighbor r1-eth177 activate
+ neighbor r1-eth178 activate
+ neighbor r1-eth179 activate
+ neighbor r1-eth180 activate
+ neighbor r1-eth181 activate
+ neighbor r1-eth182 activate
+ neighbor r1-eth183 activate
+ neighbor r1-eth184 activate
+ neighbor r1-eth185 activate
+ neighbor r1-eth186 activate
+ neighbor r1-eth187 activate
+ neighbor r1-eth188 activate
+ neighbor r1-eth189 activate
+ neighbor r1-eth190 activate
+ neighbor r1-eth191 activate
+ neighbor r1-eth192 activate
+ neighbor r1-eth193 activate
+ neighbor r1-eth194 activate
+ neighbor r1-eth195 activate
+ neighbor r1-eth196 activate
+ neighbor r1-eth197 activate
+ neighbor r1-eth198 activate
+ neighbor r1-eth199 activate
+ neighbor r1-eth200 activate
+ exit-address-family
+exit \ No newline at end of file
diff --git a/tests/topotests/high_ecmp/r2/frr.conf b/tests/topotests/high_ecmp/r2/frr.conf
index 151f6da45c..1e98e31236 100644
--- a/tests/topotests/high_ecmp/r2/frr.conf
+++ b/tests/topotests/high_ecmp/r2/frr.conf
@@ -2577,3 +2577,8 @@ interface r2-eth514
ipv6 address 2001:db8:3:5::2/64
no shutdown
!
+router bgp 1002
+ timers bgp 5 60
+ no bgp ebgp-requires-policy
+ read-quanta 1
+!
diff --git a/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf b/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf
index 48842bbfc2..afc3a30c7d 100644
--- a/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf
+++ b/tests/topotests/high_ecmp/r2/frr_ipv4_bgp.conf
@@ -1,7 +1,4 @@
router bgp 1002
- timers bgp 5 20
- no bgp ebgp-requires-policy
- read-quanta 1
neighbor 10.1.1.1 remote-as external
neighbor 10.1.2.1 remote-as external
neighbor 10.1.3.1 remote-as external
diff --git a/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf b/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf
index e3258cabd4..b0728d3069 100644
--- a/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf
+++ b/tests/topotests/high_ecmp/r2/frr_ipv6_bgp.conf
@@ -1,7 +1,4 @@
router bgp 1002
- timers bgp 5 20
- no bgp ebgp-requires-policy
- read-quanta 1
neighbor 2001:db8:1:1::1 remote-as external
neighbor 2001:db8:1:2::1 remote-as external
neighbor 2001:db8:1:3::1 remote-as external
diff --git a/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf b/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf
index 23827789fb..9428af3440 100644
--- a/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf
+++ b/tests/topotests/high_ecmp/r2/frr_unnumbered_bgp.conf
@@ -1,7 +1,4 @@
router bgp 1002
- timers bgp 5 20
- no bgp ebgp-requires-policy
- read-quanta 1
neighbor r2-eth0 interface remote-as external
neighbor r2-eth1 interface remote-as external
neighbor r2-eth2 interface remote-as external
@@ -518,3 +515,208 @@ router bgp 1002
neighbor r2-eth513 interface remote-as external
neighbor r2-eth514 interface remote-as external
+ address-family ipv6 unicast
+ redistribute sharp
+ neighbor r2-eth0 activate
+ neighbor r2-eth1 activate
+ neighbor r2-eth2 activate
+ neighbor r2-eth3 activate
+ neighbor r2-eth4 activate
+ neighbor r2-eth5 activate
+ neighbor r2-eth6 activate
+ neighbor r2-eth7 activate
+ neighbor r2-eth8 activate
+ neighbor r2-eth9 activate
+ neighbor r2-eth10 activate
+ neighbor r2-eth11 activate
+ neighbor r2-eth12 activate
+ neighbor r2-eth13 activate
+ neighbor r2-eth14 activate
+ neighbor r2-eth15 activate
+ neighbor r2-eth16 activate
+ neighbor r2-eth17 activate
+ neighbor r2-eth18 activate
+ neighbor r2-eth19 activate
+ neighbor r2-eth20 activate
+ neighbor r2-eth21 activate
+ neighbor r2-eth22 activate
+ neighbor r2-eth23 activate
+ neighbor r2-eth24 activate
+ neighbor r2-eth25 activate
+ neighbor r2-eth26 activate
+ neighbor r2-eth27 activate
+ neighbor r2-eth28 activate
+ neighbor r2-eth29 activate
+ neighbor r2-eth30 activate
+ neighbor r2-eth31 activate
+ neighbor r2-eth32 activate
+ neighbor r2-eth33 activate
+ neighbor r2-eth34 activate
+ neighbor r2-eth35 activate
+ neighbor r2-eth36 activate
+ neighbor r2-eth37 activate
+ neighbor r2-eth38 activate
+ neighbor r2-eth39 activate
+ neighbor r2-eth40 activate
+ neighbor r2-eth41 activate
+ neighbor r2-eth42 activate
+ neighbor r2-eth43 activate
+ neighbor r2-eth44 activate
+ neighbor r2-eth45 activate
+ neighbor r2-eth46 activate
+ neighbor r2-eth47 activate
+ neighbor r2-eth48 activate
+ neighbor r2-eth49 activate
+ neighbor r2-eth50 activate
+ neighbor r2-eth51 activate
+ neighbor r2-eth52 activate
+ neighbor r2-eth53 activate
+ neighbor r2-eth54 activate
+ neighbor r2-eth55 activate
+ neighbor r2-eth56 activate
+ neighbor r2-eth57 activate
+ neighbor r2-eth58 activate
+ neighbor r2-eth59 activate
+ neighbor r2-eth60 activate
+ neighbor r2-eth61 activate
+ neighbor r2-eth62 activate
+ neighbor r2-eth63 activate
+ neighbor r2-eth64 activate
+ neighbor r2-eth65 activate
+ neighbor r2-eth66 activate
+ neighbor r2-eth67 activate
+ neighbor r2-eth68 activate
+ neighbor r2-eth69 activate
+ neighbor r2-eth70 activate
+ neighbor r2-eth71 activate
+ neighbor r2-eth72 activate
+ neighbor r2-eth73 activate
+ neighbor r2-eth74 activate
+ neighbor r2-eth75 activate
+ neighbor r2-eth76 activate
+ neighbor r2-eth77 activate
+ neighbor r2-eth78 activate
+ neighbor r2-eth79 activate
+ neighbor r2-eth80 activate
+ neighbor r2-eth81 activate
+ neighbor r2-eth82 activate
+ neighbor r2-eth83 activate
+ neighbor r2-eth84 activate
+ neighbor r2-eth85 activate
+ neighbor r2-eth86 activate
+ neighbor r2-eth87 activate
+ neighbor r2-eth88 activate
+ neighbor r2-eth89 activate
+ neighbor r2-eth90 activate
+ neighbor r2-eth91 activate
+ neighbor r2-eth92 activate
+ neighbor r2-eth93 activate
+ neighbor r2-eth94 activate
+ neighbor r2-eth95 activate
+ neighbor r2-eth96 activate
+ neighbor r2-eth97 activate
+ neighbor r2-eth98 activate
+ neighbor r2-eth99 activate
+ neighbor r2-eth100 activate
+ neighbor r2-eth101 activate
+ neighbor r2-eth102 activate
+ neighbor r2-eth103 activate
+ neighbor r2-eth104 activate
+ neighbor r2-eth105 activate
+ neighbor r2-eth106 activate
+ neighbor r2-eth107 activate
+ neighbor r2-eth108 activate
+ neighbor r2-eth109 activate
+ neighbor r2-eth110 activate
+ neighbor r2-eth111 activate
+ neighbor r2-eth112 activate
+ neighbor r2-eth113 activate
+ neighbor r2-eth114 activate
+ neighbor r2-eth115 activate
+ neighbor r2-eth116 activate
+ neighbor r2-eth117 activate
+ neighbor r2-eth118 activate
+ neighbor r2-eth119 activate
+ neighbor r2-eth120 activate
+ neighbor r2-eth121 activate
+ neighbor r2-eth122 activate
+ neighbor r2-eth123 activate
+ neighbor r2-eth124 activate
+ neighbor r2-eth125 activate
+ neighbor r2-eth126 activate
+ neighbor r2-eth127 activate
+ neighbor r2-eth128 activate
+ neighbor r2-eth129 activate
+ neighbor r2-eth130 activate
+ neighbor r2-eth131 activate
+ neighbor r2-eth132 activate
+ neighbor r2-eth133 activate
+ neighbor r2-eth134 activate
+ neighbor r2-eth135 activate
+ neighbor r2-eth136 activate
+ neighbor r2-eth137 activate
+ neighbor r2-eth138 activate
+ neighbor r2-eth139 activate
+ neighbor r2-eth140 activate
+ neighbor r2-eth141 activate
+ neighbor r2-eth142 activate
+ neighbor r2-eth143 activate
+ neighbor r2-eth144 activate
+ neighbor r2-eth145 activate
+ neighbor r2-eth146 activate
+ neighbor r2-eth147 activate
+ neighbor r2-eth148 activate
+ neighbor r2-eth149 activate
+ neighbor r2-eth150 activate
+ neighbor r2-eth151 activate
+ neighbor r2-eth152 activate
+ neighbor r2-eth153 activate
+ neighbor r2-eth154 activate
+ neighbor r2-eth155 activate
+ neighbor r2-eth156 activate
+ neighbor r2-eth157 activate
+ neighbor r2-eth158 activate
+ neighbor r2-eth159 activate
+ neighbor r2-eth160 activate
+ neighbor r2-eth161 activate
+ neighbor r2-eth162 activate
+ neighbor r2-eth163 activate
+ neighbor r2-eth164 activate
+ neighbor r2-eth165 activate
+ neighbor r2-eth166 activate
+ neighbor r2-eth167 activate
+ neighbor r2-eth168 activate
+ neighbor r2-eth169 activate
+ neighbor r2-eth170 activate
+ neighbor r2-eth171 activate
+ neighbor r2-eth172 activate
+ neighbor r2-eth173 activate
+ neighbor r2-eth174 activate
+ neighbor r2-eth175 activate
+ neighbor r2-eth176 activate
+ neighbor r2-eth177 activate
+ neighbor r2-eth178 activate
+ neighbor r2-eth179 activate
+ neighbor r2-eth180 activate
+ neighbor r2-eth181 activate
+ neighbor r2-eth182 activate
+ neighbor r2-eth183 activate
+ neighbor r2-eth184 activate
+ neighbor r2-eth185 activate
+ neighbor r2-eth186 activate
+ neighbor r2-eth187 activate
+ neighbor r2-eth188 activate
+ neighbor r2-eth189 activate
+ neighbor r2-eth190 activate
+ neighbor r2-eth191 activate
+ neighbor r2-eth192 activate
+ neighbor r2-eth193 activate
+ neighbor r2-eth194 activate
+ neighbor r2-eth195 activate
+ neighbor r2-eth196 activate
+ neighbor r2-eth197 activate
+ neighbor r2-eth198 activate
+ neighbor r2-eth199 activate
+ neighbor r2-eth200 activate
+exit-address-family
+exit
diff --git a/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py b/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py
index 0947272386..ed6257f72e 100644
--- a/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py
+++ b/tests/topotests/high_ecmp/test_high_ecmp_unnumbered.py
@@ -21,6 +21,12 @@ import re
import sys
import pytest
import json
+from time import sleep
+
+from lib.common_config import (
+ kill_router_daemons,
+ start_router_daemons,
+)
pytestmark = [pytest.mark.bgpd]
@@ -99,6 +105,171 @@ def teardown_module(_mod):
tgen.stop_topology()
+def test_bgp_route_cleanup():
+ failures = 0
+ net = get_topogen().net
+ expected_route_count = 2000
+
+ # First, extract IPv4 and IPv6 loopback addresses from r1
+ lo_output = net["r1"].cmd("vtysh -c 'show interface lo'")
+
+ # Extract IPv4 and IPv6 addresses from the output
+ ipv4_match = re.search(r"inet (\d+\.\d+\.\d+\.\d+)/\d+", lo_output)
+ ipv6_match = re.search(r"inet6 ([0-9a-f:]+)/\d+", lo_output)
+
+ if not ipv4_match or not ipv6_match:
+ assert False, "Could not find IPv4 or IPv6 address on loopback interface"
+
+ ipv4_nexthop = ipv4_match.group(1)
+ ipv6_nexthop = ipv6_match.group(1)
+
+ print(f"\nUsing nexthops: IPv4={ipv4_nexthop}, IPv6={ipv6_nexthop}")
+
+ # Install IPv4 routes
+ ipv4_cmd = f"vtysh -c 'sharp install routes 39.99.0.0 nexthop {ipv4_nexthop} {expected_route_count}'"
+ net["r1"].cmd(ipv4_cmd)
+
+ # Install IPv6 routes
+ ipv6_cmd = f"vtysh -c 'sharp install routes 2100:cafe:: nexthop {ipv6_nexthop} {expected_route_count}'"
+ net["r1"].cmd(ipv6_cmd)
+
+ # Initialize actual counts
+ ipv4_actual_count = 0
+ ipv6_actual_count = 0
+ max_attempts = 12 # 60 seconds max (12 * 5)
+ attempt = 0
+
+ # Wait until both IPv4 and IPv6 routes are installed
+ while (
+ ipv4_actual_count != expected_route_count
+ or ipv6_actual_count != expected_route_count
+ ) and attempt < max_attempts:
+ sleep(5)
+ attempt += 1
+
+ # Get current IPv4 route count
+ ipv4_count_str = (
+ net["r2"]
+ .cmd('vtysh -c "show bgp ipv4 unicast" | grep "39.99" | wc -l')
+ .rstrip()
+ )
+
+ # Get current IPv6 route count
+ ipv6_count_str = (
+ net["r2"]
+ .cmd('vtysh -c "show bgp ipv6 unicast" | grep "cafe" | wc -l')
+ .rstrip()
+ )
+
+ try:
+ ipv4_actual_count = int(ipv4_count_str)
+ except ValueError:
+ ipv4_actual_count = 0
+
+ try:
+ ipv6_actual_count = int(ipv6_count_str)
+ except ValueError:
+ ipv6_actual_count = 0
+
+ print(f"Attempt {attempt}")
+ print(f"IPv4 Routes found: {ipv4_actual_count} / {expected_route_count}")
+ print(f"IPv6 Routes found: {ipv6_actual_count} / {expected_route_count}")
+
+ # Verify we have the expected number of routes
+ if ipv4_actual_count != expected_route_count:
+ sys.stderr.write(
+ f"Failed to install expected IPv4 routes: got {ipv4_actual_count}, expected {expected_route_count}\n"
+ )
+ failures += 1
+ else:
+ print("IPv4 routes successfully installed")
+
+ if ipv6_actual_count != expected_route_count:
+ sys.stderr.write(
+ f"Failed to install expected IPv6 routes: got {ipv6_actual_count}, expected {expected_route_count}\n"
+ )
+ failures += 1
+ else:
+ print("IPv6 routes successfully installed")
+
+ # Stop bgpd in r1 to trigger deletion of routes in r2
+ kill_router_daemons(get_topogen(), "r1", ["bgpd"])
+
+ # Initialize variables for post-removal check
+ # Start with the original count
+ ipv4_final_count = expected_route_count
+ ipv6_final_count = expected_route_count
+ expected_final_count = 0
+ attempt = 0
+ max_removal_attempts = 12
+
+ # Wait until both IPv4 and IPv6 routes are fully removed
+ while (
+ ipv4_final_count != expected_final_count
+ or ipv6_final_count != expected_final_count
+ ) and attempt < max_removal_attempts:
+ sleep(5)
+ attempt += 1
+
+ # Get current IPv4 route count
+ ipv4_count_str = (
+ net["r2"]
+ .cmd('vtysh -c "show bgp ipv4 unicast" | grep "39.99" | wc -l')
+ .rstrip()
+ )
+
+ # Get current IPv6 route count
+ ipv6_count_str = (
+ net["r2"]
+ .cmd('vtysh -c "show bgp ipv6 unicast" | grep "cafe" | wc -l')
+ .rstrip()
+ )
+
+ try:
+ ipv4_final_count = int(ipv4_count_str)
+ except ValueError:
+ ipv4_final_count = 0
+
+ try:
+ ipv6_final_count = int(ipv6_count_str)
+ except ValueError:
+ ipv6_final_count = 0
+
+ print(f"Route Removal Attempt {attempt}")
+ print(f"IPv4 Routes remaining: {ipv4_final_count} / {expected_final_count}")
+ print(f"IPv6 Routes remaining: {ipv6_final_count} / {expected_final_count}")
+
+ # If both are already at expected count, break early
+ if (
+ ipv4_final_count == expected_final_count
+ and ipv6_final_count == expected_final_count
+ ):
+ print("All routes successfully removed")
+ break
+
+ # Final verification
+ if ipv4_final_count != expected_final_count:
+ sys.stderr.write(
+ f"Failed to remove IPv4 routes after {max_removal_attempts} attempts: "
+ f"{ipv4_final_count} routes still present\n"
+ )
+ failures += 1
+ else:
+ print("IPv4 routes successfully removed")
+
+ if ipv6_final_count != expected_final_count:
+ sys.stderr.write(
+ f"Failed to remove IPv6 routes after {max_removal_attempts} attempts: "
+ f"{ipv6_final_count} routes still present\n"
+ )
+ failures += 1
+ else:
+ print("IPv6 routes successfully removed")
+
+ start_router_daemons(get_topogen(), "r1", ["bgpd"])
+ assert failures == 0, f"Test failed with {failures} failures"
+
+
def test_nothing():
"Do Nothing"
tgen = get_topogen()
diff --git a/tests/topotests/lib/bgp.py b/tests/topotests/lib/bgp.py
index 632aa4a10b..01fe2b3714 100644
--- a/tests/topotests/lib/bgp.py
+++ b/tests/topotests/lib/bgp.py
@@ -5,6 +5,7 @@
# ("NetDEF") in this file.
#
+import json
import ipaddress
import sys
import traceback
@@ -5658,3 +5659,34 @@ def bgp_configure_prefixes(router, asn, safi, prefixes, vrf=None, update=True):
]
logger.debug(f"setting prefix: ipv{ip.version} {safi} {ip}")
router.vtysh_cmd("".join(cmd))
+
+
+# compare exact fields of 'show bgp ipv4 vpn' and related commands
+# after having removed some attributes that are not relevant.
+def bgp_vpn_router_json_cmp_exact_filter(router, cmd, expected):
+ output = router.vtysh_cmd(cmd)
+ logger.info("{}: {}\n{}".format(router.name, cmd, output))
+
+ json_output = json.loads(output)
+
+ # filter out tableVersion, version and nhVrfID
+ json_output.pop("tableVersion")
+ if "totalRoutes" in json_output:
+ json_output.pop("totalRoutes")
+ if "totalPaths" in json_output:
+ json_output.pop("totalPaths")
+ for rd, data in json_output["routes"]["routeDistinguishers"].items():
+ for _, attrs in data.items():
+ for attr in attrs:
+ if "nhVrfId" in attr:
+ attr.pop("nhVrfId")
+ if "version" in attr:
+ attr.pop("version")
+
+ # filter out RD with no data (e.g. "444:3": {})
+ json_tmp = deepcopy(json_output)
+ for rd, data in json_tmp["routes"]["routeDistinguishers"].items():
+ if len(data.keys()) == 0:
+ json_output["routes"]["routeDistinguishers"].pop(rd)
+
+ return topotest.json_cmp(json_output, expected, exact=True)
diff --git a/tests/topotests/lib/common_config.py b/tests/topotests/lib/common_config.py
index f34c48b890..54142e8526 100644
--- a/tests/topotests/lib/common_config.py
+++ b/tests/topotests/lib/common_config.py
@@ -196,7 +196,7 @@ def get_seq_id(obj_type, router, obj_name):
return seq_id
-def set_seq_id(obj_type, router, id, obj_name):
+def set_seq_id(obj_type, router, sequence_id, obj_name):
"""
Saves sequence number if not auto-generated and given by user
Parameters
@@ -209,7 +209,7 @@ def set_seq_id(obj_type, router, id, obj_name):
obj_data = router_data.setdefault(obj_name, {})
seq_id = obj_data.setdefault("seq_id", 0)
- seq_id = int(seq_id) + int(id)
+ seq_id = int(seq_id) + int(sequence_id)
obj_data["seq_id"] = seq_id
@@ -2539,10 +2539,10 @@ def create_route_maps(tgen, input_dict, build=False):
)
return False
if large_comm_list:
- id = large_comm_list.setdefault("id", None)
+ comm_id = large_comm_list.setdefault("id", None)
del_comm = large_comm_list.setdefault("delete", None)
- if id:
- cmd = "set large-comm-list {}".format(id)
+ if comm_id:
+ cmd = "set large-comm-list {}".format(comm_id)
if del_comm:
cmd = "{} delete".format(cmd)
@@ -4608,7 +4608,7 @@ class HostApplicationHelper(object):
self.init()
return self
- def __exit__(self, type, value, traceback):
+ def __exit__(self, exit_type, exit_value, exit_traceback):
self.cleanup()
def __str__(self):
diff --git a/tests/topotests/lib/mcast-tester.py b/tests/topotests/lib/mcast-tester.py
index 3645eef25e..ecb99dc82b 100755
--- a/tests/topotests/lib/mcast-tester.py
+++ b/tests/topotests/lib/mcast-tester.py
@@ -25,28 +25,46 @@ import time
#
def interface_name_to_index(name):
"Gets the interface index using its name. Returns None on failure."
- interfaces = json.loads(subprocess.check_output("ip -j link show", shell=True))
+ try:
+ interfaces = json.loads(subprocess.check_output("ip -j link show", shell=True))
+ except subprocess.CalledProcessError as err:
+ print(f"Error executing command: {err}")
+ return None
+ except json.JSONDecodeError as err:
+ print(f"Error decoding JSON: {err}")
+ return None
for interface in interfaces:
- if interface["ifname"] == name:
- return interface["ifindex"]
+ if interface.get("ifname") == name:
+ return interface.get("ifindex")
return None
def interface_index_to_address(index, iptype="inet"):
"Gets the interface main address using its name. Returns None on failure."
- interfaces = json.loads(subprocess.check_output("ip -j addr show", shell=True))
+ try:
+ interfaces = json.loads(subprocess.check_output("ip -j addr show", shell=True))
+ except subprocess.CalledProcessError as err:
+ print(f"Error executing command: {err}")
+ return None
+ except json.JSONDecodeError as err:
+ print(f"Error decoding JSON: {err}")
+ return None
for interface in interfaces:
- if interface["ifindex"] == index:
+ if interface.get("ifindex") == index:
break
+ else:
+ return None
- for address in interface["addr_info"]:
- if address["family"] == iptype:
+ for address in interface.get("addr_info"):
+ if address.get("family") == iptype:
break
+ else:
+ return None
- local_address = ipaddress.ip_address(address["local"])
+ local_address = ipaddress.ip_address(address.get("local"))
return local_address.packed
diff --git a/tests/topotests/static_simple/test_static_simple.py b/tests/topotests/static_simple/test_static_simple.py
index afde58fbf7..615d1621f3 100644
--- a/tests/topotests/static_simple/test_static_simple.py
+++ b/tests/topotests/static_simple/test_static_simple.py
@@ -111,6 +111,7 @@ def do_config_inner(
count,
add=True,
do_ipv6=False,
+ do_ipv6_nexthop=False,
do_sadr=False,
via=None,
vrf=None,
@@ -129,6 +130,8 @@ def do_config_inner(
src_prefs = ["2001:db8:1111::/48", "2001:db8:2222::/48"]
elif do_ipv6:
super_prefs = ["2001::/48", "2002::/48"]
+ elif do_ipv6_nexthop:
+ super_prefs = ["11.0.0.0/8", "21.0.0.0/8"]
else:
super_prefs = ["10.0.0.0/8", "20.0.0.0/8"]
@@ -142,11 +145,19 @@ def do_config_inner(
matchvia = f"dev {via}"
else:
if vrf:
- via = "2102::2" if do_ipv6 else "102.0.0.2"
- matchvia = f"via {via} dev r1-eth1"
+ via = "2102::2" if do_ipv6 or do_ipv6_nexthop else "102.0.0.2"
+ matchvia = (
+ f"via inet6 {via} dev r1-eth1"
+ if not do_ipv6 and do_ipv6_nexthop
+ else f"via {via} dev r1-eth1"
+ )
else:
- via = "2101::2" if do_ipv6 else "101.0.0.2"
- matchvia = f"via {via} dev r1-eth0"
+ via = "2101::2" if do_ipv6 or do_ipv6_nexthop else "101.0.0.2"
+ matchvia = (
+ f"via inet6 {via} dev r1-eth0"
+ if not do_ipv6 and do_ipv6_nexthop
+ else f"via {via} dev r1-eth0"
+ )
vrfdbg = " in vrf {}".format(vrf) if vrf else ""
logger.debug("{} {} static {} routes{}".format(optype, count, iptype, vrfdbg))
@@ -201,6 +212,7 @@ def do_config_inner(
def do_config(*args, **kwargs):
do_config_inner(*args, do_ipv6=False, do_sadr=False, **kwargs)
+ do_config_inner(*args, do_ipv6=False, do_ipv6_nexthop=True, **kwargs)
do_config_inner(*args, do_ipv6=True, do_sadr=False, **kwargs)
do_config_inner(*args, do_ipv6=True, do_sadr=True, **kwargs)
diff --git a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py
index 1ea94c8c07..abf49df046 100755
--- a/tests/topotests/static_srv6_sids/test_static_srv6_sids.py
+++ b/tests/topotests/static_srv6_sids/test_static_srv6_sids.py
@@ -210,6 +210,36 @@ def test_srv6_static_sids_sid_modify():
check_srv6_static_sids(router, "expected_srv6_sids_sid_modify.json")
+def test_srv6_static_sids_wrong_sid_block():
+ """
+ The purpose of this test is to verify how FRR behaves when the user
+ provides an invalid configuration.
+ Add a new static Sid with a mismatch in locator and sid block
+ to make sure no Sid is allocated by zebra (TBD: Strict verify once show cmd
+ commit is merged (#16836))
+ """
+ router = get_topogen().gears["r1"]
+ router.vtysh_cmd(
+ """
+ configure terminal
+ segment-routing
+ srv6
+ locators
+ locator MAIN1
+ prefix fcbb:1234:1::/48 block-len 32 node-len 16 func-bits 16
+ srv6
+ static-sids
+ sid fcbb:bbbb:1:fe50::/64 locator MAIN1 behavior uA interface sr0 nexthop 2001::3
+ """
+ )
+
+ output = json.loads(router.vtysh_cmd("show ipv6 route static json"))
+ if "fcbb:bbbb:1:fe50::/64" in output:
+ assert (
+ False
+ ), "Failed. Expected no entry for fcbb:bbbb:1:fe50::/64 since loc and node block dont match"
+
+
def test_srv6_static_sids_sid_delete_all():
"""
Remove all static SIDs and verify they get removed
diff --git a/tools/frr-reload.py b/tools/frr-reload.py
index 048cb8323e..95a00c2b6a 100755
--- a/tools/frr-reload.py
+++ b/tools/frr-reload.py
@@ -1698,6 +1698,7 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
those commands from lines_to_del.
"""
lines_to_del_to_del = []
+ lines_to_del_to_add = []
for ctx_keys, line in lines_to_del:
# The integrated-vtysh-config one is technically "no"able but if we did
@@ -1719,10 +1720,31 @@ def ignore_unconfigurable_lines(lines_to_add, lines_to_del):
):
log.info(f'"{ctx_keys[-1]}" cannot be removed')
lines_to_del_to_del.append((ctx_keys, line))
+ # Handle segment-routing srv6 locators and formats commands
+ # - Ignore "no formats" and "no locators" command
+ # - replace "no prefix" under locator XYZ as "no locator XYZ"
+ elif (
+ len(ctx_keys) > 2
+ and ctx_keys[0].startswith("segment-routing")
+ and ctx_keys[1].startswith("srv6")
+ and ctx_keys[2] in {"locators", "formats"}
+ ):
+ is_top_level = len(ctx_keys) == 3 and not line
+ if ctx_keys[2] == "formats" and is_top_level:
+ lines_to_del_to_del.append((ctx_keys, line))
+ elif ctx_keys[2] == "locators":
+ if is_top_level:
+ lines_to_del_to_del.append((ctx_keys, line))
+ elif len(ctx_keys) == 4 and line and line.startswith("prefix "):
+ lines_to_del_to_del.append((ctx_keys, line))
+ lines_to_del_to_add.append((ctx_keys[:-1] + (ctx_keys[-1],), None))
for ctx_keys, line in lines_to_del_to_del:
lines_to_del.remove((ctx_keys, line))
+ for ctx_keys, line in lines_to_del_to_add:
+ lines_to_del.append((ctx_keys, line))
+
return (lines_to_add, lines_to_del)
@@ -2113,12 +2135,17 @@ if __name__ == "__main__":
help="Use logfmt as log format",
default=False,
)
+ parser.add_argument(
+ "--logfile",
+ help="logfile for frr-reload",
+ default="/var/log/frr/frr-reload.log",
+ )
args = parser.parse_args()
# Logging
# For --test log to stdout
- # For --reload log to /var/log/frr/frr-reload.log
+ # For --reload log to --logfile (default: "/var/log/frr/frr-reload.log")
# If --logfmt, use the logfmt format
formatter = logging.Formatter("%(asctime)s %(levelname)5s: %(message)s")
handler = logging.StreamHandler()
@@ -2133,9 +2160,9 @@ if __name__ == "__main__":
logging.WARNING, "\033[91m%s\033[0m" % logging.getLevelName(logging.WARNING)
)
if args.reload:
- if not os.path.isdir("/var/log/frr/"):
- os.makedirs("/var/log/frr/", mode=0o0755)
- handler = logging.FileHandler("/var/log/frr/frr-reload.log")
+ if not os.path.isdir(os.path.dirname(args.logfile)):
+ os.makedirs(os.path.dirname(args.logfile), mode=0o0755)
+ handler = logging.FileHandler(args.logfile)
if args.stdout:
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(formatter)
diff --git a/tools/generate_support_bundle.py b/tools/generate_support_bundle.py
index 04a374d850..a646e7eea1 100755
--- a/tools/generate_support_bundle.py
+++ b/tools/generate_support_bundle.py
@@ -32,6 +32,9 @@ def main():
parser.add_argument(
"-l", "--log-dir", default="/var/log/frr", help="directory for logfiles"
)
+ parser.add_argument(
+ "-N", "--pathspace", help="Insert prefix into config & socket paths"
+ )
args = parser.parse_args()
collecting = False # file format has sentinels (seem superfluous)
@@ -69,13 +72,22 @@ def main():
# Spawn a vtysh to fetch each set of commands
procs = []
for proc in proc_cmds:
- ofn = os.path.join(args.log_dir, proc + "_support_bundle.log")
- p = subprocess.Popen(
- ["/usr/bin/env", "vtysh", "-t"],
- stdin=proc_cmds[proc],
- stdout=open_with_backup(ofn),
- stderr=subprocess.STDOUT,
- )
+ if args.pathspace:
+ ofn = os.path.join(args.log_dir, args.pathspace + "_" + proc + "_support_bundle.log")
+ p = subprocess.Popen(
+ ["/usr/bin/env", "vtysh", "-t", "-N", args.pathspace],
+ stdin=proc_cmds[proc],
+ stdout=open_with_backup(ofn),
+ stderr=subprocess.STDOUT,
+ )
+ else:
+ ofn = os.path.join(args.log_dir, proc + "_support_bundle.log")
+ p = subprocess.Popen(
+ ["/usr/bin/env", "vtysh", "-t"],
+ stdin=proc_cmds[proc],
+ stdout=open_with_backup(ofn),
+ stderr=subprocess.STDOUT,
+ )
procs.append(p)
for p in procs:
diff --git a/tools/start-stop-daemon.c b/tools/start-stop-daemon.c
index 4406a68f61..5d6cf01936 100644
--- a/tools/start-stop-daemon.c
+++ b/tools/start-stop-daemon.c
@@ -73,14 +73,14 @@ size_t strlcpy(char *__restrict dest,
#endif
static int testmode = 0;
-static int quietmode = 0;
+static int g_quietmode = 0;
static int exitnodo = 1;
static int start = 0;
static int stop = 0;
static int background = 0;
static int mpidfile = 0;
-static int signal_nr = 15;
-static const char *signal_str = NULL;
+static int g_signal_nr = 15;
+static const char *g_signal_str = NULL;
static int user_id = -1;
static int runas_uid = -1;
static int runas_gid = -1;
@@ -93,7 +93,7 @@ static char *execname = NULL;
static char *startas = NULL;
static const char *pidfile = NULL;
static char what_stop[1024];
-static const char *schedule_str = NULL;
+static const char *g_schedule_str = NULL;
static const char *progname = "";
static int nicelevel = 0;
@@ -438,7 +438,7 @@ static void parse_schedule(const char *schedule_str)
if (count == 0) {
schedule[0].type = sched_signal;
- schedule[0].value = signal_nr;
+ schedule[0].value = g_signal_nr;
parse_schedule_item(schedule_str, &schedule[1]);
if (schedule[1].type != sched_timeout) {
badusage(
@@ -528,10 +528,10 @@ static void parse_options(int argc, char *const *argv)
pidfile = optarg;
break;
case 'q': /* --quiet */
- quietmode = 1;
+ g_quietmode = 1;
break;
case 's': /* --signal <signal> */
- signal_str = optarg;
+ g_signal_str = optarg;
break;
case 't': /* --test */
testmode = 1;
@@ -540,7 +540,7 @@ static void parse_options(int argc, char *const *argv)
userspec = optarg;
break;
case 'v': /* --verbose */
- quietmode = -1;
+ g_quietmode = -1;
break;
case 'x': /* --exec <executable> */
execname = optarg;
@@ -567,21 +567,21 @@ static void parse_options(int argc, char *const *argv)
mpidfile = 1;
break;
case 'R': /* --retry <schedule>|<timeout> */
- schedule_str = optarg;
+ g_schedule_str = optarg;
break;
default:
badusage(NULL); /* message printed by getopt */
}
}
- if (signal_str != NULL) {
- if (parse_signal(signal_str, &signal_nr) != 0)
+ if (g_signal_str != NULL) {
+ if (parse_signal(g_signal_str, &g_signal_nr) != 0)
badusage(
"signal value must be numeric or name of signal (KILL, INTR, ...)");
}
- if (schedule_str != NULL) {
- parse_schedule(schedule_str);
+ if (g_schedule_str != NULL) {
+ parse_schedule(g_schedule_str);
}
if (start == stop)
@@ -787,8 +787,8 @@ static int run_stop_schedule(void)
n_killed = 0;
if (schedule == NULL) {
- do_stop(signal_nr, quietmode, &n_killed, &n_notkilled, 0);
- if (n_notkilled > 0 && quietmode <= 0)
+ do_stop(g_signal_nr, g_quietmode, &n_killed, &n_notkilled, 0);
+ if (n_notkilled > 0 && g_quietmode <= 0)
printf("%d pids were not killed\n", n_notkilled);
if (n_killed)
anykilled = 1;
@@ -806,7 +806,7 @@ static int run_stop_schedule(void)
continue;
case sched_signal:
- do_stop(value, quietmode, &n_killed, &n_notkilled,
+ do_stop(value, g_quietmode, &n_killed, &n_notkilled,
retry_nr++);
if (!n_killed)
goto x_finished;
@@ -899,7 +899,7 @@ static int run_stop_schedule(void)
position++;
}
- if (quietmode <= 0)
+ if (g_quietmode <= 0)
printf("Program %s, %d process(es), refused to die.\n",
what_stop, n_killed);
@@ -907,7 +907,7 @@ static int run_stop_schedule(void)
x_finished:
if (!anykilled) {
- if (quietmode <= 0)
+ if (g_quietmode <= 0)
printf("No %s found running; none killed.\n",
what_stop);
return exitnodo;
@@ -969,7 +969,7 @@ int main(int argc, char **argv)
do_findprocs();
if (found) {
- if (quietmode <= 0)
+ if (g_quietmode <= 0)
printf("%s already running.\n", execname);
exit(exitnodo);
}
@@ -992,7 +992,7 @@ int main(int argc, char **argv)
printf(".\n");
exit(0);
}
- if (quietmode < 0)
+ if (g_quietmode < 0)
printf("Starting %s...\n", startas);
*--argv = startas;
if (changeroot != NULL) {
@@ -1013,14 +1013,14 @@ int main(int argc, char **argv)
if (background) { /* ok, we need to detach this process */
int i, fd;
- if (quietmode < 0)
+ if (g_quietmode < 0)
printf("Detaching to start %s...", startas);
i = fork();
if (i < 0) {
fatal("Unable to fork.\n");
}
if (i) { /* parent */
- if (quietmode < 0)
+ if (g_quietmode < 0)
printf("done.\n");
exit(0);
}
diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c
index 009432b217..6b4b3104ea 100644
--- a/vrrpd/vrrp_zebra.c
+++ b/vrrpd/vrrp_zebra.c
@@ -19,7 +19,7 @@
#define VRRP_LOGPFX "[ZEBRA] "
-static struct zclient *zclient;
+static struct zclient *vrrp_zclient;
static void vrrp_zebra_debug_if_state(struct interface *ifp, const char *func)
{
@@ -161,7 +161,7 @@ void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable)
"Requesting Zebra to turn router advertisements %s for %s",
r->vr->vrid, enable ? "on" : "off", r->mvl_ifp->name);
- zclient_send_interface_radv_req(zclient, r->mvl_ifp->vrf->vrf_id,
+ zclient_send_interface_radv_req(vrrp_zclient, r->mvl_ifp->vrf->vrf_id,
r->mvl_ifp, enable, VRRP_RADV_INT);
}
@@ -171,7 +171,7 @@ void vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down)
VRRP_LOGPFX "Requesting Zebra to set %s protodown %s", ifp->name,
down ? "on" : "off");
- zclient_send_interface_protodown(zclient, ifp->vrf->vrf_id, ifp, down);
+ zclient_send_interface_protodown(vrrp_zclient, ifp->vrf->vrf_id, ifp, down);
}
static zclient_handler *const vrrp_handlers[] = {
@@ -188,12 +188,12 @@ void vrrp_zebra_init(void)
hook_register_prio(if_unreal, 0, vrrp_ifp_destroy);
/* Socket for receiving updates from Zebra daemon */
- zclient = zclient_new(master, &zclient_options_default, vrrp_handlers,
- array_size(vrrp_handlers));
+ vrrp_zclient = zclient_new(master, &zclient_options_default, vrrp_handlers,
+ array_size(vrrp_handlers));
- zclient->zebra_connected = vrrp_zebra_connected;
+ vrrp_zclient->zebra_connected = vrrp_zebra_connected;
- zclient_init(zclient, ZEBRA_ROUTE_VRRP, 0, &vrrp_privs);
+ zclient_init(vrrp_zclient, ZEBRA_ROUTE_VRRP, 0, &vrrp_privs);
zlog_notice("%s: zclient socket initialized", __func__);
}
diff --git a/vtysh/vtysh.c b/vtysh/vtysh.c
index 31e7ce12ba..fba39526c6 100644
--- a/vtysh/vtysh.c
+++ b/vtysh/vtysh.c
@@ -44,7 +44,7 @@
DEFINE_MTYPE_STATIC(MVTYSH, VTYSH_CMD, "Vtysh cmd copy");
/* Struct VTY. */
-struct vty *vty;
+struct vty *gvty;
/* VTY shell pager name. */
char *vtysh_pager_name = NULL;
@@ -161,8 +161,8 @@ static int vtysh_reconnect(struct vtysh_client *vclient);
static void vclient_close(struct vtysh_client *vclient)
{
if (vclient->fd >= 0) {
- if (vty->of)
- vty_out(vty,
+ if (gvty->of)
+ vty_out(gvty,
"Warning: closing connection to %s because of an I/O error!\n",
vclient->name);
close(vclient->fd);
@@ -282,8 +282,8 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
vclient, bufvalid, buf + bufsz - bufvalid - 1, pass_fd);
if (nread <= 0) {
- if (vty->of)
- vty_out(vty,
+ if (gvty->of)
+ vty_out(gvty,
"vtysh: error reading from %s: %s (%d)",
vclient->name, safe_strerror(errno),
errno);
@@ -357,8 +357,8 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
/* eol is at line end now, either \n => \0 or \0\0\0 */
assert(eol && eol <= bufvalid);
- if (vty->of)
- vty_out(vty, "%s\n", buf);
+ if (gvty->of)
+ vty_out(gvty, "%s\n", buf);
callback(cbarg, buf);
@@ -371,8 +371,8 @@ static int vtysh_client_run(struct vtysh_client *vclient, const char *line,
/* else if no callback, dump raw */
if (!callback) {
- if (vty->of)
- vty_out(vty, "%s", buf);
+ if (gvty->of)
+ vty_out(gvty, "%s", buf);
memmove(buf, buf + textlen, bufvalid - buf - textlen);
bufvalid -= textlen;
if (end)
@@ -431,8 +431,8 @@ static int vtysh_client_run_all(struct vtysh_client *head_client,
rc_all = rc;
}
}
- if (wrong_instance && !correct_instance && vty->of) {
- vty_out(vty,
+ if (wrong_instance && !correct_instance && gvty->of) {
+ vty_out(gvty,
"%% [%s]: command ignored as it targets an instance that is not running\n",
head_client->name);
rc_all = CMD_WARNING_CONFIG_FAILED;
@@ -468,7 +468,7 @@ static int vtysh_client_execute_name(const char *name, const char *line)
if (idx_client != -1)
ret = vtysh_client_execute(&vtysh_client[idx_client], line);
else {
- vty_out(vty, "Client not found\n");
+ vty_out(gvty, "Client not found\n");
ret = CMD_WARNING;
}
@@ -495,11 +495,11 @@ static void vtysh_client_config(struct vtysh_client *head_client, char *line)
return;
/* suppress output to user */
- vty->of_saved = vty->of;
- vty->of = NULL;
+ gvty->of_saved = gvty->of;
+ gvty->of = NULL;
vtysh_client_run_all(head_client, line, 1, vtysh_config_parse_line,
NULL);
- vty->of = vty->of_saved;
+ gvty->of = gvty->of_saved;
}
/* Command execution over the vty interface. */
@@ -522,11 +522,11 @@ static int vtysh_execute_func(const char *line, int pager)
char ts[48];
(void)frr_timestamp(3, ts, sizeof(ts));
- vty_out(vty, "%% %s\n\n", ts);
+ vty_out(gvty, "%% %s\n\n", ts);
}
- saved_ret = ret = cmd_execute(vty, line, &cmd, 1);
- saved_node = vty->node;
+ saved_ret = ret = cmd_execute(gvty, line, &cmd, 1);
+ saved_node = gvty->node;
/*
* If command doesn't succeeded in current node, try to walk up in node
@@ -536,13 +536,13 @@ static int vtysh_execute_func(const char *line, int pager)
while (ret != CMD_SUCCESS && ret != CMD_SUCCESS_DAEMON
&& ret != CMD_WARNING && ret != CMD_WARNING_CONFIG_FAILED
&& ret != CMD_ERR_AMBIGUOUS && ret != CMD_ERR_INCOMPLETE
- && vty->node > CONFIG_NODE) {
- vty->node = node_parent(vty->node);
- ret = cmd_execute(vty, line, &cmd, 1);
+ && gvty->node > CONFIG_NODE) {
+ gvty->node = node_parent(gvty->node);
+ ret = cmd_execute(gvty, line, &cmd, 1);
tried++;
}
- vty->node = saved_node;
+ gvty->node = saved_node;
/*
* If command succeeded in any other node than current (tried > 0) we
@@ -567,17 +567,17 @@ static int vtysh_execute_func(const char *line, int pager)
switch (ret) {
case CMD_WARNING:
case CMD_WARNING_CONFIG_FAILED:
- if (vty->type == VTY_FILE)
- vty_out(vty, "Warning...\n");
+ if (gvty->type == VTY_FILE)
+ vty_out(gvty, "Warning...\n");
break;
case CMD_ERR_AMBIGUOUS:
- vty_out(vty, "%% Ambiguous command: %s\n", line);
+ vty_out(gvty, "%% Ambiguous command: %s\n", line);
break;
case CMD_ERR_NO_MATCH:
- vty_out(vty, "%% Unknown command: %s\n", line);
+ vty_out(gvty, "%% Unknown command: %s\n", line);
break;
case CMD_ERR_INCOMPLETE:
- vty_out(vty, "%% Command incomplete: %s\n", line);
+ vty_out(gvty, "%% Command incomplete: %s\n", line);
break;
case CMD_SUCCESS_DAEMON: {
/*
@@ -586,7 +586,7 @@ static int vtysh_execute_func(const char *line, int pager)
* cause any problem but is really ugly.
*/
if (pager && strncmp(line, "exit", 4))
- vty_open_pager(vty);
+ vty_open_pager(gvty);
if (!strcmp(cmd->string, "configure")) {
for (i = 0; i < array_size(vtysh_client); i++) {
@@ -602,17 +602,17 @@ static int vtysh_execute_func(const char *line, int pager)
if (vline == NULL) {
- if (vty->is_paged)
- vty_close_pager(vty);
+ if (gvty->is_paged)
+ vty_close_pager(gvty);
return CMD_SUCCESS;
}
- ret = cmd_execute_command(vline, vty, &cmd, 1);
+ ret = cmd_execute_command(vline, gvty, &cmd, 1);
cmd_free_strvec(vline);
if (ret != CMD_SUCCESS_DAEMON)
break;
} else if (cmd->func) {
- (*cmd->func)(cmd, vty, 0, NULL);
+ (*cmd->func)(cmd, gvty, 0, NULL);
break;
}
}
@@ -653,11 +653,11 @@ static int vtysh_execute_func(const char *line, int pager)
break;
if (cmd->func)
- (*cmd->func)(cmd, vty, 0, NULL);
+ (*cmd->func)(cmd, gvty, 0, NULL);
}
}
- if (vty->is_paged)
- vty_close_pager(vty);
+ if (gvty->is_paged)
+ vty_close_pager(gvty);
return cmd_stat;
}
@@ -980,21 +980,21 @@ static int vtysh_process_questionmark(const char *input, int input_len)
} else if (input_len && isspace((unsigned char)input[input_len - 1]))
vector_set(vline, NULL);
- describe = cmd_describe_command(vline, vty, &ret);
+ describe = cmd_describe_command(vline, gvty, &ret);
/* Ambiguous and no match error. */
switch (ret) {
case CMD_ERR_AMBIGUOUS:
cmd_free_strvec(vline);
vector_free(describe);
- vty_out(vty, "%% Ambiguous command.\n");
+ vty_out(gvty, "%% Ambiguous command.\n");
rl_on_new_line();
return 0;
case CMD_ERR_NO_MATCH:
cmd_free_strvec(vline);
if (describe)
vector_free(describe);
- vty_out(vty, "%% There is no matched command.\n");
+ vty_out(gvty, "%% There is no matched command.\n");
rl_on_new_line();
return 0;
}
@@ -1015,9 +1015,9 @@ static int vtysh_process_questionmark(const char *input, int input_len)
for (i = 0; i < vector_active(describe); i++)
if ((token = vector_slot(describe, i)) != NULL) {
if (!token->desc)
- vty_out(vty, " %-s\n", token->text);
+ vty_out(gvty, " %-s\n", token->text);
else
- vty_out(vty, " %-*s %s\n", width, token->text,
+ vty_out(gvty, " %-*s %s\n", width, token->text,
token->desc);
if (IS_VARYING_TOKEN(token->type)) {
@@ -1033,7 +1033,7 @@ static int vtysh_process_questionmark(const char *input, int input_len)
char *ac = cmd_variable_comp2str(
varcomps, cols);
- vty_out(vty, "%s\n", ac);
+ vty_out(gvty, "%s\n", ac);
XFREE(MTYPE_TMP, ac);
}
@@ -1056,7 +1056,7 @@ static int vtysh_rl_describe(int a, int b)
{
int ret;
- vty_out(vty, "\n");
+ vty_out(gvty, "\n");
ret = vtysh_process_questionmark(rl_line_buffer, rl_end);
rl_on_new_line();
@@ -1116,7 +1116,7 @@ static char *command_generator(const char *text, int state)
if (!state) {
index = 0;
- if (vty->node == AUTH_NODE || vty->node == AUTH_ENABLE_NODE)
+ if (gvty->node == AUTH_NODE || gvty->node == AUTH_ENABLE_NODE)
return NULL;
vline = cmd_make_strvec(rl_line_buffer);
@@ -1127,7 +1127,7 @@ static char *command_generator(const char *text, int state)
isspace((unsigned char)rl_line_buffer[rl_end - 1]))
vector_set(vline, NULL);
- matched = cmd_complete_command(vline, vty, &complete_status);
+ matched = cmd_complete_command(vline, gvty, &complete_status);
cmd_free_strvec(vline);
}
@@ -1672,13 +1672,13 @@ extern struct cmd_node vty_node;
/* When '^Z' is received from vty, move down to the enable mode. */
static int vtysh_end(void)
{
- switch (vty->node) {
+ switch (gvty->node) {
case VIEW_NODE:
case ENABLE_NODE:
/* Nothing to do. */
break;
default:
- vty->node = ENABLE_NODE;
+ gvty->node = ENABLE_NODE;
break;
}
return CMD_SUCCESS;
@@ -3627,7 +3627,7 @@ static void show_route_map_send(const char *route_map, bool json)
strlcat(command_line, " json", sizeof(command_line));
if (json)
- vty_out(vty, "{");
+ vty_out(gvty, "{");
for (i = 0; i < array_size(vtysh_client); i++) {
const struct vtysh_client *client = &vtysh_client[i];
@@ -3644,18 +3644,18 @@ static void show_route_map_send(const char *route_map, bool json)
continue;
if (json && !first)
- vty_out(vty, ",");
+ vty_out(gvty, ",");
else
first = false;
if (json)
- vty_out(vty, "\"%s\":", vtysh_client[i].name);
+ vty_out(gvty, "\"%s\":", vtysh_client[i].name);
vtysh_client_execute_name(vtysh_client[i].name, command_line);
}
if (json)
- vty_out(vty, "}\n");
+ vty_out(gvty, "}\n");
}
DEFPY (show_route_map,
@@ -3699,7 +3699,7 @@ static void show_prefix_list_send(afi_t afi, const char *prefix_list,
strlcat(command_line, " json", sizeof(command_line));
if (json)
- vty_out(vty, "{");
+ vty_out(gvty, "{");
for (i = 0; i < array_size(vtysh_client); i++) {
const struct vtysh_client *client = &vtysh_client[i];
@@ -3716,18 +3716,18 @@ static void show_prefix_list_send(afi_t afi, const char *prefix_list,
continue;
if (json && !first)
- vty_out(vty, ",");
+ vty_out(gvty, ",");
else
first = false;
if (json)
- vty_out(vty, "\"%s\":", vtysh_client[i].name);
+ vty_out(gvty, "\"%s\":", vtysh_client[i].name);
vtysh_client_execute_name(vtysh_client[i].name, command_line);
}
if (json)
- vty_out(vty, "}\n");
+ vty_out(gvty, "}\n");
}
DEFPY (show_ip_prefix_list,
@@ -3842,7 +3842,7 @@ static void show_access_list_send(afi_t afi, const char *access_list, bool json)
strlcat(command_line, access_list, sizeof(command_line));
if (json) {
strlcat(command_line, " json", sizeof(command_line));
- vty_out(vty, "{");
+ vty_out(gvty, "{");
}
for (i = 0; i < array_size(vtysh_client); i++) {
@@ -3860,18 +3860,18 @@ static void show_access_list_send(afi_t afi, const char *access_list, bool json)
continue;
if (json && !first)
- vty_out(vty, ",");
+ vty_out(gvty, ",");
else
first = false;
if (json)
- vty_out(vty, "\"%s\":", vtysh_client[i].name);
+ vty_out(gvty, "\"%s\":", vtysh_client[i].name);
vtysh_client_execute_name(vtysh_client[i].name, command_line);
}
if (json)
- vty_out(vty, "}\n");
+ vty_out(gvty, "}\n");
}
DEFPY (show_ip_access_list,
@@ -3956,10 +3956,10 @@ static void backup_config_file(const char *fbackup)
/* Move current configuration file to backup config file. */
if (unlink(integrate_sav) != 0 && errno != ENOENT)
- vty_out(vty, "Unlink failed for %s: %s\n", integrate_sav,
+ vty_out(gvty, "Unlink failed for %s: %s\n", integrate_sav,
strerror(errno));
if (rename(fbackup, integrate_sav) != 0 && errno != ENOENT)
- vty_out(vty, "Error renaming %s to %s: %s\n", fbackup,
+ vty_out(gvty, "Error renaming %s to %s: %s\n", fbackup,
integrate_sav, strerror(errno));
free(integrate_sav);
}
@@ -3981,12 +3981,12 @@ int vtysh_write_config_integrated(void)
struct stat st;
int err = 0;
- vty_out(vty, "Building Configuration...\n");
+ vty_out(gvty, "Building Configuration...\n");
backup_config_file(frr_config);
fp = fopen(frr_config, "w");
if (fp == NULL) {
- vty_out(vty,
+ vty_out(gvty,
"%% Error: failed to open configuration file %s: %s\n",
frr_config, safe_strerror(errno));
return CMD_WARNING_CONFIG_FAILED;
@@ -3997,10 +3997,10 @@ int vtysh_write_config_integrated(void)
vtysh_client_config(&vtysh_client[i], line);
vtysh_config_write();
- vty->of_saved = vty->of;
- vty->of = fp;
+ gvty->of_saved = gvty->of;
+ gvty->of = fp;
vtysh_config_dump();
- vty->of = vty->of_saved;
+ gvty->of = gvty->of_saved;
if (fchmod(fd, CONFIGFILE_MASK) != 0) {
printf("%% Warning: can't chmod configuration file %s: %s\n",
@@ -4964,7 +4964,7 @@ char *vtysh_prompt(void)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat-nonliteral"
/* prompt formatting has a %s in the cmd_node prompt string. */
- snprintf(buf, sizeof(buf), cmd_prompt(vty->node), cmd_hostname_get());
+ snprintf(buf, sizeof(buf), cmd_prompt(gvty->node), cmd_hostname_get());
#pragma GCC diagnostic pop
return buf;
}
@@ -4987,12 +4987,12 @@ static void vtysh_autocomplete(vector comps, struct cmd_token *token)
snprintf(accmd, sizeof(accmd), "autocomplete %d %s %s", token->type,
token->text, token->varname ? token->varname : "-");
- vty->of_saved = vty->of;
- vty->of = NULL;
+ gvty->of_saved = gvty->of;
+ gvty->of = NULL;
for (i = 0; i < array_size(vtysh_client); i++)
vtysh_client_run_all(&vtysh_client[i], accmd, 1, vtysh_ac_line,
comps);
- vty->of = vty->of_saved;
+ gvty->of = gvty->of_saved;
}
static const struct cmd_variable_handler vtysh_var_handler[] = {
@@ -5004,8 +5004,8 @@ static const struct cmd_variable_handler vtysh_var_handler[] = {
void vtysh_uninit(void)
{
- if (vty->of != stdout)
- fclose(vty->of);
+ if (gvty->of != stdout)
+ fclose(gvty->of);
}
void vtysh_init_vty(void)
@@ -5026,12 +5026,12 @@ void vtysh_init_vty(void)
stderr_stdout_same = true;
/* Make vty structure. */
- vty = vty_new();
- vty->type = VTY_SHELL;
- vty->node = VIEW_NODE;
+ gvty = vty_new();
+ gvty->type = VTY_SHELL;
+ gvty->node = VIEW_NODE;
/* set default output */
- vty->of = stdout;
+ gvty->of = stdout;
vtysh_pager_envdef(false);
/* Initialize commands. */
diff --git a/vtysh/vtysh.h b/vtysh/vtysh.h
index 3c532b99a8..6d5e559a2f 100644
--- a/vtysh/vtysh.h
+++ b/vtysh/vtysh.h
@@ -152,7 +152,7 @@ void suid_off(void);
/* Child process execution flag. */
extern int execute_flag;
-extern struct vty *vty;
+extern struct vty *gvty;
extern int user_mode;
diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c
index 6536e1b376..4f6fc782c2 100644
--- a/vtysh/vtysh_config.c
+++ b/vtysh/vtysh_config.c
@@ -558,19 +558,19 @@ static void configvec_dump(vector vec, bool nested)
continue;
}
- vty_out(vty, "%s\n", config->name);
+ vty_out(gvty, "%s\n", config->name);
for (ALL_LIST_ELEMENTS(config->line, mnode,
mnnode, line))
- vty_out(vty, "%s\n", line);
+ vty_out(gvty, "%s\n", line);
configvec_dump(config->nested, true);
if (config->exit)
- vty_out(vty, "%s\n", config->exit);
+ vty_out(gvty, "%s\n", config->exit);
if (!NO_DELIMITER(i))
- vty_out(vty, "!\n");
+ vty_out(gvty, "!\n");
config_del(config);
}
@@ -579,7 +579,7 @@ static void configvec_dump(vector vec, bool nested)
XFREE(MTYPE_VTYSH_CONFIG, configuration);
vector_slot(vec, i) = NULL;
if (!nested && NO_DELIMITER(i))
- vty_out(vty, "!\n");
+ vty_out(gvty, "!\n");
}
}
@@ -589,11 +589,11 @@ void vtysh_config_dump(void)
char *line;
for (ALL_LIST_ELEMENTS(config_top, node, nnode, line))
- vty_out(vty, "%s\n", line);
+ vty_out(gvty, "%s\n", line);
list_delete_all_node(config_top);
- vty_out(vty, "!\n");
+ vty_out(gvty, "!\n");
configvec_dump(configvec, false);
}
@@ -601,13 +601,13 @@ void vtysh_config_dump(void)
/* Read up configuration file from file_name. */
static int vtysh_read_file(FILE *confp, bool dry_run)
{
- struct vty *vty;
+ struct vty *lvty;
int ret;
- vty = vty_new();
- vty->wfd = STDERR_FILENO;
- vty->type = VTY_TERM;
- vty->node = CONFIG_NODE;
+ lvty = vty_new();
+ lvty->wfd = STDERR_FILENO;
+ lvty->type = VTY_TERM;
+ lvty->node = CONFIG_NODE;
vtysh_execute_no_pager("enable");
/*
@@ -622,7 +622,7 @@ static int vtysh_read_file(FILE *confp, bool dry_run)
vtysh_execute_no_pager("XFRR_start_configuration");
/* Execute configuration file. */
- ret = vtysh_config_from_file(vty, confp);
+ ret = vtysh_config_from_file(lvty, confp);
if (!dry_run)
vtysh_execute_no_pager("XFRR_end_configuration");
@@ -630,7 +630,7 @@ static int vtysh_read_file(FILE *confp, bool dry_run)
vtysh_execute_no_pager("end");
vtysh_execute_no_pager("disable");
- vty_close(vty);
+ vty_close(lvty);
return (ret);
}
diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c
index 297d87ec41..16e166beac 100644
--- a/vtysh/vtysh_main.c
+++ b/vtysh/vtysh_main.c
@@ -726,7 +726,7 @@ int main(int argc, char **argv, char **env)
vtysh_readline_init();
- vty_hello(vty);
+ vty_hello(gvty);
/* Enter into enable node. */
if (!user_mode)
diff --git a/yang/frr-bfdd.yang b/yang/frr-bfdd.yang
index 75af799acc..249d162ffc 100644
--- a/yang/frr-bfdd.yang
+++ b/yang/frr-bfdd.yang
@@ -49,8 +49,8 @@ module frr-bfdd {
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.";
- revision 2019-05-09 {
- description "Initial revision.";
+ revision 2025-03-03 {
+ description "Add log-session-changes leaf";
reference
"RFC 5880: Bidirectional Forwarding Detection (BFD).
RFC 5881: Bidirectional Forwarding Detection (BFD)
@@ -58,8 +58,8 @@ module frr-bfdd {
RFC 5883: Bidirectional Forwarding Detection (BFD) for Multihop Paths.";
}
- revision 2025-03-03 {
- description "Add log-sessio-changes leaf";
+ revision 2019-05-09 {
+ description "Initial revision.";
reference
"RFC 5880: Bidirectional Forwarding Detection (BFD).
RFC 5881: Bidirectional Forwarding Detection (BFD)
@@ -71,21 +71,20 @@ module frr-bfdd {
* BFD types declaration.
*/
typedef multiplier {
- description "Detection multiplier";
type uint8 {
range "1..255";
}
+ description "Detection multiplier";
}
typedef discriminator {
- description "BFD session identification";
type uint32 {
range "1..4294967295";
}
+ description "BFD session identification";
}
typedef state {
- description "BFD session state";
type enumeration {
enum admin-down {
value 0;
@@ -104,10 +103,10 @@ module frr-bfdd {
description "Up";
}
}
+ description "BFD session state";
}
typedef diagnostic {
- description "BFD session diagnostic";
type enumeration {
enum ok {
value 0;
@@ -146,6 +145,7 @@ module frr-bfdd {
description "Reverse concatenated path down";
}
}
+ description "BFD session diagnostic";
}
typedef profile-name {
@@ -272,23 +272,27 @@ module frr-bfdd {
}
leaf multi-hop {
- description
- "Use multi hop session instead of single hop.";
type boolean;
default false;
+ description
+ "Use multi hop session instead of single hop.";
}
leaf profile {
+ type frr-bfdd:profile-ref;
description
"BFD pre configured profile.";
- type frr-bfdd:profile-ref;
}
}
grouping session-states {
+ description
+ "This grouping defines the states of a BFD session.";
+
/*
* Local settings.
*/
+
leaf local-discriminator {
type discriminator;
description "Local session identifier";
@@ -336,20 +340,18 @@ module frr-bfdd {
* Negotiated settings.
*/
leaf negotiated-transmission-interval {
- description "Negotiated transmit interval";
type uint32;
units microseconds;
+ description "Negotiated transmit interval";
}
leaf negotiated-receive-interval {
- description "Negotiated receive interval";
type uint32;
units microseconds;
+ description "Negotiated receive interval";
}
leaf detection-mode {
- description "Detection mode";
-
type enumeration {
enum async-with-echo {
value "1";
@@ -368,6 +370,7 @@ module frr-bfdd {
description "Demand without echo";
}
}
+ description "Detection mode";
}
/*
@@ -430,6 +433,9 @@ module frr-bfdd {
* BFD operational.
*/
container bfdd {
+ description
+ "This container defines BFD daemon configuration.";
+
container bfd {
presence "Present if the BFD protocol is enabled";
@@ -448,6 +454,9 @@ module frr-bfdd {
}
container sessions {
+ description
+ "This container provides information about sessions.";
+
list single-hop {
key "dest-addr interface vrf";
description "List of single hop sessions";
@@ -483,6 +492,8 @@ module frr-bfdd {
container stats {
uses session-states;
config false;
+ description
+ "This container provides statistics for sessions.";
}
}
@@ -516,6 +527,8 @@ module frr-bfdd {
container stats {
uses session-states;
config false;
+ description
+ "This container provides statistics for sessions.";
}
}
@@ -577,6 +590,8 @@ module frr-bfdd {
container stats {
uses session-states;
config false;
+ description
+ "This container provides statistics for sessions.";
}
}
@@ -644,9 +659,13 @@ module frr-bfdd {
container stats {
uses session-states;
config false;
+ description
+ "This container provides statistics for sessions.";
}
}
}
+ description
+ "This container defines BFD protocol configuration.";
}
}
}
diff --git a/yang/frr-eigrpd.yang b/yang/frr-eigrpd.yang
index 8f2ad5be46..931f5f6fee 100644
--- a/yang/frr-eigrpd.yang
+++ b/yang/frr-eigrpd.yang
@@ -112,7 +112,7 @@ module frr-eigrpd {
list instance {
key "asn vrf";
description "EIGRP autonomous system instance";
-
+ must "count(../instance[vrf =current()/vrf]) = 1";
leaf asn {
type autonomous-system;
description "Autonomous System Number";
diff --git a/yang/frr-pathd.yang b/yang/frr-pathd.yang
index 5beda769c1..96eafda9d4 100644
--- a/yang/frr-pathd.yang
+++ b/yang/frr-pathd.yang
@@ -6,15 +6,9 @@ module frr-pathd {
import ietf-inet-types {
prefix inet;
}
- import ietf-yang-types {
- prefix yang;
- }
import ietf-routing-types {
prefix rt-types;
}
- import frr-interface {
- prefix frr-interface;
- }
organization
"Free Range Routing";
@@ -27,11 +21,10 @@ module frr-pathd {
revision 2018-11-06 {
description
"Initial revision.";
+ reference "FRRouting";
}
typedef protocol-origin-type {
- description
- "Indication for the protocol origin of an object.";
type enumeration {
enum pcep {
value 1;
@@ -46,6 +39,8 @@ module frr-pathd {
description "The object was created through CLI, Yang model via Netconf, gRPC, etc";
}
}
+ description
+ "Indication for the protocol origin of an object.";
}
typedef originator-type {
@@ -57,7 +52,13 @@ module frr-pathd {
}
container pathd {
+ description
+ "Path properties for Segment Routing TE";
+
container srte {
+ description
+ "Segment Routing TE properties";
+
list segment-list {
key "name";
description "Segment-list properties";
@@ -91,9 +92,10 @@ module frr-pathd {
}
container nai {
presence "The segment has a Node or Adjacency Identifier";
+ description
+ "Node or Adjacency Identifier for the segment";
+
leaf type {
- description "NAI type";
- mandatory true;
type enumeration {
enum ipv4_node {
value 1;
@@ -132,42 +134,59 @@ module frr-pathd {
description "IPv6 prefix with optional algorithm";
}
}
+ mandatory true;
+ description "NAI type";
}
leaf local-address {
type inet:ip-address;
mandatory true;
+ description
+ "Local address of the NAI";
}
leaf local-prefix-len {
+ when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_algo' or ../type = 'ipv6_algo'";
type uint8;
mandatory true;
- when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_algo' or ../type = 'ipv6_algo'";
+ description
+ "Prefix length of the local address";
}
leaf local-interface {
+ when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_unnumbered_adjacency'";
type uint32;
mandatory true;
- when "../type = 'ipv4_local_iface' or ../type = 'ipv6_local_iface' or ../type = 'ipv4_unnumbered_adjacency'";
+ description
+ "Local interface ID for the NAI";
}
leaf remote-address {
+ when "../type = 'ipv4_adjacency' or ../type = 'ipv6_adjacency' or ../type = 'ipv4_unnumbered_adjacency'";
type inet:ip-address;
- mandatory true;
- when "../type = 'ipv4_adjacency' or ../type = 'ipv6_adjacency' or ../type = 'ipv4_unnumbered_adjacency'";
- }
- leaf remote-interface {
- type uint32;
- mandatory true;
- when "../type = 'ipv4_unnumbered_adjacency'";
- }
+ mandatory true;
+ description
+ "Remote address of the NAI";
+ }
+ leaf remote-interface {
+ when "../type = 'ipv4_unnumbered_adjacency'";
+ type uint32;
+ mandatory true;
+ description
+ "Remote interface ID for the NAI";
+ }
leaf algorithm {
+ when "../type = 'ipv4_algo' or ../type = 'ipv6_algo'";
type uint8;
mandatory true;
- when "../type = 'ipv4_algo' or ../type = 'ipv6_algo'";
- }
+ description
+ "Algorithm to use for the NAI";
}
+ }
}
}
list policy {
key "color endpoint";
unique "name";
+ description
+ "List of SR Policies.";
+
leaf color {
type uint32;
description
@@ -197,10 +216,10 @@ module frr-pathd {
"True if a valid candidate path of this policy is operational in zebra, False otherwise";
}
list candidate-path {
+ key "preference";
unique "name";
description
"List of Candidate Paths of the SR Policy.";
- key "preference";
leaf preference {
type uint32;
description
@@ -237,17 +256,21 @@ module frr-pathd {
description "Candidate path distinguisher";
}
leaf type {
- description
- "Type of the Candidate Path.";
- mandatory true;
type enumeration {
enum explicit {
value 1;
+ description
+ "Explicit path defined by a segment list";
}
enum dynamic {
value 2;
+ description
+ "Dynamic path computed by a routing protocol";
}
}
+ mandatory true;
+ description
+ "Type of the Candidate Path.";
}
leaf segment-list-name {
type leafref {
@@ -271,10 +294,12 @@ module frr-pathd {
"If the bandwidth limitation is a requirement or only a suggestion";
}
leaf value {
- mandatory true;
type decimal64 {
fraction-digits 6;
}
+ mandatory true;
+ description
+ "The bandwidth value for the candidate path.";
}
}
container affinity {
@@ -298,9 +323,10 @@ module frr-pathd {
}
list metrics {
key "type";
+ description
+ "This list contains the different metrics that can be used to describe a path.";
+
leaf type {
- description
- "Type of the metric.";
type enumeration {
enum igp {
value 1;
@@ -387,6 +413,8 @@ module frr-pathd {
description "Border Node Count metric";
}
}
+ description
+ "Type of the metric.";
}
leaf required {
type boolean;
@@ -405,10 +433,12 @@ module frr-pathd {
"Defines if the value has been generated by the originator of the path.";
}
leaf value {
- mandatory true;
type decimal64 {
fraction-digits 6;
}
+ mandatory true;
+ description
+ "Value of the metric.";
}
}
container objective-function {
@@ -422,9 +452,6 @@ module frr-pathd {
"If an objective function is a requirement, or if it is only a suggestion";
}
leaf type {
- description
- "Type of objective function.";
- mandatory true;
type enumeration {
enum mcp {
value 1;
@@ -495,6 +522,9 @@ module frr-pathd {
description "Minimize the number of Shared Nodes";
}
}
+ mandatory true;
+ description
+ "Type of objective function.";
}
}
}
diff --git a/yang/frr-zebra.yang b/yang/frr-zebra.yang
index 72f3f7072e..4dd8e98ddb 100644
--- a/yang/frr-zebra.yang
+++ b/yang/frr-zebra.yang
@@ -79,6 +79,9 @@ module frr-zebra {
revision 2019-06-01 {
description
"Initial revision.";
+
+ reference
+ "FRRouting";
}
feature ipv6-router-advertisements {
@@ -188,6 +191,8 @@ module frr-zebra {
"Multicast PIM-SM.";
}
}
+ description
+ "Type for VTEP flood type.";
}
/*
@@ -317,7 +322,13 @@ module frr-zebra {
*/
grouping vni-information {
+ description
+ "Grouping for VNI information.";
+
choice type-choice {
+ description
+ "Choice between L2 and L3 VNI information.";
+
case l2 {
leaf is-layer2 {
type empty;
@@ -383,6 +394,9 @@ module frr-zebra {
*/
grouping vni-l2-detail {
+ description
+ "Grouping for VNI L2 details.";
+
leaf if-index {
type uint32;
description
@@ -402,6 +416,9 @@ module frr-zebra {
}
list remote-vtep-list {
+ description
+ "List of remote VTEPs.";
+
leaf remote-vtep {
type inet:ipv4-address;
description
@@ -410,6 +427,8 @@ module frr-zebra {
leaf vtep-flood {
type vni-vtep-flood-type;
+ description
+ "VTEP flood type.";
}
}
}
@@ -419,6 +438,9 @@ module frr-zebra {
*/
grouping vni-l3-detail {
+ description
+ "Grouping for VNI L3 details.";
+
leaf svi-interface {
type frr-interface:interface-ref;
description
@@ -459,6 +481,9 @@ module frr-zebra {
*/
grouping zebra-debugs {
+ description
+ "Grouping for Zebra debugging options.";
+
leaf debug-events {
type boolean;
description
@@ -569,12 +594,19 @@ module frr-zebra {
}
grouping ribs {
+ description
+ "Grouping for RIBs supported by FRR.";
+
container ribs {
config false;
description
"RIBs supported by FRR.";
list rib {
key "afi-safi-name table-id";
+
+ description
+ "List of RIBs, each with a specific AFI/SAFI name and table ID.";
+
leaf afi-safi-name {
type identityref {
base frr-rt:afi-safi-type;
@@ -585,13 +617,16 @@ module frr-zebra {
leaf table-id {
type uint32;
- default "254";
description
"Routing Table id (default id - 254).";
}
list route {
key "prefix";
+
+ description
+ "List of routes, each with a specific prefix.";
+
leaf prefix {
type inet:ip-prefix;
description
@@ -600,6 +635,10 @@ module frr-zebra {
list route-entry {
key "protocol";
+
+ description
+ "List of route entries, each owned by a specific protocol.";
+
leaf protocol {
type frr-route-types:frr-route-types;
description
@@ -647,6 +686,9 @@ module frr-zebra {
"Retrieve IPv4 or IPv6 unicast routes.";
input {
choice ip-type {
+ description
+ "Choice between retrieving IPv4 routes and retrieving IPv6 routes.";
+
case v4 {
leaf ipv4 {
type empty;
@@ -685,6 +727,10 @@ module frr-zebra {
}
choice vrf-choice {
+ description
+ "Choice between retrieving routes in a non-default VRF or |
+ retrieving routes from all VRFs.";
+
case single {
leaf vrf {
type frr-vrf:vrf-ref;
@@ -732,6 +778,10 @@ module frr-zebra {
}
choice detail {
+ description
+ "Choice between including detailed information and |
+ including summary information only.";
+
case det {
leaf include-detail {
type empty;
@@ -752,11 +802,17 @@ module frr-zebra {
// End of input
output {
choice route-list {
+ description
+ "Choice between IPv4 route information and IPv6 route information.";
+
case v4 {
container routes-v4 {
description
"IPv4 route information.";
list route {
+ description
+ "List of IPv4 routes.";
+
uses ip4-route;
}
}
@@ -767,6 +823,9 @@ module frr-zebra {
description
"IPv6 route information.";
list route {
+ description
+ "List of IPv6 routes.";
+
uses ip6-route;
}
}
@@ -783,6 +842,10 @@ module frr-zebra {
"Retrieve IPv6 multicast routes.";
input {
choice vrf-choice {
+ description
+ "Choice between retrieving routes in a non-default VRF or |
+ retrieving routes from all VRFs.";
+
case single {
leaf vrf {
type frr-vrf:vrf-ref;
@@ -806,6 +869,9 @@ module frr-zebra {
description
"IPv6 mcast route information.";
list route {
+ description
+ "List of IPv6 routes.";
+
uses ip6-route;
}
}
@@ -820,6 +886,10 @@ module frr-zebra {
// Note: no input clause.
output {
list vrf-list {
+ description
+ "List of VRF information including name, user configuration status, |
+ VRF ID, and VRF type.";
+
leaf name {
type frr-vrf:vrf-ref;
description
@@ -839,6 +909,10 @@ module frr-zebra {
}
choice vrf-type {
+ description
+ "Choice between specifying the VRF as inactive, associated with a net namespace, |
+ or associated with a table ID.";
+
case inactive {
leaf is-inactive {
type empty;
@@ -875,6 +949,10 @@ module frr-zebra {
// Note: no input clause.
output {
list vrf-vni-list {
+ description
+ "List of VRF VNI information including VRF name, EVPN VNI, VxLAN interface name, |
+ SVI interface name, router MAC address, and state.";
+
leaf vrf-name {
type frr-vrf:vrf-ref;
description
@@ -971,6 +1049,10 @@ module frr-zebra {
}
choice dad-freeze-choice {
+ description
+ "Choice between setting duplicate address detection |
+ freeze to permanent or specifying a timer.";
+
case freeze-permanent {
leaf dad-freeze-perm {
type empty;
@@ -994,10 +1076,16 @@ module frr-zebra {
// End get-evpn-info
rpc get-vni-info {
+ description
+ "Retrieve information about EVPN VNIs.";
+
// If no vni is specified, retrieve global list.
input {
choice vni-choice {
default "all-vnis";
+ description
+ "Choice between retrieving information about all VNIs or a specific EVPN VNI.";
+
case all-vnis {
leaf all-vnis {
type empty;
@@ -1029,6 +1117,9 @@ module frr-zebra {
uses vni-information;
choice detail-choice {
+ description
+ "Choice between detailed L2 or L3 information.";
+
case l2 {
description
"Detailed L2 information.";
@@ -1053,6 +1144,10 @@ module frr-zebra {
input {
choice vni-choice {
default "all-vnis";
+ description
+ "Choice between retrieving information about all VNIs or |
+ a specific EVPN VNI and a single RMAC address.";
+
case all-vnis {
leaf all-vnis {
type empty;
@@ -1079,6 +1174,10 @@ module frr-zebra {
output {
list rmac-info-list {
+ description
+ "List of RMAC information including RMAC address, remote VTEP IP address, |
+ refcount, and associated IP prefixes.";
+
leaf rmac {
type yang:mac-address;
description
@@ -1098,6 +1197,9 @@ module frr-zebra {
}
list prefix-list {
+ description
+ "List of IP prefixes associated with the RMAC.";
+
leaf prefix-item {
type inet:ip-prefix;
description
@@ -1116,6 +1218,10 @@ module frr-zebra {
input {
choice vni-choice {
default "all-vnis";
+ description
+ "Choice between retrieving information about all VNIs or |
+ a specific EVPN VNI and a single host IP address.";
+
case all-vnis {
leaf all-vnis {
type empty;
@@ -1142,6 +1248,9 @@ module frr-zebra {
output {
list nh-info-list {
+ description
+ "List of nexthop information including IP address, MAC address, and refcount.";
+
leaf ip-addr {
type inet:ip-address;
description
@@ -1161,6 +1270,9 @@ module frr-zebra {
}
list prefix-list {
+ description
+ "List of IP prefixes associated with the RMAC.";
+
leaf prefix-item {
type inet:ip-prefix;
description
@@ -1178,6 +1290,11 @@ module frr-zebra {
"Clear duplicate address detection state for one or all VNIs.";
input {
choice clear-dup-choice {
+ description
+ "Choice between clearing all VNIs or |
+ clearing state for a single EVPN VNI |
+ and a specific MAC or IP address.";
+
case all-case {
leaf all-vnis {
type empty;
@@ -1225,6 +1342,11 @@ module frr-zebra {
input {
choice all-choice {
default "all-vni";
+ description
+ "Choice between retrieving information for all VNIs or |
+ including detailed results, a single VTEP address, or |
+ showing duplicate addresses.";
+
case all-vni {
leaf all-vnis {
type empty;
@@ -1233,6 +1355,10 @@ module frr-zebra {
}
choice all-choices {
+ description
+ "Choice between including detailed results, a single VTEP address, |
+ or showing duplicate addresses.";
+
case detail-case {
leaf all-detail {
type empty;
@@ -1267,6 +1393,10 @@ module frr-zebra {
}
choice single-choices {
+ description
+ "Choice between including detailed results, a specific MAC address, |
+ a single VTEP address, or showing duplicate addresses.";
+
case detail-case {
leaf single-detail {
type empty;
@@ -1305,6 +1435,9 @@ module frr-zebra {
// End of input section
output {
list mac-list {
+ description
+ "List of MAC addresses.";
+
leaf mac-addr {
type yang:mac-address;
description
@@ -1348,6 +1481,9 @@ module frr-zebra {
}
container dup-detect-started {
+ description
+ "Container for duplicate detection process start time and count.";
+
leaf dup-detect-start {
type unix-timestamp;
description
@@ -1386,6 +1522,9 @@ module frr-zebra {
}
list neighbor-list {
+ description
+ "List of neighbor addresses.";
+
leaf neighbor-addr {
type inet:ip-address;
description
@@ -1406,6 +1545,9 @@ module frr-zebra {
}
choice local-rem-choice {
+ description
+ "Choice between local interface and VLAN or remote VTEP IP address.";
+
case local-case {
leaf intf {
type frr-interface:interface-ref;
@@ -1440,6 +1582,8 @@ module frr-zebra {
input {
choice all-choice {
default "all-vni";
+ description
+ "Choice between retrieving information for all VNIs or including detailed results or showing duplicates.";
case all-vni {
leaf all-vnis {
type empty;
@@ -1448,6 +1592,9 @@ module frr-zebra {
}
choice all-choices {
+ description
+ "Choice between including detailed results or showing duplicates.";
+
case detail-case {
leaf all-detail {
type empty;
@@ -1474,6 +1621,9 @@ module frr-zebra {
}
choice single-choices {
+ description
+ "Choice between single VTEP, neighbor address, or show duplicates.";
+
case vtep-case {
leaf single-vtep {
type inet:ipv4-address;
@@ -1504,6 +1654,9 @@ module frr-zebra {
// End input section
output {
list vni-list {
+ description
+ "List of VNI containers.";
+
container vni-container {
description
"Information for one VNI.";
@@ -1535,6 +1688,9 @@ module frr-zebra {
}
choice local-remote-choice {
+ description
+ "Choice between local and remote entries.";
+
case local-case {
leaf is-local {
type empty;
@@ -1596,6 +1752,9 @@ module frr-zebra {
// End get-evpn-arp-cache
rpc get-pbr-ipset {
+ description
+ "RPC to retrieve PBR IP set.";
+
input {
leaf name {
type string {
@@ -1608,6 +1767,9 @@ module frr-zebra {
output {
list ipset-list {
+ description
+ "List of IP sets.";
+
leaf name {
type string {
length "1..32";
@@ -1621,24 +1783,26 @@ module frr-zebra {
enum "net-net" {
value 1;
description
- "";
+ "Network to network IP set type.";
}
enum "net-port-net" {
value 2;
description
- "";
+ "Network to port to network IP set type.";
}
enum "net-port" {
value 3;
description
- "";
+ "Network to port IP set type.";
}
enum "net" {
value 4;
description
- "";
+ "Network IP set type.";
}
}
+ description
+ "Type of IP set.";
}
leaf src-prefix {
@@ -1714,6 +1878,9 @@ module frr-zebra {
}
container ipset-stats {
+ description
+ "Container for IP set statistics.";
+
leaf is-unique {
type empty;
description
@@ -1739,6 +1906,9 @@ module frr-zebra {
// End get-pbr-ipset
rpc get-pbr-iptable {
+ description
+ "RPC to retrieve PBR iptables.";
+
input {
leaf name {
type string {
@@ -1751,6 +1921,9 @@ module frr-zebra {
output {
list iptable-list {
+ description
+ "List of iptables entries.";
+
leaf name {
type string {
length "1..32";
@@ -1828,6 +2001,9 @@ module frr-zebra {
}
container dscp-info {
+ description
+ "Container for dscp information.";
+
leaf dscp-value {
type uint32;
description
@@ -1842,6 +2018,9 @@ module frr-zebra {
}
container fragment-info {
+ description
+ "Container for fragment information.";
+
leaf fragment-val {
type uint32;
description
@@ -1856,16 +2035,19 @@ module frr-zebra {
}
container iptable-stats {
+ description
+ "Container for iptables statistics.";
+
leaf packet-counter {
type uint64;
description
- "";
+ "Number of packets processed by iptables.";
}
leaf bytes-counter {
type uint64;
description
- "";
+ "Number of packets processed by iptables.";
}
}
@@ -1894,6 +2076,9 @@ module frr-zebra {
*/
rpc get-debugs {
+ description
+ "RPC to retrieve debug information.";
+
output {
uses zebra-debugs;
}
@@ -1905,6 +2090,9 @@ module frr-zebra {
description
"Extends interface model with Zebra-related parameters.";
container zebra {
+ description
+ "Container for Zebra-related information.";
+
list ipv4-addrs {
key "ip prefix-length";
description
@@ -2079,18 +2267,21 @@ module frr-zebra {
description
"Legacy mode. Only support standard admin-group (RFC3630/5305/5329)";
leaf legacy-admin-group {
- description "Admin-Group value";
type uint32;
+ description "Admin-Group value";
}
}
case affinity {
container affinities {
+ description
+ "Container for affinity information.";
+
leaf-list affinity {
type frr-affinity-map:affinity-map-ref;
- max-elements "256";
must '../../affinity-mode != "standard" or /frr-affinity-map:lib/frr-affinity-map:affinity-maps/frr-affinity-map:affinity-map[frr-affinity-map:name=current()]/frr-affinity-map:value < 32' {
error-message "Affinity bit-position must be less than 32 when used with standard affinity mode";
}
+ max-elements "256";
description
"Array of Attribute Names";
}
@@ -2098,9 +2289,6 @@ module frr-zebra {
}
}
leaf affinity-mode {
- description
- "Affinity mode";
- default "extended";
type enumeration {
enum extended {
value 0;
@@ -2118,9 +2306,11 @@ module frr-zebra {
"Standard and extended Admin-Group";
}
}
+ default "extended";
+ description
+ "Affinity mode";
}
container neighbor {
- description "Remote ASBR information (RFC 5316 & RFC 5392)";
presence "Activates neighbor information on this interface.";
leaf remote-as {
type inet:as-number;
@@ -2134,6 +2324,8 @@ module frr-zebra {
description
"IPv4 Remote ASBR ID (RFC 5316 & RFC 5392)";
}
+ description
+ "Remote ASBR information (RFC 5316 & RFC 5392)";
}
leaf delay {
type uint32 {
@@ -2143,8 +2335,6 @@ module frr-zebra {
"Average Unidirectional Link Delay";
}
container min-max-delay {
- description
- "Min/Max Unidirectional Link Delay";
presence "Activates min/max delay.";
leaf delay-min {
type uint32 {
@@ -2168,6 +2358,8 @@ module frr-zebra {
description
"Max Delay";
}
+ description
+ "Min/Max Unidirectional Link Delay";
}
leaf delay-variation {
type uint32 {
@@ -2192,6 +2384,9 @@ module frr-zebra {
choice esi-choice {
description "ESI type";
container type-0 {
+ description
+ "Container for type-0 information.";
+
leaf esi {
type yang:hex-string {
length "29";
@@ -2201,6 +2396,9 @@ module frr-zebra {
}
}
container type-3 {
+ description
+ "Container for type-3 information.";
+
leaf system-mac {
type yang:mac-address;
description
@@ -2680,6 +2878,8 @@ module frr-zebra {
leaf vni-id {
type vni-id-type;
+ description
+ "A VNI id.";
}
leaf remote-vtep {
@@ -2805,10 +3005,10 @@ module frr-zebra {
}
leaf end {
type uint32;
- mandatory true;
must ". >= ../start" {
error-message "End table must be greater than or equal to start table";
}
+ mandatory true;
description
"The last table to use.";
}
@@ -2832,6 +3032,9 @@ module frr-zebra {
}
augment "/frr-vrf:lib/frr-vrf:vrf/frr-zebra:zebra/ribs/rib/route/route-entry/nexthop-group/nexthop" {
+ description
+ "Augments the nexthop with operational data.";
+
uses frr-nh:frr-nexthop-operational;
}
@@ -2843,10 +3046,10 @@ module frr-zebra {
description
"Data model for the Zebra daemon.";
leaf max-multipath {
- config false;
type uint16 {
range "1..65535";
}
+ config false;
description
"The maximum number of nexthops for a route. At this point it
is unlikely that a multipath number will ever get larger then
@@ -2939,6 +3142,9 @@ module frr-zebra {
* Debug options
*/
container debugs {
+ description
+ "This container contains debug information for the zebra daemon.";
+
uses zebra-debugs;
}
/* End of debugs */
diff --git a/zebra/dplane_fpm_nl.c b/zebra/dplane_fpm_nl.c
index 9f26852d1f..116a697de9 100644
--- a/zebra/dplane_fpm_nl.c
+++ b/zebra/dplane_fpm_nl.c
@@ -587,6 +587,10 @@ static void fpm_read(struct event *t)
struct zebra_dplane_ctx *ctx;
size_t available_bytes;
size_t hdr_available_bytes;
+ struct dplane_ctx_list_head batch_list;
+
+ /* Initialize the batch list */
+ dplane_ctx_q_init(&batch_list);
/* Let's ignore the input at the moment. */
rv = stream_read_try(fnc->ibuf, fnc->socket,
@@ -627,7 +631,7 @@ static void fpm_read(struct event *t)
while (available_bytes) {
if (available_bytes < (ssize_t)FPM_MSG_HDR_LEN) {
stream_pulldown(fnc->ibuf);
- return;
+ goto send_batch;
}
fpm.version = stream_getc(fnc->ibuf);
@@ -642,7 +646,7 @@ static void fpm_read(struct event *t)
__func__, fpm.version, fpm.msg_type);
FPM_RECONNECT(fnc);
- return;
+ goto send_batch;
}
/*
@@ -654,7 +658,7 @@ static void fpm_read(struct event *t)
"%s: Received message length: %u that does not even fill the FPM header",
__func__, fpm.msg_len);
FPM_RECONNECT(fnc);
- return;
+ goto send_batch;
}
/*
@@ -665,7 +669,7 @@ static void fpm_read(struct event *t)
if (fpm.msg_len > available_bytes) {
stream_rewind_getp(fnc->ibuf, FPM_MSG_HDR_LEN);
stream_pulldown(fnc->ibuf);
- return;
+ goto send_batch;
}
available_bytes -= FPM_MSG_HDR_LEN;
@@ -715,8 +719,9 @@ static void fpm_read(struct event *t)
break;
}
- /* Parse the route data into a dplane ctx, then
- * enqueue it to zebra for processing.
+ /*
+ * Parse the route data into a dplane ctx, add to ctx list
+ * and enqueue the batch of ctx to zebra for processing
*/
ctx = dplane_ctx_alloc();
dplane_ctx_route_init(ctx, DPLANE_OP_ROUTE_NOTIFY, NULL,
@@ -735,7 +740,8 @@ static void fpm_read(struct event *t)
* tableid to 0 in order for this to work.
*/
dplane_ctx_set_vrf(ctx, VRF_UNKNOWN);
- dplane_provider_enqueue_to_zebra(ctx);
+ /* Add to the list for batching */
+ dplane_ctx_enqueue_tail(&batch_list, ctx);
} else {
/*
* Let's continue to read other messages
@@ -755,6 +761,15 @@ static void fpm_read(struct event *t)
}
stream_reset(fnc->ibuf);
+
+send_batch:
+ /* Send all contexts to zebra in a single batch if we have any */
+ if (dplane_ctx_queue_count(&batch_list) > 0) {
+ if (IS_ZEBRA_DEBUG_FPM)
+ zlog_debug("%s: Sending batch of %u contexts to zebra", __func__,
+ dplane_ctx_queue_count(&batch_list));
+ dplane_provider_enqueue_ctx_list_to_zebra(&batch_list);
+ }
}
static void fpm_write(struct event *t)
diff --git a/zebra/fpm_listener.c b/zebra/fpm_listener.c
index 70dcaf91a1..73e9dc2482 100644
--- a/zebra/fpm_listener.c
+++ b/zebra/fpm_listener.c
@@ -19,6 +19,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
+#include <signal.h>
#ifdef GNU_LINUX
#include <stdint.h>
@@ -33,13 +34,44 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/if_link.h>
+#include <linux/nexthop.h>
#include "rt_netlink.h"
#include "fpm/fpm.h"
#include "lib/libfrr.h"
+#include "zebra/kernel_netlink.h"
XREF_SETUP();
+PREDECL_RBTREE_UNIQ(fpm_route);
+
+/* Route structure to store in RB tree */
+struct fpm_route {
+ struct prefix prefix;
+ uint32_t table_id;
+ uint32_t nhg_id;
+ struct fpm_route_item rb_item;
+};
+
+/* Comparison function for routes */
+static int fpm_route_cmp(const struct fpm_route *a, const struct fpm_route *b)
+{
+ int ret;
+
+ /* First compare table IDs */
+ if (a->table_id < b->table_id)
+ return -1;
+ if (a->table_id > b->table_id)
+ return 1;
+
+ /* Then compare prefixes */
+ ret = prefix_cmp(&a->prefix, &b->prefix);
+ return ret;
+}
+
+/* RB tree for storing routes */
+DECLARE_RBTREE_UNIQ(fpm_route, struct fpm_route, rb_item, fpm_route_cmp);
+
struct glob {
int server_sock;
int sock;
@@ -47,6 +79,8 @@ struct glob {
bool reflect_fail_all;
bool dump_hex;
FILE *output_file;
+ const char *dump_file;
+ struct fpm_route_head route_tree;
};
struct glob glob_space;
@@ -573,6 +607,67 @@ static int parse_route_msg(struct netlink_msg_ctx *ctx)
}
/*
+ * parse_nexthop_msg
+ */
+static int parse_nexthop_msg(struct nlmsghdr *hdr)
+{
+ struct nhmsg *nhmsg;
+ struct rtattr *tb[NHA_MAX + 1] = {};
+ int len;
+ uint32_t nhgid = 0;
+ uint8_t nhg_count = 0;
+ const char *err_msg = NULL;
+ char protocol_str[32] = "Unknown";
+
+ nhmsg = NLMSG_DATA(hdr);
+ len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*nhmsg));
+ if (len < 0) {
+ fprintf(stderr, "Bad nexthop message length\n");
+ return 0;
+ }
+
+ if (!parse_rtattrs_(RTM_NHA(nhmsg), len, tb, ARRAY_SIZE(tb), &err_msg)) {
+ fprintf(stderr, "Error parsing nexthop attributes: %s\n", err_msg);
+ return 0;
+ }
+
+ /* Get protocol string */
+ snprintf(protocol_str, sizeof(protocol_str), "%s(%u)",
+ netlink_prot_to_s(nhmsg->nh_protocol), nhmsg->nh_protocol);
+
+ /* Get Nexthop Group ID */
+ if (tb[NHA_ID])
+ nhgid = *(uint32_t *)RTA_DATA(tb[NHA_ID]);
+
+ /* Count nexthops in the group */
+ if (tb[NHA_GROUP]) {
+ struct nexthop_grp *nhg = (struct nexthop_grp *)RTA_DATA(tb[NHA_GROUP]);
+ size_t count = (RTA_PAYLOAD(tb[NHA_GROUP]) / sizeof(*nhg));
+
+ if (count > 0 && (count * sizeof(*nhg)) == RTA_PAYLOAD(tb[NHA_GROUP]))
+ nhg_count = count;
+ } else if (tb[NHA_OIF] || tb[NHA_GATEWAY]) {
+ /* Single nexthop case */
+ nhg_count = 1;
+ }
+
+ /* Print blackhole status if applicable */
+ if (tb[NHA_BLACKHOLE]) {
+ fprintf(glob->output_file,
+ "[%s] %s Nexthop Group ID: %u, Protocol: %s, Type: BLACKHOLE, Family: %u\n",
+ get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid,
+ protocol_str, nhmsg->nh_family);
+ } else {
+ fprintf(glob->output_file,
+ "[%s] %s Nexthop Group ID: %u, Protocol: %s, Contains %u nexthops, Family: %u, Scope: %u\n",
+ get_timestamp(), hdr->nlmsg_type == RTM_NEWNEXTHOP ? "New" : "Del", nhgid,
+ protocol_str, nhg_count, nhmsg->nh_family, nhmsg->nh_scope);
+ }
+
+ return 1;
+}
+
+/*
* addr_to_s
*/
static const char *
@@ -695,6 +790,64 @@ static void fpm_listener_hexdump(const void *mem, size_t len)
}
/*
+ * handle_route_update
+ * Handles adding or removing a route from the route tree
+ */
+static void handle_route_update(struct netlink_msg_ctx *ctx, bool is_add)
+{
+ struct fpm_route *route;
+ struct fpm_route *existing;
+ struct fpm_route lookup = { 0 };
+
+ if (!ctx->dest || !ctx->rtmsg)
+ return;
+
+ /* Set up lookup key */
+ lookup.prefix.family = ctx->rtmsg->rtm_family;
+ lookup.prefix.prefixlen = ctx->rtmsg->rtm_dst_len;
+ memcpy(&lookup.prefix.u.prefix, RTA_DATA(ctx->dest),
+ (ctx->rtmsg->rtm_family == AF_INET) ? 4 : 16);
+ lookup.table_id = ctx->rtmsg->rtm_table;
+ lookup.nhg_id = ctx->nhgid ? *ctx->nhgid : 0;
+ /* Look up existing route */
+ existing = fpm_route_find(&glob->route_tree, &lookup);
+
+ if (is_add) {
+ if (existing) {
+ /* Route exists, update it */
+ existing->prefix = lookup.prefix;
+ existing->table_id = lookup.table_id;
+ existing->nhg_id = lookup.nhg_id;
+ } else {
+ /* Create new route structure */
+ route = calloc(1, sizeof(struct fpm_route));
+ if (!route) {
+ fprintf(stderr, "Failed to allocate route structure\n");
+ return;
+ }
+
+ /* Copy prefix information */
+ route->prefix = lookup.prefix;
+ route->table_id = lookup.table_id;
+ route->nhg_id = lookup.nhg_id;
+
+ /* Add route to tree */
+ if (fpm_route_add(&glob->route_tree, route)) {
+ fprintf(stderr, "Failed to add route to tree\n");
+ free(route);
+ }
+ }
+ } else {
+ /* Remove route from tree */
+ if (existing) {
+ existing = fpm_route_del(&glob->route_tree, existing);
+ if (existing)
+ free(existing);
+ }
+ }
+}
+
+/*
* parse_netlink_msg
*/
static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
@@ -726,6 +879,7 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
}
print_netlink_msg_ctx(ctx);
+ handle_route_update(ctx, hdr->nlmsg_type == RTM_NEWROUTE);
if (glob->reflect && hdr->nlmsg_type == RTM_NEWROUTE &&
ctx->rtmsg->rtm_protocol > RTPROT_STATIC) {
@@ -742,6 +896,11 @@ static void parse_netlink_msg(char *buf, size_t buf_len, fpm_msg_hdr_t *fpm)
}
break;
+ case RTM_NEWNEXTHOP:
+ case RTM_DELNEXTHOP:
+ parse_nexthop_msg(hdr);
+ break;
+
default:
fprintf(glob->output_file, "[%s] Ignoring netlink message - Type: %s(%d)\n",
get_timestamp(), netlink_msg_type_to_s(hdr->nlmsg_type),
@@ -786,17 +945,62 @@ static void fpm_serve(void)
}
}
+/* Signal handler for SIGUSR1 */
+static void sigusr1_handler(int signum)
+{
+ struct fpm_route *route;
+ char buf[PREFIX_STRLEN];
+ FILE *out = glob->output_file;
+ FILE *dump_fp = NULL;
+
+ if (glob->dump_file) {
+ dump_fp = fopen(glob->dump_file, "w");
+ if (dump_fp) {
+ out = dump_fp;
+ setbuf(dump_fp, NULL);
+ } else
+ out = glob->output_file;
+ }
+
+ fprintf(out, "\n=== Route Tree Dump ===\n");
+ fprintf(out, "Timestamp: %s\n", get_timestamp());
+ fprintf(out, "Total routes: %zu\n", fpm_route_count(&glob->route_tree));
+ fprintf(out, "Routes:\n");
+
+ frr_each (fpm_route, &glob->route_tree, route) {
+ prefix2str(&route->prefix, buf, sizeof(buf));
+ fprintf(out, " Table %u, NHG %u: %s\n", route->table_id, route->nhg_id, buf);
+ }
+ fprintf(out, "=====================\n\n");
+ fflush(out);
+
+ if (dump_fp)
+ fclose(dump_fp);
+}
+
int main(int argc, char **argv)
{
pid_t daemon;
int r;
bool fork_daemon = false;
const char *output_file = NULL;
+ struct sigaction sa;
memset(glob, 0, sizeof(*glob));
glob->output_file = stdout;
+ fpm_route_init(&glob->route_tree);
+
+ /* Set up signal handler for SIGUSR1 */
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = sigusr1_handler;
+ sigemptyset(&sa.sa_mask);
+ sa.sa_flags = SA_RESTART;
+ if (sigaction(SIGUSR1, &sa, NULL) < 0) {
+ fprintf(stderr, "Failed to set up SIGUSR1 handler: %s\n", strerror(errno));
+ exit(1);
+ }
- while ((r = getopt(argc, argv, "rfdvo:")) != -1) {
+ while ((r = getopt(argc, argv, "rfdvo:z:")) != -1) {
switch (r) {
case 'r':
glob->reflect = true;
@@ -813,6 +1017,9 @@ int main(int argc, char **argv)
case 'o':
output_file = optarg;
break;
+ case 'z':
+ glob->dump_file = optarg;
+ break;
}
}
diff --git a/zebra/interface.c b/zebra/interface.c
index fd1ea380a5..f836b3ab35 100644
--- a/zebra/interface.c
+++ b/zebra/interface.c
@@ -1919,8 +1919,7 @@ static void zebra_if_dplane_ifp_handling(struct zebra_dplane_ctx *ctx)
if (zif_type == ZEBRA_IF_VRF && !vrf_is_backend_netns())
interface_vrf_change(op, ifindex, name, tableid, ns_id);
} else {
- ifindex_t master_ifindex, bridge_ifindex, bond_ifindex,
- link_ifindex;
+ ifindex_t master_ifindex, bridge_ifindex, link_ifindex;
enum zebra_slave_iftype zif_slave_type;
uint8_t bypass;
uint64_t flags;
@@ -2730,14 +2729,14 @@ static void if_dump_vty(struct vty *vty, struct interface *ifp)
}
if (gre_info->ifindex_link &&
(gre_info->link_nsid != NS_UNKNOWN)) {
- struct interface *ifp;
+ struct interface *nifp;
- ifp = if_lookup_by_index_per_ns(
- zebra_ns_lookup(gre_info->link_nsid),
- gre_info->ifindex_link);
+ nifp = if_lookup_by_index_per_ns(
+ zebra_ns_lookup(gre_info->link_nsid),
+ gre_info->ifindex_link);
vty_out(vty, " Link Interface %s\n",
- ifp == NULL ? "Unknown" :
- ifp->name);
+ nifp == NULL ? "Unknown" :
+ nifp->name);
}
}
@@ -3116,14 +3115,13 @@ static void if_dump_vty_json(struct vty *vty, struct interface *ifp,
}
if (gre_info->ifindex_link
&& (gre_info->link_nsid != NS_UNKNOWN)) {
- struct interface *ifp;
+ struct interface *nifp;
- ifp = if_lookup_by_index_per_ns(
+ nifp = if_lookup_by_index_per_ns(
zebra_ns_lookup(gre_info->link_nsid),
gre_info->ifindex_link);
json_object_string_add(json_if, "linkInterface",
- ifp == NULL ? "Unknown"
- : ifp->name);
+ nifp == NULL ? "Unknown" : nifp->name);
}
}
diff --git a/zebra/irdp_packet.c b/zebra/irdp_packet.c
index 2dfc027f1d..a0ce919e91 100644
--- a/zebra/irdp_packet.c
+++ b/zebra/irdp_packet.c
@@ -217,11 +217,11 @@ void irdp_read_raw(struct event *r)
char buf[IRDP_RX_BUF];
int ret, ifindex = 0;
- int irdp_sock = EVENT_FD(r);
- event_add_read(zrouter.master, irdp_read_raw, NULL, irdp_sock,
+ int irdp_socket = EVENT_FD(r);
+ event_add_read(zrouter.master, irdp_read_raw, NULL, irdp_socket,
&t_irdp_raw);
- ret = irdp_recvmsg(irdp_sock, (uint8_t *)buf, IRDP_RX_BUF, &ifindex);
+ ret = irdp_recvmsg(irdp_socket, (uint8_t *)buf, IRDP_RX_BUF, &ifindex);
if (ret < 0)
flog_warn(EC_LIB_SOCKET, "IRDP: RX Error length = %d", ret);
diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c
index 4789cb62f2..8a6bfc45e0 100644
--- a/zebra/kernel_socket.c
+++ b/zebra/kernel_socket.c
@@ -1054,7 +1054,7 @@ void rtm_read(struct rt_msghdr *rtm)
/*
* Ignore our own messages.
*/
- if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == pid)
+ if (rtm->rtm_type != RTM_GET && rtm->rtm_pid == zebra_pid)
return;
if (dest.sa.sa_family == AF_INET) {
diff --git a/zebra/main.c b/zebra/main.c
index 5c169bb839..b23307458b 100644
--- a/zebra/main.c
+++ b/zebra/main.c
@@ -57,7 +57,7 @@
char *zserv_path;
/* process id. */
-pid_t pid;
+pid_t zebra_pid;
/* Pacify zclient.o in libfrr, which expects this variable. */
struct event_loop *master;
@@ -247,6 +247,8 @@ void zebra_finalize(struct event *dummy)
label_manager_terminate();
+ affinity_map_terminate();
+
ns_walk_func(zebra_ns_final_shutdown, NULL, NULL);
ns_terminate();
@@ -518,7 +520,7 @@ int main(int argc, char **argv)
*/
/* Needed for BSD routing socket. */
- pid = getpid();
+ zebra_pid = getpid();
/* Start dataplane system */
zebra_dplane_start();
diff --git a/zebra/rib.h b/zebra/rib.h
index 8484fe1291..fa6ce4447b 100644
--- a/zebra/rib.h
+++ b/zebra/rib.h
@@ -192,6 +192,12 @@ struct route_entry {
struct meta_queue {
struct list *subq[MQ_SIZE];
uint32_t size; /* sum of lengths of all subqueues */
+ _Atomic uint32_t max_subq[MQ_SIZE]; /* Max size of individual sub queue */
+ _Atomic uint32_t max_metaq; /* Max size of the MetaQ */
+ _Atomic uint32_t total_subq[MQ_SIZE]; /* Total subq events */
+ _Atomic uint32_t total_metaq; /* Total MetaQ events */
+ _Atomic uint32_t re_subq[MQ_SIZE]; /* current RE count sub queue */
+ _Atomic uint32_t max_re_subq[MQ_SIZE]; /* Max RE in sub queue */
};
/*
@@ -462,6 +468,8 @@ extern void meta_queue_free(struct meta_queue *mq, struct zebra_vrf *zvrf);
extern int zebra_rib_labeled_unicast(struct route_entry *re);
extern struct route_table *rib_table_ipv6;
+extern uint32_t zebra_rib_meta_queue_size(void);
+
extern void rib_unlink(struct route_node *rn, struct route_entry *re);
extern int rib_gc_dest(struct route_node *rn);
extern struct route_table *rib_tables_iter_next(rib_tables_iter_t *iter);
@@ -472,6 +480,7 @@ extern void zebra_rib_evaluate_rn_nexthops(struct route_node *rn, uint32_t seq,
bool rt_delete);
extern void rib_update_handle_vrf_all(enum rib_update_event event, int rtype);
+int zebra_show_metaq_counter(struct vty *vty, bool uj);
/*
* rib_find_rn_from_ctx
@@ -626,7 +635,7 @@ extern int rib_add_gr_run(afi_t afi, vrf_id_t vrf_id, uint8_t proto,
extern void zebra_vty_init(void);
extern uint32_t zebra_rib_dplane_results_count(void);
-extern pid_t pid;
+extern pid_t zebra_pid;
extern uint32_t rt_table_main_id;
diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c
index 9a60e32b65..a2e7997ab4 100644
--- a/zebra/rt_netlink.c
+++ b/zebra/rt_netlink.c
@@ -3139,13 +3139,11 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
if (nh->nh_srv6->seg6local_action !=
ZEBRA_SEG6_LOCAL_ACTION_UNSPEC) {
uint32_t action;
- uint16_t encap;
- struct rtattr *nest;
- const struct seg6local_context *ctx;
+ const struct seg6local_context *ctx6;
req->nhm.nh_family = AF_INET6;
action = nh->nh_srv6->seg6local_action;
- ctx = &nh->nh_srv6->seg6local_ctx;
+ ctx6 = &nh->nh_srv6->seg6local_ctx;
encap = LWTUNNEL_ENCAP_SEG6_LOCAL;
if (!nl_attr_put(&req->n, buflen,
NHA_ENCAP_TYPE,
@@ -3174,7 +3172,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
return 0;
if (!nl_attr_put(
&req->n, buflen,
- SEG6_LOCAL_NH6, &ctx->nh6,
+ SEG6_LOCAL_NH6, &ctx6->nh6,
sizeof(struct in6_addr)))
return 0;
break;
@@ -3187,7 +3185,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_TABLE,
- ctx->table))
+ ctx6->table))
return 0;
break;
case SEG6_LOCAL_ACTION_END_DX4:
@@ -3198,7 +3196,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
return 0;
if (!nl_attr_put(
&req->n, buflen,
- SEG6_LOCAL_NH4, &ctx->nh4,
+ SEG6_LOCAL_NH4, &ctx6->nh4,
sizeof(struct in_addr)))
return 0;
break;
@@ -3210,7 +3208,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
return 0;
if (!nl_attr_put(&req->n, buflen,
SEG6_LOCAL_NH6,
- &ctx->nh6,
+ &ctx6->nh6,
sizeof(struct in6_addr)))
return 0;
break;
@@ -3223,7 +3221,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_TABLE,
- ctx->table))
+ ctx6->table))
return 0;
break;
case SEG6_LOCAL_ACTION_END_DT4:
@@ -3235,7 +3233,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_VRFTABLE,
- ctx->table))
+ ctx6->table))
return 0;
break;
case SEG6_LOCAL_ACTION_END_DT46:
@@ -3247,7 +3245,7 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
if (!nl_attr_put32(
&req->n, buflen,
SEG6_LOCAL_VRFTABLE,
- ctx->table))
+ ctx6->table))
return 0;
break;
default:
@@ -3268,7 +3266,6 @@ ssize_t netlink_nexthop_msg_encode(uint16_t cmd,
!sid_zero(nh->nh_srv6->seg6_segs)) {
char tun_buf[4096];
ssize_t tun_len;
- struct rtattr *nest;
if (!nl_attr_put16(&req->n, buflen,
NHA_ENCAP_TYPE,
diff --git a/zebra/rtadv.c b/zebra/rtadv.c
index a767bda72e..ce3f0320f5 100644
--- a/zebra/rtadv.c
+++ b/zebra/rtadv.c
@@ -1602,8 +1602,6 @@ DEFPY(show_ipv6_nd_ra_if, show_ipv6_nd_ra_if_cmd,
struct vrf *vrf;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- struct zebra_vrf *zvrf;
-
zvrf = vrf->info;
if (!zvrf)
continue;
diff --git a/zebra/zapi_msg.c b/zebra/zapi_msg.c
index d4e65eb18c..fc78f87eb1 100644
--- a/zebra/zapi_msg.c
+++ b/zebra/zapi_msg.c
@@ -3872,12 +3872,13 @@ static inline void zebra_neigh_ip_del(ZAPI_HANDLER_ARGS)
static inline void zread_iptable(ZAPI_HANDLER_ARGS)
{
struct zebra_pbr_iptable *zpi =
- XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable));
+ XCALLOC(MTYPE_PBR_IPTABLE, sizeof(struct zebra_pbr_iptable));
struct stream *s;
s = msg;
zpi->interface_name_list = list_new();
+ zpi->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free;
zpi->sock = client->sock;
zpi->vrf_id = zvrf->vrf->vrf_id;
STREAM_GETL(s, zpi->unique);
diff --git a/zebra/zebra_dplane.c b/zebra/zebra_dplane.c
index 4344a8d79a..a6d43daa93 100644
--- a/zebra/zebra_dplane.c
+++ b/zebra/zebra_dplane.c
@@ -6590,6 +6590,14 @@ int dplane_provider_work_ready(void)
}
/*
+ * Enqueue a context list to zebra main.
+ */
+void dplane_provider_enqueue_ctx_list_to_zebra(struct dplane_ctx_list_head *batch_list)
+{
+ (zdplane_info.dg_results_cb)(batch_list);
+}
+
+/*
* Enqueue a context directly to zebra main.
*/
void dplane_provider_enqueue_to_zebra(struct zebra_dplane_ctx *ctx)
diff --git a/zebra/zebra_dplane.h b/zebra/zebra_dplane.h
index cabc70c232..1c03a29534 100644
--- a/zebra/zebra_dplane.h
+++ b/zebra/zebra_dplane.h
@@ -1236,6 +1236,9 @@ 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);
+/* Enqueue a context list to zebra main. */
+void dplane_provider_enqueue_ctx_list_to_zebra(struct dplane_ctx_list_head *batch_list);
+
/* 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.
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index 95207ce75c..34c936155a 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -261,7 +261,7 @@ static int netlink_route_info_fill(struct netlink_route_info *ri, int cmd,
ri->prefix = rib_dest_prefix(dest);
ri->af = rib_dest_af(dest);
- ri->nlmsg_pid = pid;
+ ri->nlmsg_pid = zebra_pid;
ri->nlmsg_type = cmd;
ri->rtm_protocol = RTPROT_UNSPEC;
diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c
index 589196ecb9..a033b3ea50 100644
--- a/zebra/zebra_nhg.c
+++ b/zebra/zebra_nhg.c
@@ -1161,11 +1161,32 @@ static void zebra_nhg_handle_uninstall(struct nhg_hash_entry *nhe)
zebra_nhg_free(nhe);
}
+static void nhg_handle_install_one(struct nhg_connected *node)
+{
+ struct nhg_connected *rb_node_indirect_dep = NULL;
+
+ frr_each_safe (nhg_connected_tree, &node->nhe->nhg_dependents,
+ rb_node_indirect_dep) {
+ SET_FLAG(rb_node_indirect_dep->nhe->flags,
+ NEXTHOP_GROUP_REINSTALL);
+
+ if (IS_ZEBRA_DEBUG_NHG_DETAIL)
+ zlog_debug("%s nh id %u (flags 0x%x) associated dependents NHG %pNG (flags 0x%x) Re-install",
+ __func__, node->nhe->id,
+ node->nhe->flags,
+ rb_node_indirect_dep->nhe,
+ rb_node_indirect_dep->nhe->flags);
+
+ zebra_nhg_install_kernel(rb_node_indirect_dep->nhe,
+ ZEBRA_ROUTE_MAX);
+ }
+
+}
+
static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install)
{
/* Update validity of groups depending on it */
struct nhg_connected *rb_node_dep;
- struct nhg_connected *rb_node_indirect_dep = NULL;
frr_each_safe (nhg_connected_tree, &nhe->nhg_dependents, rb_node_dep) {
zebra_nhg_set_valid(rb_node_dep->nhe, true);
@@ -1173,19 +1194,7 @@ static void zebra_nhg_handle_install(struct nhg_hash_entry *nhe, bool install)
if (install) {
if (CHECK_FLAG(nhe->flags, NEXTHOP_GROUP_INSTALLED) &&
CHECK_FLAG(rb_node_dep->nhe->flags, NEXTHOP_GROUP_RECURSIVE)) {
- frr_each_safe (nhg_connected_tree, &rb_node_dep->nhe->nhg_dependents,
- rb_node_indirect_dep) {
- SET_FLAG(rb_node_indirect_dep->nhe->flags,
- NEXTHOP_GROUP_REINSTALL);
- if (IS_ZEBRA_DEBUG_NHG_DETAIL)
- zlog_debug("%s nh id %u (flags 0x%x) associated dependents NHG %pNG (flags 0x%x) Re-install",
- __func__, rb_node_dep->nhe->id,
- rb_node_dep->nhe->flags,
- rb_node_indirect_dep->nhe,
- rb_node_indirect_dep->nhe->flags);
- zebra_nhg_install_kernel(rb_node_indirect_dep->nhe,
- ZEBRA_ROUTE_MAX);
- }
+ nhg_handle_install_one(rb_node_dep);
}
if (IS_ZEBRA_DEBUG_NHG_DETAIL)
diff --git a/zebra/zebra_pbr.c b/zebra/zebra_pbr.c
index 7f3635702f..49846a00c8 100644
--- a/zebra/zebra_pbr.c
+++ b/zebra/zebra_pbr.c
@@ -23,7 +23,11 @@
/* definitions */
DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPTABLE_IFNAME, "PBR interface list");
-DEFINE_MTYPE(ZEBRA, PBR_OBJ, "PBR");
+DEFINE_MTYPE_STATIC(ZEBRA, PBR_RULE, "PBR rule");
+DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPSET, "PBR ipset");
+DEFINE_MTYPE_STATIC(ZEBRA, PBR_IPSET_ENTRY, "PBR ipset entry");
+DEFINE_MTYPE(ZEBRA, PBR_IPTABLE, "PBR iptable");
+
/* definitions */
static const struct message ipset_type_msg[] = {
@@ -151,7 +155,7 @@ void zebra_pbr_rules_free(void *arg)
rule = (struct zebra_pbr_rule *)arg;
(void)dplane_pbr_rule_delete(rule);
- XFREE(MTYPE_PBR_OBJ, rule);
+ XFREE(MTYPE_PBR_RULE, rule);
}
uint32_t zebra_pbr_rules_hash_key(const void *arg)
@@ -274,7 +278,7 @@ void zebra_pbr_ipset_free(void *arg)
ipset = (struct zebra_pbr_ipset *)arg;
hook_call(zebra_pbr_ipset_update, 0, ipset);
- XFREE(MTYPE_PBR_OBJ, ipset);
+ XFREE(MTYPE_PBR_IPSET, ipset);
}
uint32_t zebra_pbr_ipset_hash_key(const void *arg)
@@ -318,7 +322,7 @@ void zebra_pbr_ipset_entry_free(void *arg)
hook_call(zebra_pbr_ipset_entry_update, 0, ipset);
- XFREE(MTYPE_PBR_OBJ, ipset);
+ XFREE(MTYPE_PBR_IPSET_ENTRY, ipset);
}
uint32_t zebra_pbr_ipset_entry_hash_key(const void *arg)
@@ -379,23 +383,16 @@ bool zebra_pbr_ipset_entry_hash_equal(const void *arg1, const void *arg2)
static void _zebra_pbr_iptable_free_all(void *arg, bool all)
{
struct zebra_pbr_iptable *iptable;
- struct listnode *node, *nnode;
- char *name;
iptable = (struct zebra_pbr_iptable *)arg;
if (all)
hook_call(zebra_pbr_iptable_update, 0, iptable);
- if (iptable->interface_name_list) {
- for (ALL_LIST_ELEMENTS(iptable->interface_name_list, node,
- nnode, name)) {
- XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
- list_delete_node(iptable->interface_name_list, node);
- }
+ if (iptable->interface_name_list)
list_delete(&iptable->interface_name_list);
- }
- XFREE(MTYPE_PBR_OBJ, iptable);
+
+ XFREE(MTYPE_PBR_IPTABLE, iptable);
}
void zebra_pbr_iptable_free(void *arg)
@@ -477,7 +474,7 @@ static void *pbr_rule_alloc_intern(void *arg)
zpr = (struct zebra_pbr_rule *)arg;
- new = XCALLOC(MTYPE_PBR_OBJ, sizeof(*new));
+ new = XCALLOC(MTYPE_PBR_RULE, sizeof(*new));
memcpy(new, zpr, sizeof(*zpr));
@@ -491,7 +488,7 @@ static struct zebra_pbr_rule *pbr_rule_free(struct zebra_pbr_rule *hash_data,
zebra_neigh_deref(hash_data);
hash_release(zrouter.rules_hash, hash_data);
if (free_data) {
- XFREE(MTYPE_PBR_OBJ, hash_data);
+ XFREE(MTYPE_PBR_RULE, hash_data);
return NULL;
}
@@ -729,7 +726,7 @@ void zebra_pbr_add_rule(struct zebra_pbr_rule *rule)
(void)dplane_pbr_rule_update(found, new);
/* release the old hash data */
if (old)
- XFREE(MTYPE_PBR_OBJ, old);
+ XFREE(MTYPE_PBR_RULE, old);
} else {
if (IS_ZEBRA_DEBUG_PBR)
zlog_debug(
@@ -897,7 +894,7 @@ static void *pbr_ipset_alloc_intern(void *arg)
zpi = (struct zebra_pbr_ipset *)arg;
- new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_ipset));
+ new = XCALLOC(MTYPE_PBR_IPSET, sizeof(struct zebra_pbr_ipset));
memcpy(new, zpi, sizeof(*zpi));
@@ -918,7 +915,7 @@ void zebra_pbr_destroy_ipset(struct zebra_pbr_ipset *ipset)
(void)dplane_pbr_ipset_delete(ipset);
if (lookup) {
hash_release(zrouter.ipset_hash, lookup);
- XFREE(MTYPE_PBR_OBJ, lookup);
+ XFREE(MTYPE_PBR_IPSET, lookup);
} else
zlog_debug(
"%s: IPSet Entry being deleted we know nothing about",
@@ -971,7 +968,7 @@ static void *pbr_ipset_entry_alloc_intern(void *arg)
zpi = (struct zebra_pbr_ipset_entry *)arg;
- new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_ipset_entry));
+ new = XCALLOC(MTYPE_PBR_IPSET_ENTRY, sizeof(struct zebra_pbr_ipset_entry));
memcpy(new, zpi, sizeof(*zpi));
@@ -993,12 +990,19 @@ void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset)
(void)dplane_pbr_ipset_entry_delete(ipset);
if (lookup) {
hash_release(zrouter.ipset_entry_hash, lookup);
- XFREE(MTYPE_PBR_OBJ, lookup);
+ XFREE(MTYPE_PBR_IPSET_ENTRY, lookup);
} else
zlog_debug("%s: IPSet being deleted we know nothing about",
__func__);
}
+void zebra_pbr_iptable_interface_name_list_free(void *arg)
+{
+ char *name = arg;
+
+ XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
+}
+
static void *pbr_iptable_alloc_intern(void *arg)
{
struct zebra_pbr_iptable *zpi;
@@ -1008,11 +1012,12 @@ static void *pbr_iptable_alloc_intern(void *arg)
zpi = (struct zebra_pbr_iptable *)arg;
- new = XCALLOC(MTYPE_PBR_OBJ, sizeof(struct zebra_pbr_iptable));
+ new = XCALLOC(MTYPE_PBR_IPTABLE, sizeof(struct zebra_pbr_iptable));
/* Deep structure copy */
memcpy(new, zpi, sizeof(*zpi));
new->interface_name_list = list_new();
+ new->interface_name_list->del = zebra_pbr_iptable_interface_name_list_free;
if (zpi->interface_name_list) {
for (ALL_LIST_ELEMENTS_RO(zpi->interface_name_list, ln, ifname))
@@ -1039,18 +1044,9 @@ void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable)
lookup = hash_lookup(zrouter.iptable_hash, iptable);
(void)dplane_pbr_iptable_delete(iptable);
if (lookup) {
- struct listnode *node, *nnode;
- char *name;
-
hash_release(zrouter.iptable_hash, lookup);
- for (ALL_LIST_ELEMENTS(iptable->interface_name_list,
- node, nnode, name)) {
- XFREE(MTYPE_PBR_IPTABLE_IFNAME, name);
- list_delete_node(iptable->interface_name_list,
- node);
- }
- list_delete(&iptable->interface_name_list);
- XFREE(MTYPE_PBR_OBJ, lookup);
+ list_delete(&lookup->interface_name_list);
+ XFREE(MTYPE_PBR_IPTABLE, lookup);
} else
zlog_debug("%s: IPTable being deleted we know nothing about",
__func__);
diff --git a/zebra/zebra_pbr.h b/zebra/zebra_pbr.h
index 1e4b5cd0f3..25868a6c1e 100644
--- a/zebra/zebra_pbr.h
+++ b/zebra/zebra_pbr.h
@@ -21,7 +21,8 @@ extern "C" {
#endif
/* Memory type for PBR objects. */
-DECLARE_MTYPE(PBR_OBJ);
+DECLARE_MTYPE(PBR_IPTABLE);
+
struct zebra_pbr_action {
afi_t afi;
@@ -195,6 +196,8 @@ struct zebra_pbr_ipset *zebra_pbr_lookup_ipset_pername(char *ipsetname);
void zebra_pbr_add_ipset_entry(struct zebra_pbr_ipset_entry *ipset);
void zebra_pbr_del_ipset_entry(struct zebra_pbr_ipset_entry *ipset);
+void zebra_pbr_iptable_interface_name_list_free(void *arg);
+
void zebra_pbr_add_iptable(struct zebra_pbr_iptable *iptable);
void zebra_pbr_del_iptable(struct zebra_pbr_iptable *iptable);
void zebra_pbr_process_iptable(struct zebra_dplane_ctx *ctx);
diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c
index 20ec25a431..c7dc5e5d07 100644
--- a/zebra/zebra_rib.c
+++ b/zebra/zebra_rib.c
@@ -30,6 +30,7 @@
#include "printfrr.h"
#include "frrscript.h"
#include "frrdistance.h"
+#include "lib/termtable.h"
#include "zebra/zebra_router.h"
#include "zebra/connected.h"
@@ -273,6 +274,63 @@ static const char *subqueue2str(enum meta_queue_indexes index)
return "Unknown";
}
+/* Handler for 'show zebra metaq' */
+int zebra_show_metaq_counter(struct vty *vty, bool uj)
+{
+ struct meta_queue *mq = zrouter.mq;
+ struct ttable *tt = NULL;
+ char *table = NULL;
+ json_object *json = NULL;
+ json_object *json_table = NULL;
+
+ if (!mq)
+ return CMD_WARNING;
+
+ /* Create a table for subqueue details */
+ tt = ttable_new(&ttable_styles[TTSTYLE_ASCII]);
+ ttable_add_row(tt, "SubQ|Current|Max Size|Total");
+
+ /* Add rows for each subqueue */
+ for (uint8_t i = 0; i < MQ_SIZE; i++) {
+ ttable_add_row(tt, "%s|%u|%u|%u", subqueue2str(i), mq->subq[i]->count,
+ mq->max_subq[i], mq->total_subq[i]);
+ }
+
+ /* For a better formatting between the content and separator */
+ tt->style.cell.rpad = 2;
+ tt->style.cell.lpad = 1;
+ ttable_restyle(tt);
+
+ if (uj) {
+ json = json_object_new_object();
+ /* Add MetaQ summary to the JSON object */
+ json_object_int_add(json, "currentSize", mq->size);
+ json_object_int_add(json, "maxSize", mq->max_metaq);
+ json_object_int_add(json, "total", mq->total_metaq);
+
+ /* Convert the table to JSON and add it to the main JSON object */
+ /* n = name/string, u = unsigned int */
+ json_table = ttable_json(tt, "sddd");
+ json_object_object_add(json, "subqueues", json_table);
+ vty_json(vty, json);
+ } else {
+ vty_out(vty, "MetaQ Summary\n");
+ vty_out(vty, "Current Size\t: %u\n", mq->size);
+ vty_out(vty, "Max Size\t: %u\n", mq->max_metaq);
+ vty_out(vty, "Total\t\t: %u\n", mq->total_metaq);
+
+ /* Dump the table */
+ table = ttable_dump(tt, "\n");
+ vty_out(vty, "%s\n", table);
+ XFREE(MTYPE_TMP_TTABLE, table);
+ }
+
+ /* Clean up the table */
+ ttable_del(tt);
+
+ return CMD_SUCCESS;
+}
+
printfrr_ext_autoreg_p("ZN", printfrr_zebra_node);
static ssize_t printfrr_zebra_node(struct fbuf *buf, struct printfrr_eargs *ea,
const void *ptr)
@@ -317,9 +375,9 @@ static ssize_t printfrr_zebra_node(struct fbuf *buf, struct printfrr_eargs *ea,
#define rnode_debug(node, vrf_id, msg, ...) \
do { \
- struct vrf *vrf = vrf_lookup_by_id(vrf_id); \
+ struct vrf *_vrf = vrf_lookup_by_id(vrf_id); \
zlog_debug("%s: (%s:%pZNt):%pZN: " msg, __func__, \
- VRF_LOGNAME(vrf), node, node, ##__VA_ARGS__); \
+ VRF_LOGNAME(_vrf), node, node, ##__VA_ARGS__); \
} while (0)
#define rnode_info(node, vrf_id, msg, ...) \
@@ -1225,10 +1283,10 @@ static void rib_process(struct route_node *rn)
* will not iterate so we are ok.
*/
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
- struct route_entry *re = re_list_first(&dest->routes);
+ struct route_entry *rent = re_list_first(&dest->routes);
zlog_debug("%s(%u:%u:%u):%pRN: Processing rn %p", VRF_LOGNAME(vrf), vrf_id,
- re->table, safi, rn, rn);
+ rent->table, safi, rn, rn);
}
old_fib = dest->selected_fib;
@@ -3257,6 +3315,7 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
struct route_node *rn = NULL;
struct route_entry *re = NULL, *curr_re = NULL;
uint8_t qindex = MQ_SIZE, curr_qindex = MQ_SIZE;
+ uint64_t curr, high;
rn = (struct route_node *)data;
@@ -3300,18 +3359,40 @@ static int rib_meta_queue_add(struct meta_queue *mq, void *data)
listnode_add(mq->subq[qindex], rn);
route_lock_node(rn);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[qindex]);
+ high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- rnode_debug(rn, re->vrf_id, "queued rn %p into sub-queue %s",
- (void *)rn, subqueue2str(qindex));
+ rnode_debug(rn, re->vrf_id, "queued rn %p into sub-queue %s mq size %u", (void *)rn,
+ subqueue2str(qindex), zrouter.mq->size);
return 0;
}
static int early_label_meta_queue_add(struct meta_queue *mq, void *data)
{
+ uint64_t curr, high;
+
listnode_add(mq->subq[META_QUEUE_EARLY_LABEL], data);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EARLY_LABEL], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[META_QUEUE_EARLY_LABEL]);
+ high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EARLY_LABEL], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[META_QUEUE_EARLY_LABEL], curr,
+ memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
+
return 0;
}
@@ -3320,6 +3401,7 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
struct nhg_ctx *ctx = NULL;
uint8_t qindex = META_QUEUE_NHG;
struct wq_nhg_wrapper *w;
+ uint64_t curr, high;
ctx = (struct nhg_ctx *)data;
@@ -3333,10 +3415,19 @@ static int rib_meta_queue_nhg_ctx_add(struct meta_queue *mq, void *data)
listnode_add(mq->subq[qindex], w);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[qindex]);
+ high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("NHG Context id=%u queued into sub-queue %s",
- ctx->id, subqueue2str(qindex));
+ zlog_debug("NHG Context id=%u queued into sub-queue %s mq size %u", ctx->id,
+ subqueue2str(qindex), zrouter.mq->size);
return 0;
}
@@ -3347,6 +3438,7 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data,
struct nhg_hash_entry *nhe = NULL;
uint8_t qindex = META_QUEUE_NHG;
struct wq_nhg_wrapper *w;
+ uint64_t curr, high;
nhe = (struct nhg_hash_entry *)data;
@@ -3361,10 +3453,19 @@ static int rib_meta_queue_nhg_process(struct meta_queue *mq, void *data,
listnode_add(mq->subq[qindex], w);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[qindex], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[qindex]);
+ high = atomic_load_explicit(&mq->max_subq[qindex], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[qindex], curr, memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("NHG id=%u queued into sub-queue %s", nhe->id,
- subqueue2str(qindex));
+ zlog_debug("NHG id=%u queued into sub-queue %s mq size %u", nhe->id,
+ subqueue2str(qindex), zrouter.mq->size);
return 0;
}
@@ -3381,8 +3482,19 @@ static int rib_meta_queue_nhg_del(struct meta_queue *mq, void *data)
static int rib_meta_queue_evpn_add(struct meta_queue *mq, void *data)
{
+ uint64_t curr, high;
+
listnode_add(mq->subq[META_QUEUE_EVPN], data);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EVPN], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[META_QUEUE_EVPN]);
+ high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EVPN], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[META_QUEUE_EVPN], curr, memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
return 0;
}
@@ -3410,6 +3522,11 @@ static int mq_add_handler(void *data,
return mq_add_func(zrouter.mq, data);
}
+uint32_t zebra_rib_meta_queue_size(void)
+{
+ return zrouter.mq->size;
+}
+
void mpls_ftn_uninstall(struct zebra_vrf *zvrf, enum lsp_types_t type,
struct prefix *prefix, uint8_t route_type,
uint8_t route_instance)
@@ -4222,11 +4339,22 @@ void _route_entry_dump(const char *func, union prefixconstptr pp,
static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data)
{
+ uint64_t curr, high;
+
listnode_add(mq->subq[META_QUEUE_GR_RUN], data);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_GR_RUN], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[META_QUEUE_GR_RUN]);
+ high = atomic_load_explicit(&mq->max_subq[META_QUEUE_GR_RUN], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[META_QUEUE_GR_RUN], curr, memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
if (IS_ZEBRA_DEBUG_RIB_DETAILED)
- zlog_debug("Graceful Run adding");
+ zlog_debug("Graceful Run adding mq size %u", zrouter.mq->size);
return 0;
}
@@ -4234,17 +4362,27 @@ static int rib_meta_queue_gr_run_add(struct meta_queue *mq, void *data)
static int rib_meta_queue_early_route_add(struct meta_queue *mq, void *data)
{
struct zebra_early_route *ere = data;
+ uint64_t curr, high;
listnode_add(mq->subq[META_QUEUE_EARLY_ROUTE], data);
mq->size++;
+ atomic_fetch_add_explicit(&mq->total_metaq, 1, memory_order_relaxed);
+ atomic_fetch_add_explicit(&mq->total_subq[META_QUEUE_EARLY_ROUTE], 1, memory_order_relaxed);
+ curr = listcount(mq->subq[META_QUEUE_EARLY_ROUTE]);
+ high = atomic_load_explicit(&mq->max_subq[META_QUEUE_EARLY_ROUTE], memory_order_relaxed);
+ if (curr > high)
+ atomic_store_explicit(&mq->max_subq[META_QUEUE_EARLY_ROUTE], curr,
+ memory_order_relaxed);
+ high = atomic_load_explicit(&mq->max_metaq, memory_order_relaxed);
+ if (mq->size > high)
+ atomic_store_explicit(&mq->max_metaq, mq->size, memory_order_relaxed);
if (IS_ZEBRA_DEBUG_RIB_DETAILED) {
struct vrf *vrf = vrf_lookup_by_id(ere->re->vrf_id);
- zlog_debug("Route %pFX(%s) (%s) queued for processing into sub-queue %s",
- &ere->p, VRF_LOGNAME(vrf),
- ere->deletion ? "delete" : "add",
- subqueue2str(META_QUEUE_EARLY_ROUTE));
+ zlog_debug("Route %pFX(%s) (%s) queued for processing into sub-queue %s mq size %u",
+ &ere->p, VRF_LOGNAME(vrf), ere->deletion ? "delete" : "add",
+ subqueue2str(META_QUEUE_EARLY_ROUTE), zrouter.mq->size);
}
return 0;
diff --git a/zebra/zebra_snmp.c b/zebra/zebra_snmp.c
index 4b4f523253..06a9c0debe 100644
--- a/zebra/zebra_snmp.c
+++ b/zebra/zebra_snmp.c
@@ -418,11 +418,11 @@ static void get_fwtable_route_node(struct variable *v, oid objid[],
objid[v->namelen + 5] = policy;
{
- struct nexthop *nexthop;
+ struct nexthop *nh;
- nexthop = (*re)->nhe->nhg.nexthop;
- if (nexthop) {
- pnt = (uint8_t *)&nexthop->gate.ipv4;
+ nh = (*re)->nhe->nhg.nexthop;
+ if (nh) {
+ pnt = (uint8_t *)&nh->gate.ipv4;
for (i = 0; i < 4; i++)
objid[i + v->namelen + 6] = *pnt++;
}
diff --git a/zebra/zebra_srv6.c b/zebra/zebra_srv6.c
index ebfd5c0908..ee0d6c41c6 100644
--- a/zebra/zebra_srv6.c
+++ b/zebra/zebra_srv6.c
@@ -36,6 +36,8 @@ DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_USID_WLIB,
DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID, "SRv6 SID");
DEFINE_MTYPE_STATIC(SRV6_MGR, ZEBRA_SRV6_SID_CTX, "SRv6 SID context");
+static struct zebra_srv6 g_srv6;
+
/* Prototypes */
static int release_srv6_sid_func_dynamic(struct zebra_srv6_sid_block *block,
uint32_t sid_func);
@@ -705,8 +707,6 @@ void zebra_notify_srv6_locator_delete(struct srv6_locator *locator)
}
}
-struct zebra_srv6 srv6;
-
struct zebra_srv6 *zebra_srv6_get_default(void)
{
static bool first_execution = true;
@@ -715,11 +715,11 @@ struct zebra_srv6 *zebra_srv6_get_default(void)
if (first_execution) {
first_execution = false;
- srv6.locators = list_new();
+ g_srv6.locators = list_new();
/* Initialize list of SID formats */
- srv6.sid_formats = list_new();
- srv6.sid_formats->del = delete_srv6_sid_format;
+ g_srv6.sid_formats = list_new();
+ g_srv6.sid_formats->del = delete_srv6_sid_format;
/* Create SID format `usid-f3216` */
format_usidf3216 = create_srv6_sid_format_usid_f3216();
@@ -730,14 +730,14 @@ struct zebra_srv6 *zebra_srv6_get_default(void)
srv6_sid_format_register(format_uncompressed);
/* Init list to store SRv6 SIDs */
- srv6.sids = list_new();
- srv6.sids->del = delete_zebra_srv6_sid_ctx;
+ g_srv6.sids = list_new();
+ g_srv6.sids->del = delete_zebra_srv6_sid_ctx;
/* Init list to store SRv6 SID blocks */
- srv6.sid_blocks = list_new();
- srv6.sid_blocks->del = delete_zebra_srv6_sid_block;
+ g_srv6.sid_blocks = list_new();
+ g_srv6.sid_blocks->del = delete_zebra_srv6_sid_block;
}
- return &srv6;
+ return &g_srv6;
}
/**
@@ -2455,51 +2455,51 @@ void zebra_srv6_terminate(void)
struct zebra_srv6_sid_block *block;
struct zebra_srv6_sid_ctx *sid_ctx;
- if (srv6.locators) {
- while (listcount(srv6.locators)) {
- locator = listnode_head(srv6.locators);
+ if (g_srv6.locators) {
+ while (listcount(g_srv6.locators)) {
+ locator = listnode_head(g_srv6.locators);
- listnode_delete(srv6.locators, locator);
+ listnode_delete(g_srv6.locators, locator);
srv6_locator_free(locator);
}
- list_delete(&srv6.locators);
+ list_delete(&g_srv6.locators);
}
/* Free SRv6 SIDs */
- if (srv6.sids) {
- while (listcount(srv6.sids)) {
- sid_ctx = listnode_head(srv6.sids);
+ if (g_srv6.sids) {
+ while (listcount(g_srv6.sids)) {
+ sid_ctx = listnode_head(g_srv6.sids);
- listnode_delete(srv6.sids, sid_ctx);
+ listnode_delete(g_srv6.sids, sid_ctx);
zebra_srv6_sid_ctx_free(sid_ctx);
}
- list_delete(&srv6.sids);
+ list_delete(&g_srv6.sids);
}
/* Free SRv6 SID blocks */
- if (srv6.sid_blocks) {
- while (listcount(srv6.sid_blocks)) {
- block = listnode_head(srv6.sid_blocks);
+ if (g_srv6.sid_blocks) {
+ while (listcount(g_srv6.sid_blocks)) {
+ block = listnode_head(g_srv6.sid_blocks);
- listnode_delete(srv6.sid_blocks, block);
+ listnode_delete(g_srv6.sid_blocks, block);
zebra_srv6_sid_block_free(block);
}
- list_delete(&srv6.sid_blocks);
+ list_delete(&g_srv6.sid_blocks);
}
/* Free SRv6 SID formats */
- if (srv6.sid_formats) {
- while (listcount(srv6.sid_formats)) {
- format = listnode_head(srv6.sid_formats);
+ if (g_srv6.sid_formats) {
+ while (listcount(g_srv6.sid_formats)) {
+ format = listnode_head(g_srv6.sid_formats);
srv6_sid_format_unregister(format);
srv6_sid_format_free(format);
}
- list_delete(&srv6.sid_formats);
+ list_delete(&g_srv6.sid_formats);
}
}
diff --git a/zebra/zebra_srv6_vty.c b/zebra/zebra_srv6_vty.c
index 22ba9386d9..3d5a76ff38 100644
--- a/zebra/zebra_srv6_vty.c
+++ b/zebra/zebra_srv6_vty.c
@@ -210,7 +210,7 @@ DEFUN (show_srv6_locator_detail,
}
for (ALL_LIST_ELEMENTS_RO(srv6->locators, node, locator)) {
- struct listnode *node;
+ struct listnode *nnode;
struct srv6_locator_chunk *chunk;
if (strcmp(locator->name, locator_name) != 0)
@@ -247,8 +247,7 @@ DEFUN (show_srv6_locator_detail,
}
vty_out(vty, "Chunks:\n");
- for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, node,
- chunk)) {
+ for (ALL_LIST_ELEMENTS_RO((struct list *)locator->chunks, nnode, chunk)) {
prefix2str(&chunk->prefix, str, sizeof(str));
vty_out(vty, "- prefix: %s, owner: %s\n", str,
zebra_route_string(chunk->proto));
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index a1731712d3..9e4db11989 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -1490,8 +1490,6 @@ DEFPY(show_nexthop_group,
struct vrf *vrf;
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- struct zebra_vrf *zvrf;
-
zvrf = vrf->info;
if (!zvrf)
continue;
@@ -4049,6 +4047,20 @@ DEFUN (zebra_show_routing_tables_summary,
return CMD_SUCCESS;
}
+/* Display Zebra MetaQ counters */
+DEFUN (show_zebra_metaq_counters,
+ show_zebra_metaq_counters_cmd,
+ "show zebra metaq [json]",
+ SHOW_STR
+ ZEBRA_STR
+ "Zebra MetaQ counters\n"
+ JSON_STR)
+{
+ bool uj = use_json(argc, argv);
+
+ return zebra_show_metaq_counter(vty, uj);
+}
+
/* IPForwarding configuration write function. */
static int config_write_forwarding(struct vty *vty)
{
@@ -4338,6 +4350,7 @@ void zebra_vty_init(void)
install_element(VIEW_NODE, &show_dataplane_providers_cmd);
install_element(CONFIG_NODE, &zebra_dplane_queue_limit_cmd);
install_element(CONFIG_NODE, &no_zebra_dplane_queue_limit_cmd);
+ install_element(VIEW_NODE, &show_zebra_metaq_counters_cmd);
#ifdef HAVE_NETLINK
install_element(CONFIG_NODE, &zebra_kernel_netlink_batch_tx_buf_cmd);
diff --git a/zebra/zserv.c b/zebra/zserv.c
index d477cd051f..aab1bd0062 100644
--- a/zebra/zserv.c
+++ b/zebra/zserv.c
@@ -530,6 +530,12 @@ static void zserv_process_messages(struct event *thread)
struct stream_fifo *cache = stream_fifo_new();
uint32_t p2p = zrouter.packets_to_process;
bool need_resched = false;
+ uint32_t meta_queue_size = zebra_rib_meta_queue_size();
+
+ if (meta_queue_size < p2p)
+ p2p = p2p - meta_queue_size;
+ else
+ p2p = 0;
frr_with_mutex (&client->ibuf_mtx) {
uint32_t i;