From 1d311a05c97d6b7b6c893aafa86db150a7397887 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 18 Sep 2019 13:42:46 -0400 Subject: lib, zebra: Allow for interface deletion when kernel event happens When zebra gets a callback from the kernel that an interface has actually been deleted *and* the end users has not configured the interface, then allow for deletion of the interface from zebra. This is especially important in a docker environment where containers and their veth interfaces are treated as ephermeal. FRR can quickly have an inordinate amount of interfaces sitting around that are not in the kernel and we have no way to clean them up either. My expectation is that this will cause a second order crashes in upper level protocols, but I am not sure how to catch these and fix them now ( suggestions welcome ). There are too many use patterns and order based events that I cannot know for certain that we are going to see any at all, until someone sees this problem as a crash :( I do not recommend that this be put in the current stabilization branch and allow this to soak in master for some time first. Testing: sharpd@donna ~/frr4> sudo ip link add vethdj type veth peer name vethjd sharpd@donna ~/frr4> sudo ip link add vethaa type veth peer name vethab sharpd@donna ~/frr4> sudo vtysh -c "show int brief" Interface Status VRF Addresses --------- ------ --- --------- dummy1 down default enp0s3 up default 10.0.2.15/24 enp0s8 up default 192.168.209.2/24 enp0s9 up default 192.168.210.2/24 enp0s10 up default 192.168.212.4/24 lo up default 10.22.89.38/32 vethaa down default vethab down default vethdj down default vethjd down default virbr0 up default 192.168.122.1/24 virbr0-nic down default sharpd@donna ~/frr4> sudo ip link set vethaa up sharpd@donna ~/frr4> sudo ip link set vethab up sharpd@donna ~/frr4> sudo ip link del vethdj sharpd@donna ~/frr4> sudo vtysh -c "show int brief" Interface Status VRF Addresses --------- ------ --- --------- dummy1 down default enp0s3 up default 10.0.2.15/24 enp0s8 up default 192.168.209.2/24 enp0s9 up default 192.168.210.2/24 enp0s10 up default 192.168.212.4/24 lo up default 10.22.89.38/32 vethaa up default vethab up default virbr0 up default 192.168.122.1/24 virbr0-nic down default sharpd@donna ~/frr4> sudo ip link del vethaa sharpd@donna ~/frr4> sudo vtysh -c "show int brief" Interface Status VRF Addresses --------- ------ --- --------- dummy1 down default enp0s3 up default 10.0.2.15/24 enp0s8 up default 192.168.209.2/24 enp0s9 up default 192.168.210.2/24 enp0s10 up default 192.168.212.4/24 lo up default 10.22.89.38/32 virbr0 up default 192.168.122.1/24 virbr0-nic down default sharpd@donna ~/frr4> sudo ip link add vethaa type veth peer name vethab sharpd@donna ~/frr4> sudo vtysh -c "show int brief" Interface Status VRF Addresses --------- ------ --- --------- dummy1 down default enp0s3 up default 10.0.2.15/24 enp0s8 up default 192.168.209.2/24 enp0s9 up default 192.168.210.2/24 enp0s10 up default 192.168.212.4/24 lo up default 10.22.89.38/32 vethaa down default vethab down default virbr0 up default 192.168.122.1/24 virbr0-nic down default sharpd@donna ~/frr4> sudo vtysh -c "show run" Building configuration... Current configuration: ! frr version 7.2-dev frr defaults datacenter hostname donna.cumulusnetworks.com log stdout no ipv6 forwarding ! ip route 192.168.3.0/24 192.168.209.1 ip route 192.168.4.0/24 blackhole ip route 192.168.5.0/24 192.168.209.1 ip route 192.168.6.0/24 192.168.209.1 ip route 192.168.7.0/24 99.99.99.99 nexthop-vrf EVA ip route 192.168.8.0/24 192.168.209.1 ip route 4.5.6.7/32 12.13.14.15 ! interface dummy1 ip address 12.13.14.15/32 ! interface vethaa description FROO ! line vty ! end sharpd@donna ~/frr4> sudo ip link del vethaa sharpd@donna ~/frr4> sudo vtysh -c "show int brief" Interface Status VRF Addresses --------- ------ --- --------- dummy1 down default enp0s3 up default 10.0.2.15/24 enp0s8 up default 192.168.209.2/24 enp0s9 up default 192.168.210.2/24 enp0s10 up default 192.168.212.4/24 lo up default 10.22.89.38/32 vethaa down default virbr0 up default 192.168.122.1/24 virbr0-nic down default sharpd@donna ~/frr4> sudo vtysh -c "show run" Building configuration... Current configuration: ! frr version 7.2-dev frr defaults datacenter hostname donna.cumulusnetworks.com log stdout no ipv6 forwarding ! ip route 192.168.3.0/24 192.168.209.1 ip route 192.168.4.0/24 blackhole ip route 192.168.5.0/24 192.168.209.1 ip route 192.168.6.0/24 192.168.209.1 ip route 192.168.7.0/24 99.99.99.99 nexthop-vrf EVA ip route 192.168.8.0/24 192.168.209.1 ip route 4.5.6.7/32 12.13.14.15 ! interface dummy1 ip address 12.13.14.15/32 ! interface vethaa description FROO ! line vty ! end Signed-off-by: Donald Sharp --- zebra/interface.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'zebra/interface.c') diff --git a/zebra/interface.c b/zebra/interface.c index 6486c01430..d21ab25fed 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -767,6 +767,13 @@ void if_delete_update(struct interface *ifp) memset(&zif->brslave_info, 0, sizeof(struct zebra_l2info_brslave)); } + + if (!ifp->configured) { + if (IS_ZEBRA_DEBUG_KERNEL) + zlog_debug("interface %s is being deleted from the system", + ifp->name); + if_delete(ifp); + } } /* VRF change for an interface */ -- cgit v1.2.3 From 138c5a745018a291c8463b67dba7602886859d2e Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 18 Sep 2019 16:20:04 -0400 Subject: *: Add infrastructure to support zapi interface callbacks Start the conversion to allow zapi interface callbacks to be controlled like vrf creation/destruction/change callbacks. This will allow us to consolidate control into the interface.c instead of having each daemon read the stream and react accordingly. This will hopefully reduce a bunch of cut-n-paste stuff Create 4 new callback functions that will be controlled by lib/if.c create -> A upper level protocol receives an interface creation event The ifp is brand spanking newly created in the system. up -> A upper level protocol receives a interface up event This means the interface is up and ready to go. down -> A upper level protocol receives a interface down destroy -> A upper level protocol receives a destroy event This means to delete the pointers associated with it. At this point this is just boilerplate setup for future commits. There is no new functionality. Signed-off-by: Donald Sharp --- babeld/babel_interface.c | 20 ++++++++++++++++++++ babeld/babel_interface.h | 5 +++++ babeld/babel_main.c | 2 ++ bfdd/ptm_adapter.c | 11 +++++++++++ bgpd/bgp_zebra.c | 23 +++++++++++++++++++++++ eigrpd/eigrp_interface.c | 22 ++++++++++++++++++++++ eigrpd/eigrp_interface.h | 1 - isisd/isis_circuit.c | 22 ++++++++++++++++++++++ ldpd/ldp_zebra.c | 23 +++++++++++++++++++++++ lib/if.c | 18 ++++++++++++++++++ lib/if.h | 5 +++++ nhrpd/nhrp_interface.c | 20 ++++++++++++++++++++ nhrpd/nhrp_main.c | 2 ++ nhrpd/nhrpd.h | 4 ++++ ospf6d/ospf6_interface.c | 22 ++++++++++++++++++++++ ospfd/ospf_interface.c | 23 +++++++++++++++++++++++ pbrd/pbr_main.c | 2 ++ pbrd/pbr_zebra.c | 20 ++++++++++++++++++++ pbrd/pbr_zebra.h | 6 ++++++ pimd/pim_iface.c | 20 ++++++++++++++++++++ pimd/pim_iface.h | 6 ++++++ pimd/pim_main.c | 2 ++ ripd/rip_interface.c | 22 ++++++++++++++++++++++ ripngd/ripng_interface.c | 22 ++++++++++++++++++++++ sharpd/sharp_zebra.c | 23 +++++++++++++++++++++++ staticd/static_zebra.c | 24 ++++++++++++++++++++++++ vrrpd/vrrp_vty.c | 1 + vrrpd/vrrp_zebra.c | 23 +++++++++++++++++++++++ vrrpd/vrrp_zebra.h | 5 +++++ zebra/interface.c | 5 +++++ 30 files changed, 403 insertions(+), 1 deletion(-) (limited to 'zebra/interface.c') diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 0eeb9b2bbb..898848f84e 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -1260,6 +1260,26 @@ DEFUN (show_babel_parameters, return CMD_SUCCESS; } +int babel_ifp_create(struct interface *ifp) +{ + return 0; +} + +int babel_ifp_up(struct interface *ifp) +{ + return 0; +} + +int babel_ifp_down(struct interface *ifp) +{ + return 0; +} + +int babel_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void babel_if_init(void) { diff --git a/babeld/babel_interface.h b/babeld/babel_interface.h index d9e2745827..9833827927 100644 --- a/babeld/babel_interface.h +++ b/babeld/babel_interface.h @@ -121,6 +121,11 @@ int babel_interface_delete (int, struct zclient *, zebra_size_t, vrf_id_t); int babel_interface_address_add (int, struct zclient *, zebra_size_t, vrf_id_t); int babel_interface_address_delete (int, struct zclient *, zebra_size_t, vrf_id_t); +int babel_ifp_create(struct interface *ifp); +int babel_ifp_up(struct interface *ifp); +int babel_ifp_down(struct interface *ifp); +int babel_ifp_destroy(struct interface *ifp); + unsigned jitter(babel_interface_nfo *, int); unsigned update_jitter(babel_interface_nfo *babel_ifp, int urgent); /* return "true" if "address" is one of our ipv6 addresses */ diff --git a/babeld/babel_main.c b/babeld/babel_main.c index a3f2b4e7d8..4bb8408157 100644 --- a/babeld/babel_main.c +++ b/babeld/babel_main.c @@ -202,6 +202,8 @@ main(int argc, char **argv) babel_replace_by_null(STDIN_FILENO); /* init some quagga's dependencies, and babeld's commands */ + if_zapi_callbacks(babel_ifp_create, babel_ifp_up, + babel_ifp_down, babel_ifp_destroy); babeld_quagga_init(); /* init zebra client's structure and it's commands */ /* this replace kernel_setup && kernel_setup_socket */ diff --git a/bfdd/ptm_adapter.c b/bfdd/ptm_adapter.c index ae6d04e77d..2d1b17ce4a 100644 --- a/bfdd/ptm_adapter.c +++ b/bfdd/ptm_adapter.c @@ -756,8 +756,19 @@ static int bfdd_interface_address_update(ZAPI_CALLBACK_ARGS) return 0; } +static int bfd_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int bfd_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void bfdd_zclient_init(struct zebra_privs_t *bfdd_priv) { + if_zapi_callbacks(bfd_ifp_create, NULL, NULL, bfd_ifp_destroy); zclient = zclient_new(master, &zclient_options_default); assert(zclient != NULL); zclient_init(zclient, ZEBRA_ROUTE_BFD, 0, bfdd_priv); diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 71f7f6d0e3..ee523e51cb 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -2721,10 +2721,33 @@ stream_failure: /* for STREAM_GETX */ extern struct zebra_privs_t bgpd_privs; +static int bgp_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int bgp_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int bgp_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int bgp_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void bgp_zebra_init(struct thread_master *master, unsigned short instance) { zclient_num_connects = 0; + if_zapi_callbacks(bgp_ifp_create, bgp_ifp_up, + bgp_ifp_down, bgp_ifp_destroy); + /* Set default values. */ zclient = zclient_new(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_BGP, 0, &bgpd_privs); diff --git a/eigrpd/eigrp_interface.c b/eigrpd/eigrp_interface.c index fd1d3f5cb9..76e101b010 100644 --- a/eigrpd/eigrp_interface.c +++ b/eigrpd/eigrp_interface.c @@ -122,10 +122,32 @@ int eigrp_if_delete_hook(struct interface *ifp) return 0; } +static int eigrp_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int eigrp_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int eigrp_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int eigrp_ifp_destroy(struct interface *ifp) +{ + return 0; +} + struct list *eigrp_iflist; void eigrp_if_init(void) { + if_zapi_callbacks(eigrp_ifp_create, eigrp_ifp_up, + eigrp_ifp_down, eigrp_ifp_destroy); /* Initialize Zebra interface data structure. */ // hook_register_prio(if_add, 0, eigrp_if_new); hook_register_prio(if_del, 0, eigrp_if_delete_hook); diff --git a/eigrpd/eigrp_interface.h b/eigrpd/eigrp_interface.h index a18b0b7015..1e66dafde2 100644 --- a/eigrpd/eigrp_interface.h +++ b/eigrpd/eigrp_interface.h @@ -63,5 +63,4 @@ extern uint32_t eigrp_scaled_to_bandwidth(uint32_t); extern uint32_t eigrp_delay_to_scaled(uint32_t); extern uint32_t eigrp_scaled_to_delay(uint32_t); - #endif /* ZEBRA_EIGRP_INTERFACE_H_ */ diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 5da8e6ee9e..64ec047054 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -1389,6 +1389,26 @@ int isis_if_delete_hook(struct interface *ifp) return 0; } +static int isis_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int isis_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int isis_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int isis_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void isis_circuit_init(void) { /* Initialize Zebra interface data structure */ @@ -1398,4 +1418,6 @@ void isis_circuit_init(void) /* Install interface node */ install_node(&interface_node, isis_interface_config_write); if_cmd_init(); + if_zapi_callbacks(isis_ifp_create, isis_ifp_up, + isis_ifp_down, isis_ifp_destroy); } diff --git a/ldpd/ldp_zebra.c b/ldpd/ldp_zebra.c index 884ae159be..251df73888 100644 --- a/ldpd/ldp_zebra.c +++ b/ldpd/ldp_zebra.c @@ -532,9 +532,32 @@ ldp_zebra_connected(struct zclient *zclient) extern struct zebra_privs_t ldpd_privs; +static int ldp_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int ldp_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int ldp_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int ldp_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void ldp_zebra_init(struct thread_master *master) { + if_zapi_callbacks(ldp_ifp_create, ldp_ifp_up, + ldp_ifp_down, ldp_ifp_destroy); + /* Set default values. */ zclient = zclient_new(master, &zclient_options_default); zclient_init(zclient, ZEBRA_ROUTE_LDP, 0, &ldpd_privs); diff --git a/lib/if.c b/lib/if.c index 371c6bef87..9d316856da 100644 --- a/lib/if.c +++ b/lib/if.c @@ -58,6 +58,13 @@ DEFINE_QOBJ_TYPE(interface) DEFINE_HOOK(if_add, (struct interface * ifp), (ifp)) DEFINE_KOOH(if_del, (struct interface * ifp), (ifp)) +struct interface_master{ + int (*create_hook)(struct interface *ifp); + int (*up_hook)(struct interface *ifp); + int (*down_hook)(struct interface *ifp); + int (*destroy_hook)(struct interface *ifp); +} ifp_master = { 0, }; + /* Compare interface names, returning an integer greater than, equal to, or * less than 0, (following the strcmp convention), according to the * relationship between ifp1 and ifp2. Interface names consist of an @@ -1367,6 +1374,17 @@ void if_cmd_init(void) install_element(INTERFACE_NODE, &no_interface_desc_cmd); } +void if_zapi_callbacks(int (*create)(struct interface *ifp), + int (*up)(struct interface *ifp), + int (*down)(struct interface *ifp), + int (*destroy)(struct interface *ifp)) +{ + ifp_master.create_hook = create; + ifp_master.up_hook = up; + ifp_master.down_hook = down; + ifp_master.destroy_hook = destroy; +} + /* ------- Northbound callbacks ------- */ /* diff --git a/lib/if.h b/lib/if.h index ee99fad2e1..ce79a3a463 100644 --- a/lib/if.h +++ b/lib/if.h @@ -558,6 +558,11 @@ void if_link_params_free(struct interface *); /* Northbound. */ extern void if_cmd_init(void); +extern void if_zapi_callbacks(int (*create)(struct interface *ifp), + int (*up)(struct interface *ifp), + int (*down)(struct interface *ifp), + int (*destroy)(struct interface *ifp)); + extern const struct frr_yang_module_info frr_interface_info; #ifdef __cplusplus diff --git a/nhrpd/nhrp_interface.c b/nhrpd/nhrp_interface.c index 8f1ba14fe4..31e19eda3e 100644 --- a/nhrpd/nhrp_interface.c +++ b/nhrpd/nhrp_interface.c @@ -436,3 +436,23 @@ void nhrp_interface_set_source(struct interface *ifp, const char *ifname) nhrp_interface_update_nbma(ifp); } + +int nhrp_ifp_create(struct interface *ifp) +{ + return 0; +} + +int nhrp_ifp_up(struct interface *ifp) +{ + return 0; +} + +int nhrp_ifp_down(struct interface *ifp) +{ + return 0; +} + +int nhrp_ifp_destroy(struct interface *ifp) +{ + return 0; +} diff --git a/nhrpd/nhrp_main.c b/nhrpd/nhrp_main.c index 969638cd77..c6c83614ef 100644 --- a/nhrpd/nhrp_main.c +++ b/nhrpd/nhrp_main.c @@ -152,6 +152,8 @@ int main(int argc, char **argv) nhrp_vc_init(); nhrp_packet_init(); vici_init(); + if_zapi_callbacks(nhrp_ifp_create, nhrp_ifp_up, + nhrp_ifp_down, nhrp_ifp_destroy); nhrp_zebra_init(); nhrp_shortcut_init(); diff --git a/nhrpd/nhrpd.h b/nhrpd/nhrpd.h index 670c9f4f18..50746d9ad5 100644 --- a/nhrpd/nhrpd.h +++ b/nhrpd/nhrpd.h @@ -319,6 +319,10 @@ void nhrp_interface_notify_del(struct interface *ifp, struct notifier_block *n); void nhrp_interface_set_protection(struct interface *ifp, const char *profile, const char *fallback_profile); void nhrp_interface_set_source(struct interface *ifp, const char *ifname); +extern int nhrp_ifp_create(struct interface *ifp); +extern int nhrp_ifp_up(struct interface *ifp); +extern int nhrp_ifp_down(struct interface *ifp); +extern int nhrp_ifp_destroy(struct interface *ifp); int nhrp_nhs_add(struct interface *ifp, afi_t afi, union sockunion *proto_addr, const char *nbma_fqdn); diff --git a/ospf6d/ospf6_interface.c b/ospf6d/ospf6_interface.c index 692c84ad08..50e9f80cc2 100644 --- a/ospf6d/ospf6_interface.c +++ b/ospf6d/ospf6_interface.c @@ -1935,11 +1935,33 @@ static struct cmd_node interface_node = { INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */ }; +static int ospf6_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int ospf6_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int ospf6_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int ospf6_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void ospf6_interface_init(void) { /* Install interface node. */ install_node(&interface_node, config_write_ospf6_interface); if_cmd_init(); + if_zapi_callbacks(ospf6_ifp_create, ospf6_ifp_up, + ospf6_ifp_down, ospf6_ifp_destroy); install_element(VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd); install_element(VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 3877708708..3324740d59 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -1218,8 +1218,31 @@ uint8_t ospf_default_iftype(struct interface *ifp) return OSPF_IFTYPE_BROADCAST; } +static int ospf_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int ospf_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int ospf_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int ospf_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void ospf_if_init(void) { + if_zapi_callbacks(ospf_ifp_create, ospf_ifp_up, + ospf_ifp_down, ospf_ifp_destroy); + /* Initialize Zebra interface data structure. */ hook_register_prio(if_add, 0, ospf_if_new_hook); hook_register_prio(if_del, 0, ospf_if_delete_hook); diff --git a/pbrd/pbr_main.c b/pbrd/pbr_main.c index 246d836acf..bb92703ae4 100644 --- a/pbrd/pbr_main.c +++ b/pbrd/pbr_main.c @@ -166,6 +166,8 @@ int main(int argc, char **argv, char **envp) access_list_init(); pbr_nht_init(); pbr_map_init(); + if_zapi_callbacks(pbr_ifp_create, pbr_ifp_up, + pbr_ifp_down, pbr_ifp_destroy); pbr_zebra_init(); pbr_vty_init(); diff --git a/pbrd/pbr_zebra.c b/pbrd/pbr_zebra.c index d74d0fcd23..b8df7fc5ae 100644 --- a/pbrd/pbr_zebra.c +++ b/pbrd/pbr_zebra.c @@ -579,3 +579,23 @@ void pbr_send_pbr_map(struct pbr_map_sequence *pbrms, zclient_send_message(zclient); } + +int pbr_ifp_create(struct interface *ifp) +{ + return 0; +} + +int pbr_ifp_up(struct interface *ifp) +{ + return 0; +} + +int pbr_ifp_down(struct interface *ifp) +{ + return 0; +} + +int pbr_ifp_destroy(struct interface *ifp) +{ + return 0; +} diff --git a/pbrd/pbr_zebra.h b/pbrd/pbr_zebra.h index 4cbefe2636..d5d938021a 100644 --- a/pbrd/pbr_zebra.h +++ b/pbrd/pbr_zebra.h @@ -39,4 +39,10 @@ extern void pbr_send_pbr_map(struct pbr_map_sequence *pbrms, struct pbr_map_interface *pmi, bool install); extern struct pbr_interface *pbr_if_new(struct interface *ifp); + +extern int pbr_ifp_create(struct interface *ifp); +extern int pbr_ifp_up(struct interface *ifp); +extern int pbr_ifp_down(struct interface *ifp); +extern int pbr_ifp_destroy(struct interface *ifp); + #endif diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index bdeda2d76b..d20713b9c5 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -1526,3 +1526,23 @@ int pim_if_ifchannel_count(struct pim_interface *pim_ifp) return count; } + +int pim_ifp_create(struct interface *ifp) +{ + return 0; +} + +int pim_ifp_up(struct interface *ifp) +{ + return 0; +} + +int pim_ifp_down(struct interface *ifp) +{ + return 0; +} + +int pim_ifp_destroy(struct interface *ifp) +{ + return 0; +} diff --git a/pimd/pim_iface.h b/pimd/pim_iface.h index 1c11e85705..1b76b52305 100644 --- a/pimd/pim_iface.h +++ b/pimd/pim_iface.h @@ -227,4 +227,10 @@ int pim_update_source_set(struct interface *ifp, struct in_addr source); bool pim_if_is_vrf_device(struct interface *ifp); int pim_if_ifchannel_count(struct pim_interface *pim_ifp); + +extern int pim_ifp_create(struct interface *ifp); +extern int pim_ifp_up(struct interface *ifp); +extern int pim_ifp_down(struct interface *ifp); +extern int pim_ifp_destroy(struct interface *ifp); + #endif /* PIM_IFACE_H */ diff --git a/pimd/pim_main.c b/pimd/pim_main.c index 5a8991c4c0..6a7dbe769f 100644 --- a/pimd/pim_main.c +++ b/pimd/pim_main.c @@ -127,6 +127,8 @@ int main(int argc, char **argv, char **envp) /* * Initialize zclient "update" and "lookup" sockets */ + if_zapi_callbacks(pim_ifp_create, pim_ifp_up, + pim_ifp_down, pim_ifp_destroy); pim_zebra_init(); pim_bfd_init(); diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c index 80561f350b..f20058a173 100644 --- a/ripd/rip_interface.c +++ b/ripd/rip_interface.c @@ -1253,6 +1253,26 @@ static int rip_interface_delete_hook(struct interface *ifp) return 0; } +static int rip_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int rip_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int rip_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int rip_ifp_destroy(struct interface *ifp) +{ + return 0; +} + /* Allocate and initialize interface vector. */ void rip_if_init(void) { @@ -1263,4 +1283,6 @@ void rip_if_init(void) /* Install interface node. */ install_node(&interface_node, rip_interface_config_write); if_cmd_init(); + if_zapi_callbacks(rip_ifp_create, rip_ifp_up, + rip_ifp_down, rip_ifp_destroy); } diff --git a/ripngd/ripng_interface.c b/ripngd/ripng_interface.c index 9ed9dc28fe..02c35e04ca 100644 --- a/ripngd/ripng_interface.c +++ b/ripngd/ripng_interface.c @@ -989,6 +989,26 @@ static struct cmd_node interface_node = { INTERFACE_NODE, "%s(config-if)# ", 1 /* VTYSH */ }; +static int ripng_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int ripng_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int ripng_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int ripng_ifp_destroy(struct interface *ifp) +{ + return 0; +} + /* Initialization of interface. */ void ripng_if_init(void) { @@ -999,4 +1019,6 @@ void ripng_if_init(void) /* Install interface node. */ install_node(&interface_node, interface_config_write); if_cmd_init(); + if_zapi_callbacks(ripng_ifp_create, ripng_ifp_up, + ripng_ifp_down, ripng_ifp_destroy); } diff --git a/sharpd/sharp_zebra.c b/sharpd/sharp_zebra.c index 6263f429ea..6e34785554 100644 --- a/sharpd/sharp_zebra.c +++ b/sharpd/sharp_zebra.c @@ -392,12 +392,35 @@ static int sharp_nexthop_update(ZAPI_CALLBACK_ARGS) return 0; } +static int sharp_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int sharp_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int sharp_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int sharp_ifp_destroy(struct interface *ifp) +{ + return 0; +} + extern struct zebra_privs_t sharp_privs; void sharp_zebra_init(void) { struct zclient_options opt = {.receive_notify = true}; + if_zapi_callbacks(sharp_ifp_create, sharp_ifp_up, + sharp_ifp_down, sharp_ifp_destroy); + zclient = zclient_new(master, &opt); zclient_init(zclient, ZEBRA_ROUTE_SHARP, 0, &sharp_privs); diff --git a/staticd/static_zebra.c b/staticd/static_zebra.c index 1965c2968e..c18cbed6ba 100644 --- a/staticd/static_zebra.c +++ b/staticd/static_zebra.c @@ -504,10 +504,34 @@ extern void static_zebra_route_add(struct route_node *rn, ZEBRA_ROUTE_ADD : ZEBRA_ROUTE_DELETE, zclient, &api); } + +static int static_ifp_create(struct interface *ifp) +{ + return 0; +} + +static int static_ifp_up(struct interface *ifp) +{ + return 0; +} + +static int static_ifp_down(struct interface *ifp) +{ + return 0; +} + +static int static_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void static_zebra_init(void) { struct zclient_options opt = { .receive_notify = true }; + if_zapi_callbacks(static_ifp_create, static_ifp_up, + static_ifp_down, static_ifp_destroy); + zclient = zclient_new(master, &opt); zclient_init(zclient, ZEBRA_ROUTE_STATIC, 0, &static_privs); diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c index 2dc3d3f8a3..f71b343140 100644 --- a/vrrpd/vrrp_vty.c +++ b/vrrpd/vrrp_vty.c @@ -30,6 +30,7 @@ #include "vrrp.h" #include "vrrp_debug.h" #include "vrrp_vty.h" +#include "vrrp_zebra.h" #ifndef VTYSH_EXTRACT_PL #include "vrrpd/vrrp_vty_clippy.c" #endif diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c index 72b77c1313..0844b90266 100644 --- a/vrrpd/vrrp_zebra.c +++ b/vrrpd/vrrp_zebra.c @@ -236,8 +236,31 @@ int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down) down); } +int vrrp_ifp_create(struct interface *ifp) +{ + return 0; +} + +int vrrp_ifp_up(struct interface *ifp) +{ + return 0; +} + +int vrrp_ifp_down(struct interface *ifp) +{ + return 0; +} + +int vrrp_ifp_destroy(struct interface *ifp) +{ + return 0; +} + void vrrp_zebra_init(void) { + if_zapi_callbacks(vrrp_ifp_create, vrrp_ifp_up, + vrrp_ifp_down, vrrp_ifp_destroy); + /* Socket for receiving updates from Zebra daemon */ zclient = zclient_new(master, &zclient_options_default); diff --git a/vrrpd/vrrp_zebra.h b/vrrpd/vrrp_zebra.h index 84bcba23c1..02d7055b86 100644 --- a/vrrpd/vrrp_zebra.h +++ b/vrrpd/vrrp_zebra.h @@ -29,4 +29,9 @@ extern void vrrp_zebra_radv_set(struct vrrp_router *r, bool enable); extern int vrrp_zclient_send_interface_protodown(struct interface *ifp, bool down); +extern int vrrp_ifp_create(struct interface *ifp); +extern int vrrp_ifp_up(struct interface *ifp); +extern int vrrp_ifp_down(struct interface *ifp); +extern int vrrp_ifp_destroy(struct interface *ifp); + #endif /* __VRRP_ZEBRA_H__ */ diff --git a/zebra/interface.c b/zebra/interface.c index d21ab25fed..baf94ad285 100644 --- a/zebra/interface.c +++ b/zebra/interface.c @@ -3202,6 +3202,11 @@ void zebra_if_init(void) install_node(&interface_node, if_config_write); install_node(&link_params_node, NULL); if_cmd_init(); + /* + * This is *intentionally* setting this to NULL, signaling + * that interface creation for zebra acts differently + */ + if_zapi_callbacks(NULL, NULL, NULL, NULL); install_element(VIEW_NODE, &show_interface_cmd); install_element(VIEW_NODE, &show_interface_vrf_all_cmd); -- cgit v1.2.3