2018-11-19 21:51:52 +01:00
|
|
|
/*
|
2018-12-06 22:31:05 +01:00
|
|
|
* VRRPD global definitions and state machine
|
2018-11-19 21:51:52 +01:00
|
|
|
* 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
|
|
|
|
*/
|
2018-11-30 09:45:36 +01:00
|
|
|
#ifndef _VRRP_H
|
|
|
|
#define _VRRP_H
|
2018-11-19 21:51:52 +01:00
|
|
|
|
|
|
|
#include <zebra.h>
|
2018-12-19 17:48:36 +01:00
|
|
|
#include <netinet/ip.h>
|
2018-12-06 22:31:05 +01:00
|
|
|
|
|
|
|
#include "lib/hash.h"
|
|
|
|
#include "lib/hook.h"
|
|
|
|
#include "lib/if.h"
|
|
|
|
#include "lib/linklist.h"
|
|
|
|
#include "lib/privs.h"
|
2018-12-19 17:48:36 +01:00
|
|
|
#include "lib/stream.h"
|
2018-12-06 22:31:05 +01:00
|
|
|
#include "lib/thread.h"
|
2018-11-19 21:51:52 +01:00
|
|
|
|
|
|
|
/* Global definitions */
|
|
|
|
#define VRRP_DEFAULT_ADVINT 100
|
|
|
|
#define VRRP_DEFAULT_PRIORITY 100
|
|
|
|
#define VRRP_PRIO_MASTER 255
|
2018-12-11 18:55:21 +01:00
|
|
|
#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
|
2018-11-19 21:51:52 +01:00
|
|
|
#define IPPROTO_VRRP 112
|
|
|
|
|
2018-12-08 01:16:27 +01:00
|
|
|
#define VRRP_LOGPFX_VRID "[VRID: %u] "
|
|
|
|
|
2018-11-19 21:51:52 +01:00
|
|
|
/* threadmaster */
|
|
|
|
extern struct thread_master *master;
|
|
|
|
|
2018-12-04 21:41:37 +01:00
|
|
|
/* privileges */
|
|
|
|
extern struct zebra_privs_t vrrp_privs;
|
|
|
|
|
2018-11-19 21:51:52 +01:00
|
|
|
/* Global hash of all Virtual Routers */
|
|
|
|
struct hash *vrrp_vrouters_hash;
|
|
|
|
|
|
|
|
/*
|
2018-12-11 18:55:21 +01:00
|
|
|
* VRRP Router.
|
|
|
|
*
|
|
|
|
* This struct contains all state for a particular VRRP Router operating in a
|
|
|
|
* Virtual Router for either IPv4 or IPv6.
|
2018-11-19 21:51:52 +01:00
|
|
|
*/
|
2018-12-11 18:55:21 +01:00
|
|
|
struct vrrp_router {
|
|
|
|
/*
|
|
|
|
* Whether this VRRP Router is active.
|
|
|
|
*/
|
|
|
|
bool is_active;
|
|
|
|
|
2019-01-07 20:02:53 +01:00
|
|
|
/* 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;
|
2018-11-19 21:51:52 +01:00
|
|
|
|
2018-12-19 17:48:36 +01:00
|
|
|
/* Socket read buffer */
|
|
|
|
uint8_t ibuf[IP_MAXPACKET];
|
|
|
|
|
2018-12-11 18:55:21 +01:00
|
|
|
/*
|
|
|
|
* Address family of this Virtual Router.
|
|
|
|
* Either AF_INET or AF_INET6.
|
|
|
|
*/
|
|
|
|
int family;
|
2018-11-19 21:51:52 +01:00
|
|
|
|
|
|
|
/*
|
2018-12-11 18:55:21 +01:00
|
|
|
* Virtual Router this VRRP Router is participating in.
|
2018-11-19 21:51:52 +01:00
|
|
|
*/
|
2018-12-11 18:55:21 +01:00
|
|
|
struct vrrp_vrouter *vr;
|
2018-11-19 21:51:52 +01:00
|
|
|
|
2018-12-11 18:55:21 +01:00
|
|
|
/*
|
|
|
|
* 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;
|
2018-11-19 21:51:52 +01:00
|
|
|
|
2018-12-10 23:16:10 +01:00
|
|
|
/*
|
|
|
|
* Effective priority
|
2018-12-11 18:55:21 +01:00
|
|
|
* => vr->priority if we are Backup
|
2018-12-10 23:16:10 +01:00
|
|
|
* => 255 if we are Master
|
|
|
|
*/
|
2018-11-19 21:51:52 +01:00
|
|
|
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;
|
|
|
|
|
2018-12-11 18:55:21 +01:00
|
|
|
/*
|
|
|
|
* 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 thread *t_master_down_timer;
|
|
|
|
struct thread *t_adver_timer;
|
2018-12-19 17:48:36 +01:00
|
|
|
struct thread *t_read;
|
|
|
|
struct thread *t_write;
|
2018-12-11 18:55:21 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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 {
|
|
|
|
/* Interface */
|
|
|
|
struct interface *ifp;
|
|
|
|
|
2018-12-19 17:48:36 +01:00
|
|
|
/* Version */
|
|
|
|
uint8_t version;
|
|
|
|
|
2018-12-11 18:55:21 +01:00
|
|
|
/* 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;
|
|
|
|
|
2018-11-19 21:51:52 +01:00
|
|
|
/*
|
|
|
|
* 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;
|
|
|
|
|
2018-12-11 18:55:21 +01:00
|
|
|
struct vrrp_router *v4;
|
|
|
|
struct vrrp_router *v6;
|
2018-11-19 21:51:52 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Initialize VRRP global datastructures.
|
|
|
|
*/
|
|
|
|
void vrrp_init(void);
|
|
|
|
|
2018-12-06 22:31:05 +01:00
|
|
|
|
|
|
|
/* Creation and destruction ------------------------------------------------ */
|
|
|
|
|
2018-11-19 21:51:52 +01:00
|
|
|
/*
|
|
|
|
* Create and register a new VRRP Virtual Router.
|
2018-12-06 22:31:05 +01:00
|
|
|
*
|
|
|
|
* ifp
|
|
|
|
* Base interface to configure VRRP on
|
|
|
|
*
|
|
|
|
* vrid
|
|
|
|
* Virtual Router Identifier
|
2018-11-19 21:51:52 +01:00
|
|
|
*/
|
|
|
|
struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid);
|
|
|
|
|
2018-12-04 22:28:25 +01:00
|
|
|
/*
|
|
|
|
* Destroy a VRRP Virtual Router.
|
|
|
|
*/
|
|
|
|
void vrrp_vrouter_destroy(struct vrrp_vrouter *vr);
|
|
|
|
|
2018-12-06 22:31:05 +01:00
|
|
|
|
|
|
|
/* Configuration controllers ----------------------------------------------- */
|
|
|
|
|
2018-12-04 22:28:25 +01:00
|
|
|
/*
|
2018-12-10 23:16:10 +01:00
|
|
|
* Change the configured priority of a VRRP Virtual Router.
|
2018-12-04 22:28:25 +01:00
|
|
|
*
|
2018-12-10 23:16:10 +01:00
|
|
|
* 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.
|
2018-12-04 22:28:25 +01:00
|
|
|
*
|
2018-12-06 22:31:05 +01:00
|
|
|
* vr
|
|
|
|
* Virtual Router to change priority of
|
2018-12-04 22:28:25 +01:00
|
|
|
*
|
2018-12-06 22:31:05 +01:00
|
|
|
* priority
|
|
|
|
* New priority
|
2018-12-04 22:28:25 +01:00
|
|
|
*/
|
2018-12-06 22:31:05 +01:00
|
|
|
void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority);
|
2018-12-04 22:28:25 +01:00
|
|
|
|
|
|
|
/*
|
2018-12-06 22:31:05 +01:00
|
|
|
* Set Advertisement Interval on this Virtual Router.
|
2018-12-04 22:28:25 +01:00
|
|
|
*
|
|
|
|
* vr
|
|
|
|
* Virtual Router to change priority of
|
|
|
|
*
|
2018-12-06 22:31:05 +01:00
|
|
|
* advertisement_interval
|
|
|
|
* New advertisement interval
|
2018-12-04 22:28:25 +01:00
|
|
|
*/
|
2018-12-06 22:31:05 +01:00
|
|
|
void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr,
|
|
|
|
uint16_t advertisement_interval);
|
2018-12-04 22:28:25 +01:00
|
|
|
|
|
|
|
/*
|
2018-12-11 18:55:21 +01:00
|
|
|
* Add an IPvX address to a VRRP Virtual Router.
|
|
|
|
*
|
|
|
|
* vr
|
|
|
|
* Virtual Router to add IPvx address to
|
|
|
|
*
|
|
|
|
* ip
|
|
|
|
* Address to add
|
|
|
|
*/
|
|
|
|
void vrrp_add_ip(struct vrrp_vrouter *vr, struct ipaddr ip);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Add an IPv4 address to a VRRP Virtual Router.
|
2018-12-04 22:28:25 +01:00
|
|
|
*
|
|
|
|
* vr
|
|
|
|
* Virtual Router to add IPv4 address to
|
|
|
|
*
|
|
|
|
* v4
|
|
|
|
* Address to add
|
|
|
|
*/
|
2018-12-11 18:55:21 +01:00
|
|
|
void 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
|
|
|
|
*/
|
|
|
|
void vrrp_add_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6);
|
2018-12-04 22:28:25 +01:00
|
|
|
|
2018-12-06 22:31:05 +01:00
|
|
|
|
|
|
|
/* State machine ----------------------------------------------------------- */
|
|
|
|
|
2018-12-08 01:16:27 +01:00
|
|
|
#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 *vrrp_state_names[3];
|
|
|
|
extern const char *vrrp_event_names[2];
|
2018-12-06 22:31:05 +01:00
|
|
|
|
2018-11-19 21:51:52 +01:00
|
|
|
/*
|
2018-12-06 22:31:05 +01:00
|
|
|
* 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.
|
2018-11-19 21:51:52 +01:00
|
|
|
*/
|
2018-12-11 18:55:21 +01:00
|
|
|
DECLARE_HOOK(vrrp_change_state_hook, (struct vrrp_router * r, int to), (r, to));
|
2018-11-19 21:51:52 +01:00
|
|
|
|
|
|
|
/*
|
2018-12-06 22:31:05 +01:00
|
|
|
* 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
|
2018-11-19 21:51:52 +01:00
|
|
|
*/
|
2018-12-11 18:55:21 +01:00
|
|
|
int vrrp_event(struct vrrp_router *r, int event);
|
2018-11-19 21:51:52 +01:00
|
|
|
|
2018-12-06 22:31:05 +01:00
|
|
|
|
|
|
|
/* Other ------------------------------------------------------------------- */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Find VRRP Virtual Router by Virtual Router ID
|
|
|
|
*/
|
|
|
|
struct vrrp_vrouter *vrrp_lookup(uint8_t vrid);
|
|
|
|
|
2018-11-30 09:45:36 +01:00
|
|
|
#endif /* _VRRP_H */
|