mirror of
https://github.com/FRRouting/frr.git
synced 2025-04-30 13:37:17 +02:00
vrrpd: initial commit
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
This commit is contained in:
parent
db95656d48
commit
5435a2bf61
|
@ -147,6 +147,7 @@ include staticd/subdir.am
|
|||
include bfdd/subdir.am
|
||||
include yang/subdir.am
|
||||
include yang/libyang_plugins/subdir.am
|
||||
include vrrpd/subdir.am
|
||||
|
||||
include vtysh/subdir.am
|
||||
include tests/subdir.am
|
||||
|
@ -188,7 +189,6 @@ EXTRA_DIST += \
|
|||
snapcraft/defaults \
|
||||
snapcraft/helpers \
|
||||
snapcraft/snap \
|
||||
\
|
||||
babeld/Makefile \
|
||||
bgpd/Makefile \
|
||||
bgpd/rfp-example/librfp/Makefile \
|
||||
|
@ -218,6 +218,7 @@ EXTRA_DIST += \
|
|||
vtysh/Makefile \
|
||||
watchfrr/Makefile \
|
||||
zebra/Makefile \
|
||||
vrrpd/Makefile \
|
||||
# end
|
||||
|
||||
noinst_HEADERS += defaults.h
|
||||
|
|
|
@ -1602,6 +1602,7 @@ AM_CONDITIONAL([PBRD], [test "${enable_pbrd}" != "no"])
|
|||
AM_CONDITIONAL([SHARPD], [test "${enable_sharpd}" = "yes"])
|
||||
AM_CONDITIONAL([STATICD], [test "${enable_staticd}" != "no"])
|
||||
AM_CONDITIONAL([FABRICD], [test "${enable_fabricd}" != "no"])
|
||||
AM_CONDITIONAL([VRRPD], [test "${enable_vrrpd}" != "no"])
|
||||
|
||||
if test "${enable_bgp_announce}" = "no";then
|
||||
AC_DEFINE([DISABLE_BGP_ANNOUNCE], [1], [Disable BGP installation to zebra])
|
||||
|
|
10
vrrpd/Makefile
Normal file
10
vrrpd/Makefile
Normal file
|
@ -0,0 +1,10 @@
|
|||
all: ALWAYS
|
||||
@$(MAKE) -s -C .. vrrp/vrrp
|
||||
%: ALWAYS
|
||||
@$(MAKE) -s -C .. vrrp/$@
|
||||
|
||||
Makefile:
|
||||
#nothing
|
||||
ALWAYS:
|
||||
.PHONY: ALWAYS makefiles
|
||||
.SUFFIXES:
|
32
vrrpd/subdir.am
Normal file
32
vrrpd/subdir.am
Normal file
|
@ -0,0 +1,32 @@
|
|||
#
|
||||
# vrrpd
|
||||
#
|
||||
|
||||
if VRRPD
|
||||
noinst_LIBRARIES += vrrpd/libvrrp.a
|
||||
sbin_PROGRAMS += vrrpd/vrrpd
|
||||
# dist_examples_DATA += staticd/staticd.conf.sample
|
||||
vtysh_scan += $(top_srcdir)/vrrpd/vrrp_vty.c
|
||||
man8 += $(MANBUILD)/vrrpd.8
|
||||
endif
|
||||
|
||||
vrrpd_libvrrp_a_SOURCES = \
|
||||
vrrpd/vrrp_memory.c \
|
||||
vrrpd/vrrp_zebra.c \
|
||||
vrrpd/vrrp_vty.c \
|
||||
vrrpd/vrrp_packet.c \
|
||||
vrrpd/vrrp.c \
|
||||
# end
|
||||
|
||||
noinst_HEADERS += \
|
||||
vrrpd/vrrp_memory.h \
|
||||
vrrpd/vrrp_zebra.h \
|
||||
vrrpd/vrrp_vty.h \
|
||||
vrrpd/vrrp.h \
|
||||
# end
|
||||
|
||||
vrrpd/vrrp_vty_clippy.c: $(CLIPPY_DEPS)
|
||||
vrrpd/vrrp_vty.$(OBJEXT): vrrpd/vrrp_vty_clippy.c
|
||||
|
||||
vrrpd_vrrpd_SOURCES = vrrpd/vrrp_main.c
|
||||
vrrpd_vrrpd_LDADD = vrrpd/libvrrp.a lib/libfrr.la @LIBCAP@
|
351
vrrpd/vrrp.c
Normal file
351
vrrpd/vrrp.c
Normal file
|
@ -0,0 +1,351 @@
|
|||
/*
|
||||
* VRRPD global definitions
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "memory.h"
|
||||
#include "if.h"
|
||||
#include "linklist.h"
|
||||
#include "prefix.h"
|
||||
#include "hash.h"
|
||||
#include "vrf.h"
|
||||
#include "hook.h"
|
||||
|
||||
#include "vrrp.h"
|
||||
|
||||
/* Utility functions ------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Sets an ethaddr to RFC-defined Virtual Router MAC address.
|
||||
*
|
||||
* mac
|
||||
* ethaddr to set
|
||||
*
|
||||
* v6
|
||||
* Whether this is a V6 or V4 Virtual Router MAC
|
||||
*
|
||||
* vrid
|
||||
* Virtual Router Identifier
|
||||
*/
|
||||
static void vrrp_mac_set(struct ethaddr *mac, bool v6, uint8_t vrid)
|
||||
{
|
||||
/*
|
||||
* V4: 00-00-5E-00-01-{VRID}
|
||||
* V6: 00-00-5E-00-02-{VRID}
|
||||
*/
|
||||
mac->octet[0] = 0x00;
|
||||
mac->octet[1] = 0x00;
|
||||
mac->octet[2] = 0x5E;
|
||||
mac->octet[3] = 0x00;
|
||||
mac->octet[4] = v6 ? 0x02 : 0x01;
|
||||
mac->octet[5] = vrid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets advertisement_interval and master_adver_interval on a Virtual Router,
|
||||
* then recalculates and sets skew_time and master_down_interval based on these
|
||||
* values.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router to operate on
|
||||
*
|
||||
* advertisement_interval
|
||||
* Advertisement_Interval to set
|
||||
*
|
||||
* master_adver_interval
|
||||
* Master_Adver_Interval to set
|
||||
*/
|
||||
static void vrrp_update_times(struct vrrp_vrouter *vr, uint16_t advertisement_interval,
|
||||
uint16_t master_adver_interval)
|
||||
{
|
||||
vr->advertisement_interval = advertisement_interval;
|
||||
vr->master_adver_interval = master_adver_interval;
|
||||
vr->skew_time = (256 - vr->priority) * vr->master_adver_interval;
|
||||
vr->skew_time /= 256;
|
||||
vr->master_down_interval = (3 * vr->master_adver_interval);
|
||||
vr->master_down_interval /= 256;
|
||||
}
|
||||
|
||||
struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid)
|
||||
{
|
||||
struct vrrp_vrouter *vr =
|
||||
XCALLOC(MTYPE_TMP, sizeof(struct vrrp_vrouter));
|
||||
|
||||
vr->sock = -1;
|
||||
vr->ifp = ifp;
|
||||
vr->vrid = vrid;
|
||||
vr->v4 = list_new();
|
||||
vr->v6 = list_new();
|
||||
vr->advint = VRRP_DEFAULT_ADVINT;
|
||||
vr->is_master = false;
|
||||
vr->priority = VRRP_DEFAULT_PRIORITY;
|
||||
vr->advertisement_interval = VRRP_DEFAULT_ADVINT;
|
||||
vr->master_adver_interval = 0;
|
||||
vr->skew_time = 0;
|
||||
vr->master_down_interval = 0;
|
||||
vr->preempt_mode = true;
|
||||
vr->accept_mode = false;
|
||||
vrrp_mac_set(&vr->vr_mac_v4, false, vrid);
|
||||
vrrp_mac_set(&vr->vr_mac_v6, true, vrid);
|
||||
vr->fsm.state = VRRP_STATE_INITIALIZE;
|
||||
|
||||
hash_get(vrrp_vrouters_hash, vr, hash_alloc_intern);
|
||||
|
||||
return vr;
|
||||
}
|
||||
|
||||
struct vrrp_vrouter *vrrp_lookup(uint8_t vrid)
|
||||
{
|
||||
struct vrrp_vrouter vr;
|
||||
vr.vrid = vrid;
|
||||
|
||||
return hash_lookup(vrrp_vrouters_hash, &vr);
|
||||
}
|
||||
|
||||
/* Network ----------------------------------------------------------------- */
|
||||
|
||||
/*
|
||||
* Create and broadcast VRRP ADVERTISEMENT message.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router for which to send ADVERTISEMENT
|
||||
*/
|
||||
static void vrrp_send_advertisement(struct vrrp_vrouter *vr)
|
||||
{
|
||||
}
|
||||
|
||||
/* FIXME:
|
||||
static void vrrp_recv_advertisement(struct thread *thread)
|
||||
{
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Create Virtual Router listen socket and join it to the VRRP multicast group.
|
||||
*
|
||||
* The first connected address on the Virtual Router's interface is used as the
|
||||
* interface address.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router for which to create listen socket
|
||||
*/
|
||||
static int vrrp_socket(struct vrrp_vrouter *vr)
|
||||
{
|
||||
struct ip_mreqn req;
|
||||
int ret;
|
||||
|
||||
vr->sock = socket(AF_INET, SOCK_RAW, IPPROTO_VRRP);
|
||||
|
||||
if (vr->sock < 0) {
|
||||
/* FIXME */
|
||||
}
|
||||
|
||||
/* Join the multicast group.*/
|
||||
|
||||
/* FIXME: Use first address on the interface and for imr_interface */
|
||||
struct connected *c = listhead(vr->ifp->connected)->data;
|
||||
struct in_addr v4 = c->address->u.prefix4;
|
||||
|
||||
memset(&req, 0, sizeof(req));
|
||||
req.imr_multiaddr.s_addr = htonl(VRRP_MCAST_GROUP_HEX);
|
||||
req.imr_address = v4;
|
||||
req.imr_ifindex = 0; // FIXME: vr->ifp->ifindex ?
|
||||
ret = setsockopt(vr->sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&req,
|
||||
sizeof(struct ip_mreq));
|
||||
if (ret < 0) {
|
||||
// int err = errno;
|
||||
/* VRRP_LOG(("cant do IP_ADD_MEMBERSHIP errno=%d\n", err)); */
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* State machine ----------------------------------------------------------- */
|
||||
|
||||
DEFINE_HOOK(vrrp_change_state_hook, (struct vrrp_vrouter *vr, int to), (vr, to));
|
||||
|
||||
/*
|
||||
* Handle any necessary actions during state change to MASTER state.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router to operate on
|
||||
*/
|
||||
static void vrrp_change_state_master(struct vrrp_vrouter *vr)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle any necessary actions during state change to BACKUP state.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router to operate on
|
||||
*/
|
||||
static void vrrp_change_state_backup(struct vrrp_vrouter *vr)
|
||||
{
|
||||
/* Uninstall ARP entry for vrouter MAC */
|
||||
/* ... */
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle any necessary actions during state change to INITIALIZE state.
|
||||
*
|
||||
* This is not called for initial startup, only when transitioning from MASTER
|
||||
* or BACKUP.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router to operate on
|
||||
*/
|
||||
static void vrrp_change_state_initialize(struct vrrp_vrouter *vr)
|
||||
{
|
||||
}
|
||||
|
||||
void (*vrrp_change_state_handlers[])(struct vrrp_vrouter *vr) = {
|
||||
[VRRP_STATE_MASTER] = vrrp_change_state_master,
|
||||
[VRRP_STATE_BACKUP] = vrrp_change_state_backup,
|
||||
[VRRP_STATE_INITIALIZE] = vrrp_change_state_initialize,
|
||||
};
|
||||
|
||||
/*
|
||||
* Change Virtual Router FSM position. Handles transitional actions and calls
|
||||
* any subscribers to the state change hook.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router for which to change state
|
||||
*
|
||||
* to
|
||||
* State to change to
|
||||
*/
|
||||
static void vrrp_change_state(struct vrrp_vrouter *vr, int to)
|
||||
{
|
||||
/* Call our handlers, then any subscribers */
|
||||
vrrp_change_state_handlers[to](vr);
|
||||
hook_call(vrrp_change_state_hook, vr, to);
|
||||
vr->fsm.state = to;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when Adver_Timer expires.
|
||||
*/
|
||||
static int vrrp_adver_timer_expire(struct thread *thread)
|
||||
{
|
||||
struct vrrp_vrouter *vr = thread->arg;
|
||||
|
||||
if (vr->fsm.state == VRRP_STATE_BACKUP) {
|
||||
vrrp_send_advertisement(vr);
|
||||
/* FIXME: vrrp_send_gratuitous_arp(vr); */
|
||||
} else if (vr->fsm.state == VRRP_STATE_MASTER) {
|
||||
|
||||
} else if (vr->fsm.state == VRRP_STATE_INITIALIZE) {
|
||||
assert(!"FUCK");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when Master_Down timer expires.
|
||||
*/
|
||||
static int vrrp_master_down_timer_expire(struct thread *thread)
|
||||
{
|
||||
/* struct vrrp_vrouter *vr = thread->arg; */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Event handler for Startup event.
|
||||
*
|
||||
* Creates sockets, sends advertisements and ARP requests, starts timers,
|
||||
* updates state machine.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router on which to apply Startup event
|
||||
*/
|
||||
static void vrrp_startup(struct vrrp_vrouter *vr)
|
||||
{
|
||||
/* Create socket */
|
||||
vrrp_socket(vr);
|
||||
|
||||
/* Schedule listener */
|
||||
/* ... */
|
||||
|
||||
if (vr->priority == VRRP_PRIO_MASTER) {
|
||||
vrrp_send_advertisement(vr);
|
||||
/* FIXME: vrrp_send_gratuitous_arp(vr); */
|
||||
|
||||
thread_add_timer_msec(master, vrrp_adver_timer_expire, vr,
|
||||
vr->advertisement_interval * 10,
|
||||
&vr->t_adver_timer);
|
||||
vrrp_change_state(vr, VRRP_STATE_MASTER);
|
||||
} else {
|
||||
vrrp_update_times(vr, vr->advertisement_interval,
|
||||
vr->advertisement_interval);
|
||||
thread_add_timer_msec(master, vrrp_master_down_timer_expire, vr,
|
||||
vr->master_down_interval * 10,
|
||||
&vr->t_master_down_timer);
|
||||
vrrp_change_state(vr, VRRP_STATE_BACKUP);
|
||||
}
|
||||
}
|
||||
|
||||
static void vrrp_shutdown(struct vrrp_vrouter *vr)
|
||||
{
|
||||
/* NOTHING */
|
||||
}
|
||||
|
||||
static void (*vrrp_event_handlers[])(struct vrrp_vrouter *vr) = {
|
||||
[VRRP_EVENT_STARTUP] = vrrp_startup,
|
||||
[VRRP_EVENT_SHUTDOWN] = vrrp_shutdown,
|
||||
};
|
||||
|
||||
/*
|
||||
* Spawn a VRRP FSM event on a Virtual Router.
|
||||
*
|
||||
* vr
|
||||
* Virtual Router on which to spawn event
|
||||
*
|
||||
* event
|
||||
* The event to spawn
|
||||
*/
|
||||
void vrrp_event(struct vrrp_vrouter *vr, int event)
|
||||
{
|
||||
vrrp_event_handlers[event](vr);
|
||||
}
|
||||
|
||||
|
||||
/* Other ------------------------------------------------------------------- */
|
||||
|
||||
static unsigned int vrrp_hash_key(void *arg)
|
||||
{
|
||||
struct vrrp_vrouter *vr = arg;
|
||||
|
||||
return vr->vrid;
|
||||
}
|
||||
|
||||
static bool vrrp_hash_cmp(const void *arg1, const void *arg2)
|
||||
{
|
||||
const struct vrrp_vrouter *vr1 = arg1;
|
||||
const struct vrrp_vrouter *vr2 = arg2;
|
||||
|
||||
return vr1->vrid > vr2->vrid;
|
||||
}
|
||||
|
||||
void vrrp_init(void)
|
||||
{
|
||||
vrrp_vrouters_hash = hash_create(&vrrp_hash_key, vrrp_hash_cmp,
|
||||
"VRRP virtual router hash");
|
||||
vrf_init(NULL, NULL, NULL, NULL, NULL);
|
||||
}
|
162
vrrpd/vrrp.h
Normal file
162
vrrpd/vrrp.h
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
* VRRPD global definitions
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __VRRP_H__
|
||||
#define __VRRP_H_
|
||||
|
||||
#include <zebra.h>
|
||||
#include "linklist.h"
|
||||
#include "hash.h"
|
||||
#include "if.h"
|
||||
#include "thread.h"
|
||||
#include "hook.h"
|
||||
|
||||
/* Global definitions */
|
||||
#define VRRP_DEFAULT_ADVINT 100
|
||||
#define VRRP_DEFAULT_PRIORITY 100
|
||||
#define VRRP_PRIO_MASTER 255
|
||||
#define VRRP_MCAST_GROUP "224.0.0.18"
|
||||
#define VRRP_MCAST_GROUP_HEX 0xe0000012
|
||||
#define IPPROTO_VRRP 112
|
||||
|
||||
/* threadmaster */
|
||||
extern struct thread_master *master;
|
||||
|
||||
/* Global hash of all Virtual Routers */
|
||||
struct hash *vrrp_vrouters_hash;
|
||||
|
||||
/*
|
||||
* VRRP Virtual Router
|
||||
*/
|
||||
struct vrrp_vrouter {
|
||||
/* Socket */
|
||||
int sock;
|
||||
|
||||
/* Interface */
|
||||
struct interface *ifp;
|
||||
|
||||
/* Virtual Router Identifier */
|
||||
uint32_t vrid;
|
||||
|
||||
/* One or more IPv4 addresses associated with this Virtual Router. */
|
||||
struct list *v4;
|
||||
|
||||
/*
|
||||
* One ore more IPv6 addresses associated with this Virtual Router. The
|
||||
* first address must be the Link-Local address associated with the
|
||||
* virtual router.
|
||||
*/
|
||||
struct list *v6;
|
||||
|
||||
/* Time between ADVERTISEMENTS (centiseconds) */
|
||||
int advint;
|
||||
|
||||
/* Whether this VRRP Router is currently the master */
|
||||
bool is_master;
|
||||
|
||||
/* Priority */
|
||||
uint8_t priority;
|
||||
|
||||
/*
|
||||
* Time interval between ADVERTISEMENTS (centiseconds). Default is 100
|
||||
* centiseconds (1 second).
|
||||
*/
|
||||
uint16_t advertisement_interval;
|
||||
/*
|
||||
* Advertisement interval contained in ADVERTISEMENTS received from the
|
||||
* Master (centiseconds)
|
||||
*/
|
||||
uint16_t master_adver_interval;
|
||||
|
||||
/*
|
||||
* Time to skew Master_Down_Interval in centiseconds. Calculated as:
|
||||
* (((256 - priority) * Master_Adver_Interval) / 256)
|
||||
*/
|
||||
uint16_t skew_time;
|
||||
|
||||
/*
|
||||
* Time interval for Backup to declare Master down (centiseconds).
|
||||
* Calculated as:
|
||||
* (3 * Master_Adver_Interval) + Skew_time
|
||||
*/
|
||||
uint16_t master_down_interval;
|
||||
|
||||
/*
|
||||
* Controls whether a (starting or restarting) higher-priority Backup
|
||||
* router preempts a lower-priority Master router. Values are True to
|
||||
* allow preemption and False to prohibit preemption. Default is True.
|
||||
*/
|
||||
bool preempt_mode;
|
||||
|
||||
/*
|
||||
* Controls whether a virtual router in Master state will accept
|
||||
* packets addressed to the address owner's IPvX address as its own if
|
||||
* it is not the IPvX address owner. The default is False.
|
||||
*/
|
||||
bool accept_mode;
|
||||
|
||||
/*
|
||||
* The MAC address used for the source MAC address in VRRP
|
||||
* advertisements and advertised in ARP responses as the MAC address to
|
||||
* use for IP_Addresses.
|
||||
*/
|
||||
struct ethaddr vr_mac_v4;
|
||||
struct ethaddr vr_mac_v6;
|
||||
|
||||
struct thread *t_master_down_timer;
|
||||
struct thread *t_adver_timer;
|
||||
|
||||
struct {
|
||||
int state;
|
||||
} fsm;
|
||||
};
|
||||
|
||||
/* State machine */
|
||||
#define VRRP_STATE_INITIALIZE 1
|
||||
#define VRRP_STATE_MASTER 2
|
||||
#define VRRP_STATE_BACKUP 3
|
||||
#define VRRP_EVENT_STARTUP 1
|
||||
#define VRRP_EVENT_SHUTDOWN 2
|
||||
|
||||
DECLARE_HOOK(vrrp_change_state_hook, (struct vrrp_vrouter *vr, int to), (vr, to));
|
||||
void vrrp_event(struct vrrp_vrouter *vr, int event);
|
||||
/* End state machine */
|
||||
|
||||
|
||||
/*
|
||||
* Initialize VRRP global datastructures.
|
||||
*/
|
||||
void vrrp_init(void);
|
||||
|
||||
/*
|
||||
* Create and register a new VRRP Virtual Router.
|
||||
*/
|
||||
struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid);
|
||||
|
||||
/*
|
||||
* Find VRRP Virtual Router by Virtual Router ID
|
||||
*/
|
||||
struct vrrp_vrouter *vrrp_lookup(uint8_t vrid);
|
||||
|
||||
/*
|
||||
* Trigger VRRP event
|
||||
*/
|
||||
void vrrp_event(struct vrrp_vrouter *vr, int event);
|
||||
|
||||
#endif
|
151
vrrpd/vrrp_main.c
Normal file
151
vrrpd/vrrp_main.c
Normal file
|
@ -0,0 +1,151 @@
|
|||
/*
|
||||
* VRRP
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include <lib/version.h>
|
||||
#include "getopt.h"
|
||||
#include "thread.h"
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
#include "memory.h"
|
||||
#include "privs.h"
|
||||
#include "sigevent.h"
|
||||
#include "libfrr.h"
|
||||
#include "vrf.h"
|
||||
#include "nexthop.h"
|
||||
#include "filter.h"
|
||||
|
||||
#include "vrrp.h"
|
||||
#include "vrrp_zebra.h"
|
||||
#include "vrrp_vty.h"
|
||||
|
||||
char backup_config_file[256];
|
||||
|
||||
zebra_capabilities_t _caps_p[] = {
|
||||
};
|
||||
|
||||
struct zebra_privs_t vrrp_privs = {
|
||||
#if defined(FRR_USER) && defined(FRR_GROUP)
|
||||
.user = FRR_USER,
|
||||
.group = FRR_GROUP,
|
||||
#endif
|
||||
#if defined(VTY_GROUP)
|
||||
.vty_group = VTY_GROUP,
|
||||
#endif
|
||||
.caps_p = _caps_p,
|
||||
.cap_num_p = array_size(_caps_p),
|
||||
.cap_num_i = 0};
|
||||
|
||||
struct option longopts[] = { { 0 } };
|
||||
|
||||
/* Master of threads. */
|
||||
struct thread_master *master;
|
||||
|
||||
/* SIGHUP handler. */
|
||||
static void sighup(void)
|
||||
{
|
||||
zlog_info("SIGHUP received");
|
||||
}
|
||||
|
||||
/* SIGINT / SIGTERM handler. */
|
||||
static void sigint(void)
|
||||
{
|
||||
zlog_notice("Terminating on signal");
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* SIGUSR1 handler. */
|
||||
static void sigusr1(void)
|
||||
{
|
||||
zlog_rotate();
|
||||
}
|
||||
|
||||
struct quagga_signal_t vrrp_signals[] = {
|
||||
{
|
||||
.signal = SIGHUP,
|
||||
.handler = &sighup,
|
||||
},
|
||||
{
|
||||
.signal = SIGUSR1,
|
||||
.handler = &sigusr1,
|
||||
},
|
||||
{
|
||||
.signal = SIGINT,
|
||||
.handler = &sigint,
|
||||
},
|
||||
{
|
||||
.signal = SIGTERM,
|
||||
.handler = &sigint,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct frr_yang_module_info *vrrp_yang_modules[] = {
|
||||
};
|
||||
|
||||
#define VRRP_VTY_PORT 2617
|
||||
|
||||
FRR_DAEMON_INFO(vrrpd, VRRP, .vty_port = VRRP_VTY_PORT,
|
||||
.proghelp = "Virtual Router Redundancy Protocol",
|
||||
.signals = vrrp_signals,
|
||||
.n_signals = array_size(vrrp_signals),
|
||||
.privs = &vrrp_privs,
|
||||
.yang_modules = vrrp_yang_modules,
|
||||
.n_yang_modules = array_size(vrrp_yang_modules),
|
||||
)
|
||||
|
||||
int main(int argc, char **argv, char **envp)
|
||||
{
|
||||
frr_preinit(&vrrpd_di, argc, argv);
|
||||
frr_opt_add("", longopts, "");
|
||||
|
||||
while (1) {
|
||||
int opt;
|
||||
|
||||
opt = frr_getopt(argc, argv, NULL);
|
||||
|
||||
if (opt == EOF)
|
||||
break;
|
||||
|
||||
switch (opt) {
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
frr_help_exit(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
master = frr_init();
|
||||
|
||||
vrrp_zebra_init();
|
||||
vrrp_vty_init();
|
||||
vrrp_init();
|
||||
|
||||
snprintf(backup_config_file, sizeof(backup_config_file),
|
||||
"%s/vrrpd.conf", frr_sysconfdir);
|
||||
vrrpd_di.backup_config_file = backup_config_file;
|
||||
|
||||
frr_config_fork();
|
||||
frr_run(master);
|
||||
|
||||
/* Not reached. */
|
||||
return 0;
|
||||
}
|
24
vrrpd/vrrp_memory.c
Normal file
24
vrrpd/vrrp_memory.c
Normal file
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* VRRPD memory types
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
#include <memory.h>
|
||||
#include "vrrp_memory.h"
|
||||
|
||||
DEFINE_MGROUP(VRRP, "vrrpd")
|
27
vrrpd/vrrp_memory.h
Normal file
27
vrrpd/vrrp_memory.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* VRRPD memory types
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __VRRP_MEMORY_H__
|
||||
#define __VRRP_MEMORY_H__
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
DECLARE_MGROUP(VRRP)
|
||||
|
||||
#endif
|
50
vrrpd/vrrp_packet.c
Normal file
50
vrrpd/vrrp_packet.c
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* VRRPD packet crafting
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "ipaddr.h"
|
||||
|
||||
#include "vrrp_packet.h"
|
||||
|
||||
/*
|
||||
* Builds a VRRP packet.
|
||||
*/
|
||||
struct vrrp_pkt *vrrp_pkt_build(uint8_t vrid, uint8_t prio,
|
||||
uint16_t max_adver_int, bool v6, uint8_t numip,
|
||||
void **ips)
|
||||
{
|
||||
size_t addrsz = v6 ? sizeof(struct in6_addr) : sizeof(struct in_addr);
|
||||
struct vrrp_pkt *pkt =
|
||||
XCALLOC(MTYPE_TMP, sizeof(struct vrrp_pkt) + addrsz * numip);
|
||||
|
||||
pkt->version = VRRP_VERSION;
|
||||
pkt->type = VRRP_TYPE_ADVERTISEMENT;
|
||||
pkt->vrid = vrid;
|
||||
pkt->priority = prio;
|
||||
pkt->rsvd = 0;
|
||||
pkt->max_adver_int = max_adver_int;
|
||||
for (uint8_t i = 0; i < numip; i++)
|
||||
memcpy(&pkt->addrs[i].v4, ips[i], addrsz);
|
||||
/* FIXME */
|
||||
pkt->cksum = 0;
|
||||
|
||||
return pkt;
|
||||
}
|
49
vrrpd/vrrp_packet.h
Normal file
49
vrrpd/vrrp_packet.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* VRRPD packet crafting
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "ipaddr.h"
|
||||
#include "prefix.h"
|
||||
|
||||
#define VRRP_VERSION 3
|
||||
#define VRRP_TYPE_ADVERTISEMENT 1
|
||||
|
||||
struct vrrp_pkt {
|
||||
uint8_t version : 4;
|
||||
uint8_t type : 4;
|
||||
uint8_t vrid;
|
||||
uint8_t priority;
|
||||
uint8_t num_ip;
|
||||
uint16_t rsvd : 4;
|
||||
uint16_t max_adver_int : 12;
|
||||
uint16_t cksum;
|
||||
union {
|
||||
struct in_addr v4;
|
||||
struct in6_addr v6;
|
||||
} addrs[];
|
||||
} __attribute((packed, aligned(1)));
|
||||
|
||||
/*
|
||||
* Builds a VRRP packet.
|
||||
*/
|
||||
struct vrrp_pkt *vrrp_pkt_build(uint8_t vrid, uint8_t prio,
|
||||
uint16_t max_adver_int, bool v6, uint8_t numip,
|
||||
void **ips);
|
80
vrrpd/vrrp_vty.c
Normal file
80
vrrpd/vrrp_vty.c
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
* VRRP commands
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "vty.h"
|
||||
#include "if.h"
|
||||
|
||||
#include "vrrp.h"
|
||||
#include "vrrp_vty.h"
|
||||
#include "vrrp_memory.h"
|
||||
//#ifndef VTYSH_EXTRACT_PL
|
||||
//#include "vrrp/vrrp_vty_clippy.c"
|
||||
//#endif
|
||||
|
||||
|
||||
#define VRRP_STR "Virtual Router Redundancy Protocol\n"
|
||||
#define VRRP_VRID_STR "Virtual Router ID\n"
|
||||
|
||||
DEFUN_NOSH (show_debugging_vrrpd,
|
||||
show_debugging_vrrpd_cmd,
|
||||
"show debugging [vrrp]",
|
||||
SHOW_STR
|
||||
DEBUG_STR
|
||||
"VRRP information\n")
|
||||
{
|
||||
vty_out(vty, "VRRP debugging status\n");
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN(vrrp_vrid,
|
||||
vrrp_vrid_cmd,
|
||||
"[no] vrrp (1-255)",
|
||||
NO_STR
|
||||
VRRP_STR
|
||||
VRRP_VRID_STR)
|
||||
{
|
||||
VTY_DECLVAR_CONTEXT(interface, ifp);
|
||||
int idx = 0;
|
||||
uint8_t vrid;
|
||||
|
||||
argv_find(argv, argc, "(1-255)", &idx);
|
||||
vrid = strtoul(argv[idx]->arg, NULL, 10);
|
||||
|
||||
struct vrrp_vrouter *vr = vrrp_vrouter_create(ifp, vrid);
|
||||
vrrp_event(vr, VRRP_EVENT_STARTUP);
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
static struct cmd_node interface_node = {
|
||||
INTERFACE_NODE,
|
||||
"%s(config-if)# ", 1
|
||||
};
|
||||
|
||||
void vrrp_vty_init(void)
|
||||
{
|
||||
install_node(&interface_node, NULL);
|
||||
if_cmd_init();
|
||||
install_element(VIEW_NODE, &show_debugging_vrrpd_cmd);
|
||||
install_element(INTERFACE_NODE, &vrrp_vrid_cmd);
|
||||
}
|
23
vrrpd/vrrp_vty.h
Normal file
23
vrrpd/vrrp_vty.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* VRRP commands
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __VRRP_VTY_H__
|
||||
#define __VRRP_VTY_H__
|
||||
|
||||
void vrrp_vty_init(void);
|
||||
#endif
|
39
vrrpd/vrrp_zebra.c
Normal file
39
vrrpd/vrrp_zebra.c
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Zebra interfacing
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include <zebra.h>
|
||||
|
||||
#include "zclient.h"
|
||||
#include "thread.h"
|
||||
|
||||
#include "vrrp_zebra.h"
|
||||
|
||||
/* Zebra structure to hold current status. */
|
||||
struct thread_master *master;
|
||||
struct zclient *zclient;
|
||||
|
||||
void vrrp_zebra_init(void)
|
||||
{
|
||||
struct zclient_options opt = { .receive_notify = true };
|
||||
|
||||
zclient = zclient_new(master, &opt);
|
||||
|
||||
zclient_init(zclient, 0, 0, &vrrp_privs);
|
||||
}
|
||||
|
29
vrrpd/vrrp_zebra.h
Normal file
29
vrrpd/vrrp_zebra.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Zebra interfacing
|
||||
* Copyright (C) 2018 Cumulus Networks, Inc.
|
||||
* Quentin Young
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; see the file COPYING; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef __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
|
|
@ -42,6 +42,7 @@ DECLARE_MGROUP(MVTYSH)
|
|||
#define VTYSH_STATICD 0x08000
|
||||
#define VTYSH_BFDD 0x10000
|
||||
#define VTYSH_FABRICD 0x20000
|
||||
#define VTYSH_VRRPD 0x40000
|
||||
|
||||
#define VTYSH_WAS_ACTIVE (-2)
|
||||
|
||||
|
|
Loading…
Reference in a new issue