vrrpd: zebra connections

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
Quentin Young 2018-12-04 20:41:37 +00:00
parent a8144d7fc8
commit b6029d6a5f
3 changed files with 212 additions and 13 deletions

View File

@ -38,6 +38,9 @@
/* threadmaster */
extern struct thread_master *master;
/* privileges */
extern struct zebra_privs_t vrrp_privs;
/* Global hash of all Virtual Routers */
struct hash *vrrp_vrouters_hash;

View File

@ -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__);
}

View File

@ -20,10 +20,5 @@
#ifndef __VRRP_ZEBRA_H__
#define __VRRP_ZEBRA_H__
#include "zclient.h"
#include "thread.h"
extern struct thread_master *master;
extern struct zebra_privs_t vrrp_privs;
extern void vrrp_zebra_init(void);
#endif