1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * VRRP global definitions and state machine.
4 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
11 #include <netinet/ip.h>
13 #include "lib/memory.h"
17 #include "lib/linklist.h"
18 #include "lib/northbound.h"
19 #include "lib/privs.h"
20 #include "lib/stream.h"
21 #include "lib/event.h"
24 /* Global definitions */
25 #define VRRP_RADV_INT 16
26 #define VRRP_PRIO_MASTER 255
27 #define VRRP_MCASTV4_GROUP_STR "224.0.0.18"
28 #define VRRP_MCASTV6_GROUP_STR "ff02:0:0:0:0:0:0:12"
29 #define VRRP_MCASTV4_GROUP 0xe0000012
30 #define VRRP_MCASTV6_GROUP 0xff020000000000000000000000000012
31 #define IPPROTO_VRRP 112
33 #define VRRP_LOGPFX_VRID "[VRID %u] "
34 #define VRRP_LOGPFX_FAM "[%s] "
36 /* Default defaults */
37 #define VRRP_XPATH_FULL "/frr-interface:lib/interface/frr-vrrpd:vrrp/vrrp-group"
38 #define VRRP_XPATH "./frr-vrrpd:vrrp/vrrp-group"
39 #define VRRP_DEFAULT_PRIORITY 100
40 #define VRRP_DEFAULT_ADVINT 100
41 #define VRRP_DEFAULT_PREEMPT true
42 #define VRRP_DEFAULT_ACCEPT true
43 #define VRRP_DEFAULT_CHECKSUM_WITH_IPV4_PSEUDOHEADER true
44 #define VRRP_DEFAULT_SHUTDOWN false
46 /* User compatibility constant */
49 DECLARE_MGROUP(VRRPD
);
52 extern const struct frr_yang_module_info frr_vrrpd_info
;
54 /* Configured defaults */
55 struct vrrp_defaults
{
58 uint16_t advertisement_interval
;
61 bool checksum_with_ipv4_pseudoheader
;
65 extern struct vrrp_defaults vd
;
68 extern struct event_loop
*master
;
71 extern struct zebra_privs_t vrrp_privs
;
73 /* Global hash of all Virtual Routers */
74 extern struct hash
*vrrp_vrouters_hash
;
79 * This struct contains all state for a particular VRRP Router operating
80 * in a Virtual Router for either IPv4 or IPv6.
84 * Whether this VRRP Router is active.
88 /* Whether we are the address owner */
91 /* Rx socket: Rx from parent of mvl_ifp */
93 /* Tx socket; Tx from mvl_ifp */
96 /* macvlan interface */
97 struct interface
*mvl_ifp
;
99 /* Source address for advertisements */
102 /* Socket read buffer */
103 uint8_t ibuf
[IP_MAXPACKET
];
106 * Address family of this Virtual Router.
107 * Either AF_INET or AF_INET6.
112 * Virtual Router this VRRP Router is participating in.
114 struct vrrp_vrouter
*vr
;
117 * One or more IPvX addresses associated with this Virtual
118 * Router. The first address must be the "primary" address this
119 * Virtual Router is backing up in the case of IPv4. In the case of
120 * IPv6 it must be the link-local address of vr->ifp.
122 * Type: struct ipaddr *
127 * This flag says whether we are waiting on an interface up
128 * notification from Zebra before we send an ADVERTISEMENT.
133 * If this is an IPv4 VRRP router, this flag says whether we are
134 * waiting on an interface up notification from Zebra before we send
135 * gratuitous ARP packets for all our addresses. Should never be true
136 * if family == AF_INET6.
140 * If this is an IPv6 VRRP router, this flag says whether we are
141 * waiting on an interface up notification from Zebra before we send
142 * Unsolicited Neighbor Advertisement packets for all our addresses.
143 * Should never be true if family == AF_INET.
149 * => vr->priority if we are Backup
150 * => 255 if we are Master
155 * Advertisement interval contained in ADVERTISEMENTS received from the
156 * Master (centiseconds)
158 uint16_t master_adver_interval
;
161 * Time to skew Master_Down_Interval in centiseconds. Calculated as:
162 * (((256 - priority) * Master_Adver_Interval) / 256)
167 * Time interval for Backup to declare Master down (centiseconds).
169 * (3 * Master_Adver_Interval) + Skew_time
171 uint16_t master_down_interval
;
174 * The MAC address used for the source MAC address in VRRP
175 * advertisements, advertised in ARP requests/responses, and advertised
176 * in ND Neighbor Advertisements.
185 /* Total number of advertisements sent and received */
186 uint32_t adver_tx_cnt
;
187 uint32_t adver_rx_cnt
;
188 /* Total number of gratuitous ARPs sent */
189 uint32_t garp_tx_cnt
;
190 /* Total number of unsolicited Neighbor Advertisements sent */
192 /* Total number of state transitions */
196 struct event
*t_master_down_timer
;
197 struct event
*t_adver_timer
;
198 struct event
*t_read
;
199 struct event
*t_write
;
203 * VRRP Virtual Router.
205 * This struct contains all state and configuration for a given Virtual Router
206 * Identifier on a given interface, both v4 and v6.
208 * RFC5798 s. 1 states:
209 * "Within a VRRP router, the virtual routers in each of the IPv4 and IPv6
210 * address families are a domain unto themselves and do not overlap."
212 * This implementation has chosen the tuple (interface, VRID) as the key for a
213 * particular VRRP Router, and the rest of the program is designed around this
214 * assumption. Additionally, base protocol configuration parameters such as the
215 * advertisement interval and (configured) priority are shared between v4 and
216 * v6 instances. This corresponds to the choice made by other industrial
219 struct vrrp_vrouter
{
220 /* Whether this instance was automatically configured */
223 /* Whether this VRRP router is in administrative shutdown */
227 struct interface
*ifp
;
232 /* Virtual Router Identifier */
235 /* Configured priority */
239 * Time interval between ADVERTISEMENTS (centiseconds). Default is 100
240 * centiseconds (1 second).
242 uint16_t advertisement_interval
;
245 * Controls whether a (starting or restarting) higher-priority Backup
246 * router preempts a lower-priority Master router. Values are True to
247 * allow preemption and False to prohibit preemption. Default is True.
252 * Controls whether a virtual router in Master state will accept
253 * packets addressed to the address owner's IPvX address as its own if
254 * it is not the IPvX address owner. The default is False.
259 * Indicates whether this router computes and accepts VRRPv3 checksums
260 * without pseudoheader, for device interoperability.
262 * This option should only affect IPv4 virtual routers.
264 bool checksum_with_ipv4_pseudoheader
;
266 struct vrrp_router
*v4
;
267 struct vrrp_router
*v6
;
271 * Initialize VRRP global datastructures.
273 void vrrp_init(void);
276 * Destroy all VRRP instances and gracefully shutdown.
278 * For instances in Master state, VRRP advertisements with 0 priority will be
279 * sent if possible to notify Backup routers that we are going away.
281 void vrrp_fini(void);
284 /* Creation and destruction ------------------------------------------------ */
287 * Create and register a new VRRP Virtual Router.
290 * Base interface to configure VRRP on
293 * Virtual Router Identifier
295 struct vrrp_vrouter
*vrrp_vrouter_create(struct interface
*ifp
, uint8_t vrid
,
299 * Destroy a VRRP Virtual Router, freeing all its resources.
301 * If there are any running VRRP instances, these are stopped and destroyed.
303 void vrrp_vrouter_destroy(struct vrrp_vrouter
*vr
);
306 /* Configuration controllers ----------------------------------------------- */
309 * Check if a Virtual Router ought to be started, and if so, start it.
312 * Virtual Router to checkstart
314 void vrrp_check_start(struct vrrp_vrouter
*vr
);
317 * Change the configured priority of a VRRP Virtual Router.
319 * Note that this only changes the configured priority of the Virtual Router.
320 * The currently effective priority will not be changed; to change the
321 * effective priority, the Virtual Router must be restarted by issuing a
322 * VRRP_EVENT_SHUTDOWN followed by a VRRP_EVENT_STARTUP.
325 * Virtual Router to change priority of
330 void vrrp_set_priority(struct vrrp_vrouter
*vr
, uint8_t priority
);
333 * Set Advertisement Interval on this Virtual Router.
336 * Virtual Router to change priority of
338 * advertisement_interval
339 * New advertisement interval
341 void vrrp_set_advertisement_interval(struct vrrp_vrouter
*vr
,
342 uint16_t advertisement_interval
);
345 * Add an IPvX address to a VRRP Virtual Router.
348 * Virtual Router to add IPvx address to
354 * Whether to automatically start the VRRP router if this is the first IP
361 int vrrp_add_ip(struct vrrp_vrouter
*vr
, struct ipaddr
*ip
);
364 * Add an IPv4 address to a VRRP Virtual Router.
367 * Virtual Router to add IPv4 address to
373 * Whether to automatically start the VRRP router if this is the first IP
380 int vrrp_add_ipv4(struct vrrp_vrouter
*vr
, struct in_addr v4
);
383 * Add an IPv6 address to a VRRP Virtual Router.
386 * Virtual Router to add IPv6 address to
392 * Whether to automatically start the VRRP router if this is the first IP
399 int vrrp_add_ipv6(struct vrrp_vrouter
*vr
, struct in6_addr v6
);
402 * Remove an IP address from a VRRP Virtual Router.
405 * Virtual Router to remove IP address from
411 * Whether to automatically stop the VRRP router if removing v4 would leave
412 * us with an empty address list. If this is not true and ip is the only IP
413 * address backed up by this virtual router, this function will not remove
414 * the address and return failure.
420 int vrrp_del_ip(struct vrrp_vrouter
*vr
, struct ipaddr
*ip
);
423 * Remove an IPv4 address from a VRRP Virtual Router.
426 * Virtual Router to remove IPv4 address from
432 * Whether to automatically stop the VRRP router if removing v4 would leave
433 * us with an empty address list. If this is not true and v4 is the only
434 * IPv4 address backed up by this virtual router, this function will not
435 * remove the address and return failure.
441 int vrrp_del_ipv4(struct vrrp_vrouter
*vr
, struct in_addr v4
);
444 * Remove an IPv6 address from a VRRP Virtual Router.
447 * Virtual Router to remove IPv6 address from
453 * Whether to automatically stop the VRRP router if removing v5 would leave
454 * us with an empty address list. If this is not true and v4 is the only
455 * IPv6 address backed up by this virtual router, this function will not
456 * remove the address and return failure.
462 int vrrp_del_ipv6(struct vrrp_vrouter
*vr
, struct in6_addr v6
);
464 /* State machine ----------------------------------------------------------- */
466 #define VRRP_STATE_INITIALIZE 0
467 #define VRRP_STATE_MASTER 1
468 #define VRRP_STATE_BACKUP 2
469 #define VRRP_EVENT_STARTUP 0
470 #define VRRP_EVENT_SHUTDOWN 1
472 extern const char *const vrrp_state_names
[3];
475 * This hook called whenever the state of a Virtual Router changes, after the
476 * specific internal state handlers have run.
478 * Use this if you need to react to state changes to perform non-critical
479 * tasks. Critical tasks should go in the internal state change handlers.
481 DECLARE_HOOK(vrrp_change_state_hook
, (struct vrrp_router
*r
, int to
), (r
, to
));
484 * Trigger a VRRP event on a given Virtual Router..
487 * Virtual Router to operate on
490 * Event to kick off. All event related processing will have completed upon
491 * return of this function.
494 * < 0 if the event created an error
497 int vrrp_event(struct vrrp_router
*r
, int event
);
499 /* Autoconfig -------------------------------------------------------------- */
502 * Search for and automatically configure VRRP instances on interfaces.
505 * Interface to autoconfig. If it is a macvlan interface and has a VRRP MAC,
506 * a VRRP instance corresponding to VMAC assigned to macvlan will be created
507 * on the parent interface and all addresses on the macvlan interface except
508 * the v6 link local will be configured as VRRP addresses. If NULL, this
509 * treatment will be applied to all existing interfaces matching the above
516 int vrrp_autoconfig(void);
519 * Enable autoconfiguration.
521 * Calling this function will cause vrrpd to automatically configure VRRP
522 * instances on existing compatible macvlan interfaces. These instances will
523 * react to interface up/down and address add/delete events to keep themselves
524 * in sync with the available interfaces.
527 * VRRP version to use for autoconfigured instances. Must be 2 or 3.
529 void vrrp_autoconfig_on(int version
);
532 * Disable autoconfiguration.
534 * Calling this function will delete all existing autoconfigured VRRP instances.
536 void vrrp_autoconfig_off(void);
538 /* Interface Tracking ------------------------------------------------------ */
540 void vrrp_if_add(struct interface
*ifp
);
541 void vrrp_if_del(struct interface
*ifp
);
542 void vrrp_if_up(struct interface
*ifp
);
543 void vrrp_if_down(struct interface
*ifp
);
544 void vrrp_if_address_add(struct interface
*ifp
);
545 void vrrp_if_address_del(struct interface
*ifp
);
547 /* Other ------------------------------------------------------------------- */
550 * Write global level configuration to vty.
553 * vty to write config to
558 int vrrp_config_write_global(struct vty
*vty
);
561 * Find VRRP Virtual Router by Virtual Router ID
563 struct vrrp_vrouter
*vrrp_lookup(const struct interface
*ifp
, uint8_t vrid
);
565 #endif /* __VRRP_H__ */