diff options
| author | Quentin Young <qlyoung@cumulusnetworks.com> | 2018-11-19 20:51:52 +0000 | 
|---|---|---|
| committer | Quentin Young <qlyoung@cumulusnetworks.com> | 2019-05-17 00:27:08 +0000 | 
| commit | 5435a2bf61c4179e8b69af5d3a808b42f5387177 (patch) | |
| tree | f4f0f9f8b0d7304d84360928f31f640740c8fcde /vrrpd | |
| parent | db95656d48ecc46555fc9e8524849aa73a357dcb (diff) | |
vrrpd: initial commit
Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
Diffstat (limited to 'vrrpd')
| -rw-r--r-- | vrrpd/Makefile | 10 | ||||
| -rw-r--r-- | vrrpd/subdir.am | 32 | ||||
| -rw-r--r-- | vrrpd/vrrp.c | 351 | ||||
| -rw-r--r-- | vrrpd/vrrp.h | 162 | ||||
| -rw-r--r-- | vrrpd/vrrp_main.c | 151 | ||||
| -rw-r--r-- | vrrpd/vrrp_memory.c | 24 | ||||
| -rw-r--r-- | vrrpd/vrrp_memory.h | 27 | ||||
| -rw-r--r-- | vrrpd/vrrp_packet.c | 50 | ||||
| -rw-r--r-- | vrrpd/vrrp_packet.h | 49 | ||||
| -rw-r--r-- | vrrpd/vrrp_vty.c | 80 | ||||
| -rw-r--r-- | vrrpd/vrrp_vty.h | 23 | ||||
| -rw-r--r-- | vrrpd/vrrp_zebra.c | 39 | ||||
| -rw-r--r-- | vrrpd/vrrp_zebra.h | 29 | 
13 files changed, 1027 insertions, 0 deletions
diff --git a/vrrpd/Makefile b/vrrpd/Makefile new file mode 100644 index 0000000000..027c6ee1f8 --- /dev/null +++ b/vrrpd/Makefile @@ -0,0 +1,10 @@ +all: ALWAYS +	@$(MAKE) -s -C .. vrrp/vrrp +%: ALWAYS +	@$(MAKE) -s -C .. vrrp/$@ + +Makefile: +	#nothing +ALWAYS: +.PHONY: ALWAYS makefiles +.SUFFIXES: diff --git a/vrrpd/subdir.am b/vrrpd/subdir.am new file mode 100644 index 0000000000..40dee9c145 --- /dev/null +++ b/vrrpd/subdir.am @@ -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@ diff --git a/vrrpd/vrrp.c b/vrrpd/vrrp.c new file mode 100644 index 0000000000..2cc0896605 --- /dev/null +++ b/vrrpd/vrrp.c @@ -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); +} diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h new file mode 100644 index 0000000000..308e3a8e10 --- /dev/null +++ b/vrrpd/vrrp.h @@ -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 diff --git a/vrrpd/vrrp_main.c b/vrrpd/vrrp_main.c new file mode 100644 index 0000000000..8c73375c9d --- /dev/null +++ b/vrrpd/vrrp_main.c @@ -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; +} diff --git a/vrrpd/vrrp_memory.c b/vrrpd/vrrp_memory.c new file mode 100644 index 0000000000..4a7c0b7e42 --- /dev/null +++ b/vrrpd/vrrp_memory.c @@ -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") diff --git a/vrrpd/vrrp_memory.h b/vrrpd/vrrp_memory.h new file mode 100644 index 0000000000..f57a864804 --- /dev/null +++ b/vrrpd/vrrp_memory.h @@ -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 diff --git a/vrrpd/vrrp_packet.c b/vrrpd/vrrp_packet.c new file mode 100644 index 0000000000..4cbcd771f2 --- /dev/null +++ b/vrrpd/vrrp_packet.c @@ -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; +} diff --git a/vrrpd/vrrp_packet.h b/vrrpd/vrrp_packet.h new file mode 100644 index 0000000000..04116c6245 --- /dev/null +++ b/vrrpd/vrrp_packet.h @@ -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); diff --git a/vrrpd/vrrp_vty.c b/vrrpd/vrrp_vty.c new file mode 100644 index 0000000000..f438c24895 --- /dev/null +++ b/vrrpd/vrrp_vty.c @@ -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); +} diff --git a/vrrpd/vrrp_vty.h b/vrrpd/vrrp_vty.h new file mode 100644 index 0000000000..2aa47ec20d --- /dev/null +++ b/vrrpd/vrrp_vty.h @@ -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 diff --git a/vrrpd/vrrp_zebra.c b/vrrpd/vrrp_zebra.c new file mode 100644 index 0000000000..c96f9a5646 --- /dev/null +++ b/vrrpd/vrrp_zebra.c @@ -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); +} + diff --git a/vrrpd/vrrp_zebra.h b/vrrpd/vrrp_zebra.h new file mode 100644 index 0000000000..be6338f17f --- /dev/null +++ b/vrrpd/vrrp_zebra.h @@ -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  | 
