diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-12-04 20:41:37 +0000 | 
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-05-17 00:27:08 +0000 | 
| commit | b6029d6a5f29e3fce036e3013b992e47af77639d (patch) | |
| tree | 7192f0c5a733aa2672d6796508076eaf377beee0 /vrrpd/vrrp_zebra.c | |
| parent | a8144d7fc8521c1f01f73e28b68df20110ad7e81 (diff) | |
vrrpd: zebra connections
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'vrrpd/vrrp_zebra.c')
| -rw-r--r-- | vrrpd/vrrp_zebra.c | 217 | 
1 files changed, 209 insertions, 8 deletions
diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c index c96f9a5646..26d0a5020a 100644 --- a/vrrpd/vrrp_zebra.c +++ b/vrrpd/vrrp_zebra.c @@ -19,21 +19,222 @@   */  #include <zebra.h> -#include "zclient.h" -#include "thread.h" +#include "lib/if.h" +#include "lib/log.h" +#include "lib/prefix.h" +#include "lib/zclient.h" +#include "lib/vty.h" +#include "lib/linklist.h" +#include "vrrp.h"  #include "vrrp_zebra.h" -/* Zebra structure to hold current status. */ -struct thread_master *master; -struct zclient *zclient; +static struct zclient *zclient = NULL; + +static void vrrp_zebra_connected(struct zclient *zclient) +{ +	fprintf(stderr, "Zclient connected\n"); +	zclient_send_reg_requests(zclient, VRF_DEFAULT); +} + +/* Router-id update message from zebra. */ +static int vrrp_router_id_update_zebra(int command, struct zclient *zclient, +				       zebra_size_t length, vrf_id_t vrf_id) +{ +	struct prefix router_id; + +	zebra_router_id_update_read(zclient->ibuf, &router_id); + +	return 0; +} + +static int vrrp_zebra_if_add(int command, struct zclient *zclient, +			     zebra_size_t length, vrf_id_t vrf_id) +{ +	struct interface *ifp; + +	/* +	 * zebra api adds/dels interfaces using the same call +	 * interface_add_read below, see comments in lib/zclient.c +	 */ +	ifp = zebra_interface_add_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +	/* FIXME: handle subinterface creation here */ + +	return 0; +} + +static int vrrp_zebra_if_del(int command, struct zclient *zclient, +			     zebra_size_t length, vrf_id_t vrf_id) +{ +	struct interface *ifp; + +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +#if 0 +	if (VRRP_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} +#endif + +	return 0; +} + +static int vrrp_zebra_if_state_up(int command, struct zclient *zclient, +				  zebra_size_t length, vrf_id_t vrf_id) +{ +	struct interface *ifp; + +	/* +	 * zebra api notifies interface up/down events by using the same call +	 * zebra_interface_state_read below, see comments in lib/zclient.c ifp = +	 * zebra_interface_state_read(zclient->ibuf, vrf_id); +	 */ +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +#if 0 +	if (VRRP_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} +#endif + +	return 0; +} + +static int vrrp_zebra_if_state_down(int command, struct zclient *zclient, +				    zebra_size_t length, vrf_id_t vrf_id) +{ +	struct interface *ifp; + +	/* +	 * zebra api notifies interface up/down events by using the same call +	 * zebra_interface_state_read below, see comments in lib/zclient.c +	 */ +	ifp = zebra_interface_state_read(zclient->ibuf, vrf_id); +	if (!ifp) +		return 0; + +#if 0 +	if (VRRP_DEBUG_ZEBRA) { +		zlog_debug( +			"%s: %s index %d(%u) flags %ld metric %d mtu %d operative %d", +			__PRETTY_FUNCTION__, ifp->name, ifp->ifindex, vrf_id, +			(long)ifp->flags, ifp->metric, ifp->mtu, +			if_is_operative(ifp)); +	} +#endif + +	return 0; +} + +#ifdef VRRP_DEBUG_IFADDR_DUMP +static void dump_if_address(struct interface *ifp) +{ +	struct connected *ifc; +	struct listnode *node; + +	zlog_debug("%s %s: interface %s addresses:", __FILE__, +		   __PRETTY_FUNCTION__, ifp->name); + +	for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) { +		struct prefix *p = ifc->address; + +		if (p->family != AF_INET) +			continue; + +		zlog_debug("%s %s: interface %s address %s %s", __FILE__, +			   __PRETTY_FUNCTION__, ifp->name, +			   inet_ntoa(p->u.prefix4), +			   CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY) +				   ? "secondary" +				   : "primary"); +	} +} +#endif + +static int vrrp_zebra_if_address_add(int command, struct zclient *zclient, +				     zebra_size_t length, vrf_id_t vrf_id) +{ +	struct connected *c; + +	/* +	 * zebra api notifies address adds/dels events by using the same call +	 * interface_add_read below, see comments in lib/zclient.c +	 * +	 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_ADD, ...) +	 * will add address to interface list by calling +	 * connected_add_by_prefix() +	 */ +	c = zebra_interface_address_read(command, zclient->ibuf, vrf_id); +	if (!c) +		return 0; + +#if 0 +	if (VRRP_DEBUG_ZEBRA) { +		char buf[BUFSIZ]; +		prefix2str(p, buf, BUFSIZ); +		zlog_debug("%s: %s(%u) connected IP address %s flags %u %s", +			   __PRETTY_FUNCTION__, c->ifp->name, vrf_id, buf, +			   c->flags, +			   CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY) +				   ? "secondary" +				   : "primary"); + +	} +#endif + +	return 0; +} + +static int vrrp_zebra_if_address_del(int command, struct zclient *client, +				     zebra_size_t length, vrf_id_t vrf_id) +{ +	struct connected *c; + +	/* +	 * zebra api notifies address adds/dels events by using the same call +	 * interface_add_read below, see comments in lib/zclient.c +	 * +	 * zebra_interface_address_read(ZEBRA_INTERFACE_ADDRESS_DELETE, ...) +	 * will remove address from interface list by calling +	 * connected_delete_by_prefix() +	 */ +	c = zebra_interface_address_read(command, client->ibuf, vrf_id); +	if (!c) +		return 0; + +	return 0; +}  void vrrp_zebra_init(void)  { -	struct zclient_options opt = { .receive_notify = true }; +	/* Socket for receiving updates from Zebra daemon */ +	zclient = zclient_new(master, &zclient_options_default); -	zclient = zclient_new(master, &opt); +	zclient->zebra_connected = vrrp_zebra_connected; +	zclient->router_id_update = vrrp_router_id_update_zebra; +	zclient->interface_add = vrrp_zebra_if_add; +	zclient->interface_delete = vrrp_zebra_if_del; +	zclient->interface_up = vrrp_zebra_if_state_up; +	zclient->interface_down = vrrp_zebra_if_state_down; +	zclient->interface_address_add = vrrp_zebra_if_address_add; +	zclient->interface_address_delete = vrrp_zebra_if_address_del;  	zclient_init(zclient, 0, 0, &vrrp_privs); -} +	zlog_notice("%s: zclient socket initialized", __PRETTY_FUNCTION__); +}  | 
