summaryrefslogtreecommitdiffstats
path: root/vrrpd/vrrp.h
diff options
context:
space:
mode:
Diffstat (limited to 'vrrpd/vrrp.h')
-rw-r--r--vrrpd/vrrp.h565
1 files changed, 565 insertions, 0 deletions
diff --git a/vrrpd/vrrp.h b/vrrpd/vrrp.h
new file mode 100644
index 0000000..0ac9b1f
--- /dev/null
+++ b/vrrpd/vrrp.h
@@ -0,0 +1,565 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * VRRP global definitions and state machine.
+ * Copyright (C) 2018-2019 Cumulus Networks, Inc.
+ * Quentin Young
+ */
+#ifndef __VRRP_H__
+#define __VRRP_H__
+
+#include <zebra.h>
+#include <netinet/ip.h>
+
+#include "lib/memory.h"
+#include "lib/hash.h"
+#include "lib/hook.h"
+#include "lib/if.h"
+#include "lib/linklist.h"
+#include "lib/northbound.h"
+#include "lib/privs.h"
+#include "lib/stream.h"
+#include "lib/frrevent.h"
+#include "lib/vty.h"
+
+/* Global definitions */
+#define VRRP_RADV_INT 16
+#define VRRP_PRIO_MASTER 255
+#define VRRP_MCASTV4_GROUP_STR "224.0.0.18"
+#define VRRP_MCASTV6_GROUP_STR "ff02:0:0:0:0:0:0:12"
+#define VRRP_MCASTV4_GROUP 0xe0000012
+#define VRRP_MCASTV6_GROUP 0xff020000000000000000000000000012
+#define IPPROTO_VRRP 112
+
+#define VRRP_LOGPFX_VRID "[VRID %u] "
+#define VRRP_LOGPFX_FAM "[%s] "
+
+/* Default defaults */
+#define VRRP_XPATH_FULL "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group"
+#define VRRP_XPATH "./frr-vrrpd:vrrp/vrrp-group"
+#define VRRP_DEFAULT_PRIORITY 100
+#define VRRP_DEFAULT_ADVINT 100
+#define VRRP_DEFAULT_PREEMPT true
+#define VRRP_DEFAULT_ACCEPT true
+#define VRRP_DEFAULT_CHECKSUM_WITH_IPV4_PSEUDOHEADER true
+#define VRRP_DEFAULT_SHUTDOWN false
+
+/* User compatibility constant */
+#define CS2MS 10
+
+DECLARE_MGROUP(VRRPD);
+
+/* Northbound */
+extern const struct frr_yang_module_info frr_vrrpd_info;
+
+/* Configured defaults */
+struct vrrp_defaults {
+ uint8_t version;
+ uint8_t priority;
+ uint16_t advertisement_interval;
+ bool preempt_mode;
+ bool accept_mode;
+ bool checksum_with_ipv4_pseudoheader;
+ bool shutdown;
+};
+
+extern struct vrrp_defaults vd;
+
+/* threadmaster */
+extern struct event_loop *master;
+
+/* privileges */
+extern struct zebra_privs_t vrrp_privs;
+
+/* Global hash of all Virtual Routers */
+extern struct hash *vrrp_vrouters_hash;
+
+/*
+ * VRRP Router.
+ *
+ * This struct contains all state for a particular VRRP Router operating
+ * in a Virtual Router for either IPv4 or IPv6.
+ */
+struct vrrp_router {
+ /*
+ * Whether this VRRP Router is active.
+ */
+ bool is_active;
+
+ /* Whether we are the address owner */
+ bool is_owner;
+
+ /* Rx socket: Rx from parent of mvl_ifp */
+ int sock_rx;
+ /* Tx socket; Tx from mvl_ifp */
+ int sock_tx;
+
+ /* macvlan interface */
+ struct interface *mvl_ifp;
+
+ /* Source address for advertisements */
+ struct ipaddr src;
+
+ /* Socket read buffer */
+ uint8_t ibuf[IP_MAXPACKET];
+
+ /*
+ * Address family of this Virtual Router.
+ * Either AF_INET or AF_INET6.
+ */
+ int family;
+
+ /*
+ * Virtual Router this VRRP Router is participating in.
+ */
+ struct vrrp_vrouter *vr;
+
+ /*
+ * One or more IPvX addresses associated with this Virtual
+ * Router. The first address must be the "primary" address this
+ * Virtual Router is backing up in the case of IPv4. In the case of
+ * IPv6 it must be the link-local address of vr->ifp.
+ *
+ * Type: struct ipaddr *
+ */
+ struct list *addrs;
+
+ /*
+ * This flag says whether we are waiting on an interface up
+ * notification from Zebra before we send an ADVERTISEMENT.
+ */
+ bool advert_pending;
+
+ /*
+ * If this is an IPv4 VRRP router, this flag says whether we are
+ * waiting on an interface up notification from Zebra before we send
+ * gratuitous ARP packets for all our addresses. Should never be true
+ * if family == AF_INET6.
+ */
+ bool garp_pending;
+ /*
+ * If this is an IPv6 VRRP router, this flag says whether we are
+ * waiting on an interface up notification from Zebra before we send
+ * Unsolicited Neighbor Advertisement packets for all our addresses.
+ * Should never be true if family == AF_INET.
+ */
+ bool ndisc_pending;
+
+ /*
+ * Effective priority
+ * => vr->priority if we are Backup
+ * => 255 if we are Master
+ */
+ uint8_t priority;
+
+ /*
+ * 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;
+
+ /*
+ * The MAC address used for the source MAC address in VRRP
+ * advertisements, advertised in ARP requests/responses, and advertised
+ * in ND Neighbor Advertisements.
+ */
+ struct ethaddr vmac;
+
+ struct {
+ int state;
+ } fsm;
+
+ struct {
+ /* Total number of advertisements sent and received */
+ uint32_t adver_tx_cnt;
+ uint32_t adver_rx_cnt;
+ /* Total number of gratuitous ARPs sent */
+ uint32_t garp_tx_cnt;
+ /* Total number of unsolicited Neighbor Advertisements sent */
+ uint32_t una_tx_cnt;
+ /* Total number of state transitions */
+ uint32_t trans_cnt;
+ } stats;
+
+ struct event *t_master_down_timer;
+ struct event *t_adver_timer;
+ struct event *t_read;
+ struct event *t_write;
+};
+
+/*
+ * VRRP Virtual Router.
+ *
+ * This struct contains all state and configuration for a given Virtual Router
+ * Identifier on a given interface, both v4 and v6.
+ *
+ * RFC5798 s. 1 states:
+ * "Within a VRRP router, the virtual routers in each of the IPv4 and IPv6
+ * address families are a domain unto themselves and do not overlap."
+ *
+ * This implementation has chosen the tuple (interface, VRID) as the key for a
+ * particular VRRP Router, and the rest of the program is designed around this
+ * assumption. Additionally, base protocol configuration parameters such as the
+ * advertisement interval and (configured) priority are shared between v4 and
+ * v6 instances. This corresponds to the choice made by other industrial
+ * implementations.
+ */
+struct vrrp_vrouter {
+ /* Whether this instance was automatically configured */
+ bool autoconf;
+
+ /* Whether this VRRP router is in administrative shutdown */
+ bool shutdown;
+
+ /* Interface */
+ struct interface *ifp;
+
+ /* Version */
+ uint8_t version;
+
+ /* Virtual Router Identifier */
+ uint32_t vrid;
+
+ /* Configured priority */
+ uint8_t priority;
+
+ /*
+ * Time interval between ADVERTISEMENTS (centiseconds). Default is 100
+ * centiseconds (1 second).
+ */
+ uint16_t advertisement_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;
+
+ /*
+ * Indicates whether this router computes and accepts VRRPv3 checksums
+ * without pseudoheader, for device interoperability.
+ *
+ * This option should only affect IPv4 virtual routers.
+ */
+ bool checksum_with_ipv4_pseudoheader;
+
+ struct vrrp_router *v4;
+ struct vrrp_router *v6;
+};
+
+/*
+ * Initialize VRRP global datastructures.
+ */
+void vrrp_init(void);
+
+/*
+ * Destroy all VRRP instances and gracefully shutdown.
+ *
+ * For instances in Master state, VRRP advertisements with 0 priority will be
+ * sent if possible to notify Backup routers that we are going away.
+ */
+void vrrp_fini(void);
+
+
+/* Creation and destruction ------------------------------------------------ */
+
+/*
+ * Create and register a new VRRP Virtual Router.
+ *
+ * ifp
+ * Base interface to configure VRRP on
+ *
+ * vrid
+ * Virtual Router Identifier
+ */
+struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid,
+ uint8_t version);
+
+/*
+ * Destroy a VRRP Virtual Router, freeing all its resources.
+ *
+ * If there are any running VRRP instances, these are stopped and destroyed.
+ */
+void vrrp_vrouter_destroy(struct vrrp_vrouter *vr);
+
+
+/* Configuration controllers ----------------------------------------------- */
+
+/*
+ * Check if a Virtual Router ought to be started, and if so, start it.
+ *
+ * vr
+ * Virtual Router to checkstart
+ */
+void vrrp_check_start(struct vrrp_vrouter *vr);
+
+/*
+ * Change the configured priority of a VRRP Virtual Router.
+ *
+ * Note that this only changes the configured priority of the Virtual Router.
+ * The currently effective priority will not be changed; to change the
+ * effective priority, the Virtual Router must be restarted by issuing a
+ * VRRP_EVENT_SHUTDOWN followed by a VRRP_EVENT_STARTUP.
+ *
+ * vr
+ * Virtual Router to change priority of
+ *
+ * priority
+ * New priority
+ */
+void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority);
+
+/*
+ * Set Advertisement Interval on this Virtual Router.
+ *
+ * vr
+ * Virtual Router to change priority of
+ *
+ * advertisement_interval
+ * New advertisement interval
+ */
+void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr,
+ uint16_t advertisement_interval);
+
+/*
+ * Add an IPvX address to a VRRP Virtual Router.
+ *
+ * vr
+ * Virtual Router to add IPvx address to
+ *
+ * ip
+ * Address to add
+ *
+ * activate
+ * Whether to automatically start the VRRP router if this is the first IP
+ * address added.
+ *
+ * Returns:
+ * -1 on error
+ * 0 otherwise
+ */
+int vrrp_add_ip(struct vrrp_vrouter *vr, struct ipaddr *ip);
+
+/*
+ * Add an IPv4 address to a VRRP Virtual Router.
+ *
+ * vr
+ * Virtual Router to add IPv4 address to
+ *
+ * v4
+ * Address to add
+ *
+ * activate
+ * Whether to automatically start the VRRP router if this is the first IP
+ * address added.
+ *
+ * Returns:
+ * -1 on error
+ * 0 otherwise
+ */
+int vrrp_add_ipv4(struct vrrp_vrouter *vr, struct in_addr v4);
+
+/*
+ * Add an IPv6 address to a VRRP Virtual Router.
+ *
+ * vr
+ * Virtual Router to add IPv6 address to
+ *
+ * v6
+ * Address to add
+ *
+ * activate
+ * Whether to automatically start the VRRP router if this is the first IP
+ * address added.
+ *
+ * Returns:
+ * -1 on error
+ * 0 otherwise
+ */
+int vrrp_add_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6);
+
+/*
+ * Remove an IP address from a VRRP Virtual Router.
+ *
+ * vr
+ * Virtual Router to remove IP address from
+ *
+ * ip
+ * Address to remove
+ *
+ * deactivate
+ * Whether to automatically stop the VRRP router if removing v4 would leave
+ * us with an empty address list. If this is not true and ip is the only IP
+ * address backed up by this virtual router, this function will not remove
+ * the address and return failure.
+ *
+ * Returns:
+ * -1 on error
+ * 0 otherwise
+ */
+int vrrp_del_ip(struct vrrp_vrouter *vr, struct ipaddr *ip);
+
+/*
+ * Remove an IPv4 address from a VRRP Virtual Router.
+ *
+ * vr
+ * Virtual Router to remove IPv4 address from
+ *
+ * v4
+ * Address to remove
+ *
+ * deactivate
+ * Whether to automatically stop the VRRP router if removing v4 would leave
+ * us with an empty address list. If this is not true and v4 is the only
+ * IPv4 address backed up by this virtual router, this function will not
+ * remove the address and return failure.
+ *
+ * Returns:
+ * -1 on error
+ * 0 otherwise
+ */
+int vrrp_del_ipv4(struct vrrp_vrouter *vr, struct in_addr v4);
+
+/*
+ * Remove an IPv6 address from a VRRP Virtual Router.
+ *
+ * vr
+ * Virtual Router to remove IPv6 address from
+ *
+ * v6
+ * Address to remove
+ *
+ * deactivate
+ * Whether to automatically stop the VRRP router if removing v5 would leave
+ * us with an empty address list. If this is not true and v4 is the only
+ * IPv6 address backed up by this virtual router, this function will not
+ * remove the address and return failure.
+ *
+ * Returns:
+ * -1 on error
+ * 0 otherwise
+ */
+int vrrp_del_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6);
+
+/* State machine ----------------------------------------------------------- */
+
+#define VRRP_STATE_INITIALIZE 0
+#define VRRP_STATE_MASTER 1
+#define VRRP_STATE_BACKUP 2
+#define VRRP_EVENT_STARTUP 0
+#define VRRP_EVENT_SHUTDOWN 1
+
+extern const char *const vrrp_state_names[3];
+
+/*
+ * This hook called whenever the state of a Virtual Router changes, after the
+ * specific internal state handlers have run.
+ *
+ * Use this if you need to react to state changes to perform non-critical
+ * tasks. Critical tasks should go in the internal state change handlers.
+ */
+DECLARE_HOOK(vrrp_change_state_hook, (struct vrrp_router *r, int to), (r, to));
+
+/*
+ * Trigger a VRRP event on a given Virtual Router..
+ *
+ * vr
+ * Virtual Router to operate on
+ *
+ * event
+ * Event to kick off. All event related processing will have completed upon
+ * return of this function.
+ *
+ * Returns:
+ * < 0 if the event created an error
+ * 0 otherwise
+ */
+int vrrp_event(struct vrrp_router *r, int event);
+
+/* Autoconfig -------------------------------------------------------------- */
+
+/*
+ * Search for and automatically configure VRRP instances on interfaces.
+ *
+ * ifp
+ * Interface to autoconfig. If it is a macvlan interface and has a VRRP MAC,
+ * a VRRP instance corresponding to VMAC assigned to macvlan will be created
+ * on the parent interface and all addresses on the macvlan interface except
+ * the v6 link local will be configured as VRRP addresses. If NULL, this
+ * treatment will be applied to all existing interfaces matching the above
+ * criterion.
+ *
+ * Returns:
+ * -1 on failure
+ * 0 otherwise
+ */
+int vrrp_autoconfig(void);
+
+/*
+ * Enable autoconfiguration.
+ *
+ * Calling this function will cause vrrpd to automatically configure VRRP
+ * instances on existing compatible macvlan interfaces. These instances will
+ * react to interface up/down and address add/delete events to keep themselves
+ * in sync with the available interfaces.
+ *
+ * version
+ * VRRP version to use for autoconfigured instances. Must be 2 or 3.
+ */
+void vrrp_autoconfig_on(int version);
+
+/*
+ * Disable autoconfiguration.
+ *
+ * Calling this function will delete all existing autoconfigured VRRP instances.
+ */
+void vrrp_autoconfig_off(void);
+
+/* Interface Tracking ------------------------------------------------------ */
+
+void vrrp_if_add(struct interface *ifp);
+void vrrp_if_del(struct interface *ifp);
+void vrrp_if_up(struct interface *ifp);
+void vrrp_if_down(struct interface *ifp);
+void vrrp_if_address_add(struct interface *ifp);
+void vrrp_if_address_del(struct interface *ifp);
+
+/* Other ------------------------------------------------------------------- */
+
+/*
+ * Write global level configuration to vty.
+ *
+ * vty
+ * vty to write config to
+ *
+ * Returns:
+ * # of lines written
+ */
+int vrrp_config_write_global(struct vty *vty);
+
+/*
+ * Find VRRP Virtual Router by Virtual Router ID
+ */
+struct vrrp_vrouter *vrrp_lookup(const struct interface *ifp, uint8_t vrid);
+
+#endif /* __VRRP_H__ */