]> git.proxmox.com Git - mirror_frr.git/blob - vrrpd/vrrp.c
Merge pull request #4285 from vishaldhingra/no_neighbor
[mirror_frr.git] / vrrpd / vrrp.c
1 /*
2 * VRRP global definitions and state machine.
3 * Copyright (C) 2018-2019 Cumulus Networks, Inc.
4 * Quentin Young
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20 #include <zebra.h>
21
22 #include "lib/hash.h"
23 #include "lib/hook.h"
24 #include "lib/if.h"
25 #include "lib/linklist.h"
26 #include "lib/memory.h"
27 #include "lib/network.h"
28 #include "lib/prefix.h"
29 #include "lib/sockopt.h"
30 #include "lib/sockunion.h"
31 #include "lib/vrf.h"
32 #include "lib/vty.h"
33
34 #include "vrrp.h"
35 #include "vrrp_arp.h"
36 #include "vrrp_debug.h"
37 #include "vrrp_memory.h"
38 #include "vrrp_ndisc.h"
39 #include "vrrp_packet.h"
40 #include "vrrp_zebra.h"
41
42 #define VRRP_LOGPFX "[CORE] "
43
44 /* statics */
45 struct hash *vrrp_vrouters_hash;
46 bool vrrp_autoconfig_is_on;
47 int vrrp_autoconfig_version;
48
49 struct vrrp_defaults vd;
50
51 const char *vrrp_state_names[3] = {
52 [VRRP_STATE_INITIALIZE] = "Initialize",
53 [VRRP_STATE_MASTER] = "Master",
54 [VRRP_STATE_BACKUP] = "Backup",
55 };
56
57 const char *vrrp_event_names[2] = {
58 [VRRP_EVENT_STARTUP] = "Startup",
59 [VRRP_EVENT_SHUTDOWN] = "Shutdown",
60 };
61
62
63 /* Utility functions ------------------------------------------------------- */
64
65 /*
66 * Sets an ethaddr to RFC-defined Virtual Router MAC address.
67 *
68 * mac
69 * ethaddr to set
70 *
71 * v6
72 * Whether this is a V6 or V4 Virtual Router MAC
73 *
74 * vrid
75 * Virtual Router Identifier
76 */
77 static void vrrp_mac_set(struct ethaddr *mac, bool v6, uint8_t vrid)
78 {
79 /*
80 * V4: 00-00-5E-00-01-{VRID}
81 * V6: 00-00-5E-00-02-{VRID}
82 */
83 mac->octet[0] = 0x00;
84 mac->octet[1] = 0x00;
85 mac->octet[2] = 0x5E;
86 mac->octet[3] = 0x00;
87 mac->octet[4] = v6 ? 0x02 : 0x01;
88 mac->octet[5] = vrid;
89 }
90
91 /*
92 * Recalculates and sets skew_time and master_down_interval based
93 * values.
94 *
95 * r
96 * VRRP Router to operate on
97 */
98 static void vrrp_recalculate_timers(struct vrrp_router *r)
99 {
100 uint16_t mdiadv = r->vr->version == 3 ? r->master_adver_interval
101 : r->vr->advertisement_interval;
102 uint16_t skm = (r->vr->version == 3) ? r->master_adver_interval : 100;
103
104 r->skew_time = ((256 - r->vr->priority) * skm) / 256;
105 r->master_down_interval = 3 * mdiadv;
106 r->master_down_interval += r->skew_time;
107 }
108
109 /*
110 * Determines if a VRRP router is the owner of the specified address.
111 *
112 * The determining factor for whether an interface is the address owner is
113 * simply whether the address is assigned to the VRRP base interface by someone
114 * other than vrrpd.
115 *
116 * This function should always return the correct answer regardless of
117 * master/backup status.
118 *
119 * ifp
120 * The interface to check owernship of. This should be the base interface of
121 * a VRRP router.
122 *
123 * vr
124 * Virtual Router
125 *
126 * Returns:
127 * whether or not vr owns the specified address
128 */
129 static bool vrrp_is_owner(struct interface *ifp, struct ipaddr *addr)
130 {
131 /*
132 * This code sanity checks implicit ownership configuration. Ideally,
133 * the way we determine address ownership status for this VRRP router
134 * is by looking at whether our VIPs are also assigned to the base
135 * interface, and therefore count as "real" addresses. This frees the
136 * user from having to manually configure priority 255 to indicate
137 * address ownership. However, this means one of the VIPs will be used
138 * as the source address for VRRP advertisements, which in turn means
139 * that other VRRP routers will be receiving packets with a source
140 * address they themselves have. This causes lots of different issues
141 * so for now we're disabling this and forcing the user to configure
142 * priority 255 to indicate ownership.
143 */
144
145 return false;
146
147 #if 0
148 struct prefix p;
149
150 p.family = IS_IPADDR_V4(addr) ? AF_INET : AF_INET6;
151 p.prefixlen = IS_IPADDR_V4(addr) ? IPV4_MAX_BITLEN : IPV6_MAX_BITLEN;
152 memcpy(&p.u, &addr->ip, sizeof(addr->ip));
153
154 return !!connected_lookup_prefix_exact(ifp, &p);
155 #endif
156 }
157
158 /*
159 * Whether an interface has a MAC address that matches the VRRP RFC.
160 *
161 * ifp
162 * Interface to check
163 *
164 * Returns:
165 * Whether the interface has a VRRP mac or not
166 */
167 static bool vrrp_ifp_has_vrrp_mac(struct interface *ifp)
168 {
169 struct ethaddr vmac4;
170 struct ethaddr vmac6;
171
172 vrrp_mac_set(&vmac4, 0, 0x00);
173 vrrp_mac_set(&vmac6, 1, 0x00);
174
175 return !memcmp(ifp->hw_addr, vmac4.octet, sizeof(vmac4.octet) - 1)
176 || !memcmp(ifp->hw_addr, vmac6.octet, sizeof(vmac6.octet) - 1);
177 }
178
179 /*
180 * Lookup a Virtual Router instance given a macvlan subinterface.
181 *
182 * The VRID is extracted from the interface MAC and the 2-tuple (iface, vrid)
183 * is used to look up any existing instances that match the interface. It does
184 * not matter whether the instance is already bound to the interface or not.
185 *
186 * mvl_ifp
187 * Interface pointer to use to lookup. Should be a macvlan device.
188 *
189 * Returns:
190 * Virtual Router, if found
191 * NULL otherwise
192 */
193 static struct vrrp_vrouter *vrrp_lookup_by_if_mvl(struct interface *mvl_ifp)
194 {
195 struct interface *p;
196
197 if (!mvl_ifp || !mvl_ifp->link_ifindex
198 || !vrrp_ifp_has_vrrp_mac(mvl_ifp))
199 return NULL;
200
201 p = if_lookup_by_index(mvl_ifp->link_ifindex, VRF_DEFAULT);
202 uint8_t vrid = mvl_ifp->hw_addr[5];
203
204 return vrrp_lookup(p, vrid);
205 }
206
207 /*
208 * Lookup the Virtual Router instances configured on a particular interface.
209 *
210 * ifp
211 * Interface pointer to use to lookup. Should not be a macvlan device.
212 *
213 * Returns:
214 * List of virtual routers found
215 */
216 static struct list *vrrp_lookup_by_if(struct interface *ifp)
217 {
218 struct list *l = hash_to_list(vrrp_vrouters_hash);
219 struct listnode *ln, *nn;
220 struct vrrp_vrouter *vr;
221
222 for (ALL_LIST_ELEMENTS(l, ln, nn, vr))
223 if (vr->ifp != ifp)
224 list_delete_node(l, ln);
225
226 return l;
227 }
228
229 /*
230 * Lookup any Virtual Router instances associated with a particular interface.
231 * This is a combination of the results from vrrp_lookup_by_if_mvl and
232 * vrrp_lookup_by_if.
233 *
234 * Suppose the system interface list looks like the following:
235 *
236 * eth0
237 * \- eth0-v0 00:00:5e:00:01:01
238 * \- eth0-v1 00:00:5e:00:02:01
239 * \- eth0-v2 00:00:5e:00:01:0a
240 *
241 * Passing eth0-v2 to this function will give you the VRRP instance configured
242 * on eth0 with VRID 10. Passing eth0-v0 or eth0-v1 will give you the VRRP
243 * instance configured on eth0 with VRID 1. Passing eth0 will give you both.
244 *
245 * ifp
246 * Interface pointer to use to lookup. Can be any interface.
247 *
248 * Returns:
249 * List of virtual routers found
250 */
251 static struct list *vrrp_lookup_by_if_any(struct interface *ifp)
252 {
253 struct vrrp_vrouter *vr;
254 struct list *vrs;
255
256 vr = vrrp_lookup_by_if_mvl(ifp);
257 vrs = vr ? list_new() : vrrp_lookup_by_if(ifp);
258
259 if (vr)
260 listnode_add(vrs, vr);
261
262 return vrs;
263 }
264
265 /* Configuration controllers ----------------------------------------------- */
266
267 void vrrp_check_start(struct vrrp_vrouter *vr)
268 {
269 struct vrrp_router *r;
270 bool start;
271 const char *whynot = NULL;
272
273 if (vr->shutdown || vr->ifp == NULL)
274 return;
275
276 r = vr->v4;
277 /* Must not already be started */
278 start = r->fsm.state == VRRP_STATE_INITIALIZE;
279 /* Must have a parent interface */
280 start = start && (vr->ifp != NULL);
281 whynot = (!start && !whynot) ? "No base interface" : NULL;
282 #if 0
283 /* Parent interface must be up */
284 start = start && if_is_operative(vr->ifp);
285 #endif
286 /* Parent interface must have at least one v4 */
287 start = start && vr->ifp->connected->count > 1;
288 whynot = (!start && !whynot) ? "No primary IPv4 address" : NULL;
289 /* Must have a macvlan interface */
290 start = start && (r->mvl_ifp != NULL);
291 whynot = (!start && !whynot) ? "No VRRP interface" : NULL;
292 #if 0
293 /* Macvlan interface must be admin up */
294 start = start && CHECK_FLAG(r->mvl_ifp->flags, IFF_UP);
295 #endif
296 /* Must have at least one VIP configured */
297 start = start && r->addrs->count > 0;
298 whynot =
299 (!start && !whynot) ? "No Virtual IP address configured" : NULL;
300 if (start)
301 vrrp_event(r, VRRP_EVENT_STARTUP);
302 else if (whynot)
303 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
304 "Refusing to start Virtual Router: %s",
305 vr->vrid, family2str(r->family), whynot);
306
307 r = vr->v6;
308 /* Must not already be started */
309 start = r->fsm.state == VRRP_STATE_INITIALIZE;
310 /* Must not be v2 */
311 start = start && vr->version != 2;
312 whynot = (!start && !whynot) ? "VRRPv2 does not support v6" : NULL;
313 /* Must have a parent interface */
314 start = start && (vr->ifp != NULL);
315 whynot = (!start && !whynot) ? "No base interface" : NULL;
316 #if 0
317 /* Parent interface must be up */
318 start = start && if_is_operative(vr->ifp);
319 #endif
320 /* Must have a macvlan interface */
321 start = start && (r->mvl_ifp != NULL);
322 whynot = (!start && !whynot) ? "No VRRP interface" : NULL;
323 #if 0
324 /* Macvlan interface must be admin up */
325 start = start && CHECK_FLAG(r->mvl_ifp->flags, IFF_UP);
326 /* Macvlan interface must have a link local */
327 start = start && connected_get_linklocal(r->mvl_ifp);
328 whynot =
329 (!start && !whynot) ? "No link local address configured" : NULL;
330 /* Macvlan interface must have a v6 IP besides the link local */
331 start = start && (r->mvl_ifp->connected->count >= 2);
332 whynot = (!start && !whynot)
333 ? "No Virtual IP configured on macvlan device"
334 : NULL;
335 #endif
336 /* Must have at least one VIP configured */
337 start = start && r->addrs->count > 0;
338 whynot =
339 (!start && !whynot) ? "No Virtual IP address configured" : NULL;
340 if (start)
341 vrrp_event(r, VRRP_EVENT_STARTUP);
342 else if (whynot)
343 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
344 "Refusing to start Virtual Router: %s",
345 vr->vrid, family2str(r->family), whynot);
346 }
347
348 void vrrp_set_priority(struct vrrp_vrouter *vr, uint8_t priority)
349 {
350 vr->priority = priority;
351 vr->v4->priority = priority;
352 vr->v6->priority = priority;
353 }
354
355 void vrrp_set_advertisement_interval(struct vrrp_vrouter *vr,
356 uint16_t advertisement_interval)
357 {
358 if (vr->advertisement_interval == advertisement_interval)
359 return;
360
361 vr->advertisement_interval = advertisement_interval;
362 vrrp_recalculate_timers(vr->v4);
363 vrrp_recalculate_timers(vr->v6);
364 }
365
366 static bool vrrp_has_ip(struct vrrp_vrouter *vr, struct ipaddr *ip)
367 {
368 struct vrrp_router *r = ip->ipa_type == IPADDR_V4 ? vr->v4 : vr->v6;
369 struct listnode *ln;
370 struct ipaddr *iter;
371
372 for (ALL_LIST_ELEMENTS_RO(r->addrs, ln, iter))
373 if (!memcmp(&iter->ip, &ip->ip, IPADDRSZ(ip)))
374 return true;
375
376 return false;
377 }
378
379 int vrrp_add_ip(struct vrrp_router *r, struct ipaddr *ip)
380 {
381 int af = (ip->ipa_type == IPADDR_V6) ? AF_INET6 : AF_INET;
382
383 assert(r->family == af);
384 assert(!(r->vr->version == 2 && ip->ipa_type == IPADDR_V6));
385
386 if (vrrp_has_ip(r->vr, ip))
387 return 0;
388
389 if (!vrrp_is_owner(r->vr->ifp, ip) && r->is_owner) {
390 char ipbuf[INET6_ADDRSTRLEN];
391
392 inet_ntop(r->family, &ip->ip, ipbuf, sizeof(ipbuf));
393 zlog_err(
394 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
395 "This VRRP router is not the address owner of %s, but is the address owner of other addresses; this config is unsupported.",
396 r->vr->vrid, family2str(r->family), ipbuf);
397 return -1;
398 }
399
400 struct ipaddr *new = XCALLOC(MTYPE_VRRP_IP, sizeof(struct ipaddr));
401
402 *new = *ip;
403 listnode_add(r->addrs, new);
404
405 if (r->fsm.state == VRRP_STATE_MASTER) {
406 switch (r->family) {
407 case AF_INET:
408 vrrp_garp_send(r, &new->ipaddr_v4);
409 break;
410 case AF_INET6:
411 vrrp_ndisc_una_send(r, new);
412 break;
413 }
414 }
415
416 return 0;
417 }
418
419 int vrrp_add_ipv4(struct vrrp_vrouter *vr, struct in_addr v4)
420 {
421 struct ipaddr ip;
422
423 ip.ipa_type = IPADDR_V4;
424 ip.ipaddr_v4 = v4;
425 return vrrp_add_ip(vr->v4, &ip);
426 }
427
428 int vrrp_add_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6)
429 {
430 assert(vr->version != 2);
431
432 struct ipaddr ip;
433
434 ip.ipa_type = IPADDR_V6;
435 ip.ipaddr_v6 = v6;
436 return vrrp_add_ip(vr->v6, &ip);
437 }
438
439 int vrrp_del_ip(struct vrrp_router *r, struct ipaddr *ip)
440 {
441 struct listnode *ln, *nn;
442 struct ipaddr *iter;
443 int ret = 0;
444
445 if (!vrrp_has_ip(r->vr, ip))
446 return 0;
447
448 for (ALL_LIST_ELEMENTS(r->addrs, ln, nn, iter))
449 if (!memcmp(&iter->ip, &ip->ip, IPADDRSZ(ip)))
450 list_delete_node(r->addrs, ln);
451
452 /*
453 * NB: Deleting the last address and then issuing a shutdown will cause
454 * transmission of a priority 0 VRRP Advertisement - as per the RFC -
455 * but it will have no addresses. This is not forbidden in the RFC but
456 * might confuse other implementations.
457 */
458 if (r->addrs->count == 0 && r->fsm.state != VRRP_STATE_INITIALIZE)
459 ret = vrrp_event(r, VRRP_EVENT_SHUTDOWN);
460
461 return ret;
462 }
463
464 int vrrp_del_ipv6(struct vrrp_vrouter *vr, struct in6_addr v6)
465 {
466 struct ipaddr ip;
467
468 ip.ipa_type = IPADDR_V6;
469 ip.ipaddr_v6 = v6;
470 return vrrp_del_ip(vr->v6, &ip);
471 }
472
473 int vrrp_del_ipv4(struct vrrp_vrouter *vr, struct in_addr v4)
474 {
475 struct ipaddr ip;
476
477 ip.ipa_type = IPADDR_V4;
478 ip.ipaddr_v4 = v4;
479 return vrrp_del_ip(vr->v4, &ip);
480 }
481
482
483 /* Creation and destruction ------------------------------------------------ */
484
485 static void vrrp_router_addr_list_del_cb(void *val)
486 {
487 struct ipaddr *ip = val;
488
489 XFREE(MTYPE_VRRP_IP, ip);
490 }
491
492 /*
493 * Search for a suitable macvlan subinterface we can attach to, and if found,
494 * attach to it.
495 *
496 * r
497 * Router to attach to interface
498 *
499 * Returns:
500 * Whether an interface was successfully attached
501 */
502 static bool vrrp_attach_interface(struct vrrp_router *r)
503 {
504 /* Search for existing interface with computed MAC address */
505 struct interface **ifps;
506
507 size_t ifps_cnt = if_lookup_by_hwaddr(
508 r->vmac.octet, sizeof(r->vmac.octet), &ifps, VRF_DEFAULT);
509
510 /*
511 * Filter to only those macvlan interfaces whose parent is the base
512 * interface this VRRP router is configured on.
513 *
514 * If there are still multiple interfaces we just select the first one,
515 * as it should be functionally identical to the others.
516 */
517 unsigned int candidates = 0;
518 struct interface *selection = NULL;
519
520 for (unsigned int i = 0; i < ifps_cnt; i++) {
521 if (ifps[i]->link_ifindex != r->vr->ifp->ifindex)
522 ifps[i] = NULL;
523 else {
524 selection = selection ? selection : ifps[i];
525 candidates++;
526 }
527 }
528
529 if (ifps_cnt)
530 XFREE(MTYPE_TMP, ifps);
531
532 char ethstr[ETHER_ADDR_STRLEN];
533
534 prefix_mac2str(&r->vmac, ethstr, sizeof(ethstr));
535
536 assert(!!selection == !!candidates);
537
538 if (candidates == 0)
539 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
540 "Interface: None (no interface found w/ MAC %s)",
541 r->vr->vrid, family2str(r->family), ethstr);
542 else if (candidates > 1)
543 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
544 "Interface: Multiple interfaces found; using %s",
545 r->vr->vrid, family2str(r->family), selection->name);
546 else
547 zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
548 "Interface: %s",
549 r->vr->vrid, family2str(r->family), selection->name);
550
551 r->mvl_ifp = selection;
552
553 return !!r->mvl_ifp;
554 }
555
556 static struct vrrp_router *vrrp_router_create(struct vrrp_vrouter *vr,
557 int family)
558 {
559 struct vrrp_router *r =
560 XCALLOC(MTYPE_VRRP_RTR, sizeof(struct vrrp_router));
561
562 r->family = family;
563 r->sock_rx = -1;
564 r->sock_tx = -1;
565 r->vr = vr;
566 r->addrs = list_new();
567 r->addrs->del = vrrp_router_addr_list_del_cb;
568 r->priority = vr->priority;
569 r->fsm.state = VRRP_STATE_INITIALIZE;
570 vrrp_mac_set(&r->vmac, family == AF_INET6, vr->vrid);
571
572 vrrp_attach_interface(r);
573
574 return r;
575 }
576
577 static void vrrp_router_destroy(struct vrrp_router *r)
578 {
579 if (r->is_active)
580 vrrp_event(r, VRRP_EVENT_SHUTDOWN);
581
582 if (r->sock_rx >= 0)
583 close(r->sock_rx);
584 if (r->sock_tx >= 0)
585 close(r->sock_tx);
586
587 /* FIXME: also delete list elements */
588 list_delete(&r->addrs);
589 XFREE(MTYPE_VRRP_RTR, r);
590 }
591
592 struct vrrp_vrouter *vrrp_vrouter_create(struct interface *ifp, uint8_t vrid,
593 uint8_t version)
594 {
595 struct vrrp_vrouter *vr = vrrp_lookup(ifp, vrid);
596
597 if (vr)
598 return vr;
599
600 if (version != 2 && version != 3)
601 return NULL;
602
603 vr = XCALLOC(MTYPE_VRRP_RTR, sizeof(struct vrrp_vrouter));
604
605 vr->ifp = ifp;
606 vr->version = version;
607 vr->vrid = vrid;
608 vr->priority = vd.priority;
609 vr->preempt_mode = vd.preempt_mode;
610 vr->accept_mode = vd.accept_mode;
611 vr->shutdown = vd.shutdown;
612
613 vr->v4 = vrrp_router_create(vr, AF_INET);
614 vr->v6 = vrrp_router_create(vr, AF_INET6);
615
616 vrrp_set_advertisement_interval(vr, vd.advertisement_interval);
617
618 hash_get(vrrp_vrouters_hash, vr, hash_alloc_intern);
619
620 return vr;
621 }
622
623 void vrrp_vrouter_destroy(struct vrrp_vrouter *vr)
624 {
625 vrrp_router_destroy(vr->v4);
626 vrrp_router_destroy(vr->v6);
627 hash_release(vrrp_vrouters_hash, vr);
628 XFREE(MTYPE_VRRP_RTR, vr);
629 }
630
631 struct vrrp_vrouter *vrrp_lookup(struct interface *ifp, uint8_t vrid)
632 {
633 struct vrrp_vrouter vr;
634
635 vr.vrid = vrid;
636 vr.ifp = ifp;
637
638 return hash_lookup(vrrp_vrouters_hash, &vr);
639 }
640
641 /* Network ----------------------------------------------------------------- */
642
643 /* Forward decls */
644 static void vrrp_change_state(struct vrrp_router *r, int to);
645 static int vrrp_adver_timer_expire(struct thread *thread);
646 static int vrrp_master_down_timer_expire(struct thread *thread);
647
648 /*
649 * Finds the first connected address of the appropriate family on a VRRP
650 * router's interface and binds the Tx socket of the VRRP router to that
651 * address.
652 *
653 * Also sets src field of vrrp_router.
654 *
655 * r
656 * VRRP router to operate on
657 *
658 * Returns:
659 * 0 on success
660 * -1 on failure
661 */
662 static int vrrp_bind_to_primary_connected(struct vrrp_router *r)
663 {
664 char ipstr[INET6_ADDRSTRLEN];
665 struct interface *ifp;
666
667 /*
668 * A slight quirk: the RFC specifies that advertisements under IPv6 must
669 * be transmitted using the link local address of the source interface
670 */
671 ifp = r->family == AF_INET ? r->vr->ifp : r->mvl_ifp;
672
673 struct listnode *ln;
674 struct connected *c = NULL;
675
676 for (ALL_LIST_ELEMENTS_RO(ifp->connected, ln, c))
677 if (c->address->family == r->family) {
678 if (r->family == AF_INET6
679 && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6))
680 break;
681 else if (r->family == AF_INET)
682 break;
683 }
684
685 if (c == NULL) {
686 zlog_err(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
687 "Failed to find address to bind on %s",
688 r->vr->vrid, family2str(r->family), ifp->name);
689 return -1;
690 }
691
692 union sockunion su;
693
694 memset(&su, 0x00, sizeof(su));
695
696 switch (r->family) {
697 case AF_INET:
698 r->src.ipa_type = IPADDR_V4;
699 r->src.ipaddr_v4 = c->address->u.prefix4;
700 su.sin.sin_family = AF_INET;
701 su.sin.sin_addr = c->address->u.prefix4;
702 break;
703 case AF_INET6:
704 r->src.ipa_type = IPADDR_V6;
705 r->src.ipaddr_v6 = c->address->u.prefix6;
706 su.sin6.sin6_family = AF_INET6;
707 su.sin6.sin6_scope_id = ifp->ifindex;
708 su.sin6.sin6_addr = c->address->u.prefix6;
709 break;
710 }
711
712 int ret = 0;
713
714 sockopt_reuseaddr(r->sock_tx);
715 if (bind(r->sock_tx, (const struct sockaddr *)&su, sizeof(su)) < 0) {
716 zlog_err(
717 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
718 "Failed to bind Tx socket to primary IP address %s: %s",
719 r->vr->vrid, family2str(r->family),
720 inet_ntop(r->family,
721 (const void *)&c->address->u.prefix, ipstr,
722 sizeof(ipstr)),
723 safe_strerror(errno));
724 ret = -1;
725 } else {
726 DEBUGD(&vrrp_dbg_sock,
727 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
728 "Bound Tx socket to primary IP address %s",
729 r->vr->vrid, family2str(r->family),
730 inet_ntop(r->family, (const void *)&c->address->u.prefix,
731 ipstr, sizeof(ipstr)));
732 }
733
734 return ret;
735 }
736
737
738 /*
739 * Create and multicast a VRRP ADVERTISEMENT message.
740 *
741 * r
742 * VRRP Router for which to send ADVERTISEMENT
743 */
744 static void vrrp_send_advertisement(struct vrrp_router *r)
745 {
746 struct vrrp_pkt *pkt;
747 ssize_t pktsz;
748 struct ipaddr *addrs[r->addrs->count];
749 union sockunion dest;
750
751 if (r->src.ipa_type == IPADDR_NONE
752 && vrrp_bind_to_primary_connected(r) < 0)
753 return;
754
755 list_to_array(r->addrs, (void **)addrs, r->addrs->count);
756
757 pktsz = vrrp_pkt_adver_build(&pkt, &r->src, r->vr->version, r->vr->vrid,
758 r->priority, r->vr->advertisement_interval,
759 r->addrs->count, (struct ipaddr **)&addrs);
760
761 if (DEBUG_MODE_CHECK(&vrrp_dbg_pkt, DEBUG_MODE_ALL))
762 zlog_hexdump(pkt, (size_t)pktsz);
763
764 const char *group = r->family == AF_INET ? VRRP_MCASTV4_GROUP_STR
765 : VRRP_MCASTV6_GROUP_STR;
766 (void)str2sockunion(group, &dest);
767
768 ssize_t sent = sendto(r->sock_tx, pkt, (size_t)pktsz, 0, &dest.sa,
769 sockunion_sizeof(&dest));
770
771 XFREE(MTYPE_VRRP_PKT, pkt);
772
773 if (sent < 0) {
774 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
775 "Failed to send VRRP Advertisement: %s",
776 r->vr->vrid, family2str(r->family),
777 safe_strerror(errno));
778 } else {
779 ++r->stats.adver_tx_cnt;
780 }
781 }
782
783 /*
784 * Receive and parse VRRP advertisement.
785 *
786 * By the time we get here all fields have been validated for basic correctness
787 * and the packet is a valid VRRP packet.
788 *
789 * However, we have not validated whether the VRID is correct for this virtual
790 * router, nor whether the priority is correct (i.e. is not 255 when we are the
791 * address owner), nor whether the advertisement interval equals our own
792 * configured value (this check is only performed in VRRPv2).
793 *
794 * r
795 * VRRP Router associated with the socket this advertisement was received on
796 *
797 * src
798 * Source address of sender
799 *
800 * pkt
801 * The advertisement they sent
802 *
803 * pktsize
804 * Size of advertisement
805 *
806 * Returns:
807 * -1 if advertisement is invalid
808 * 0 otherwise
809 */
810 static int vrrp_recv_advertisement(struct vrrp_router *r, struct ipaddr *src,
811 struct vrrp_pkt *pkt, size_t pktsize)
812 {
813 char sipstr[INET6_ADDRSTRLEN];
814 char dipstr[INET6_ADDRSTRLEN];
815
816 ipaddr2str(src, sipstr, sizeof(sipstr));
817 ipaddr2str(&r->src, dipstr, sizeof(dipstr));
818
819 char dumpbuf[BUFSIZ];
820
821 vrrp_pkt_adver_dump(dumpbuf, sizeof(dumpbuf), pkt);
822 DEBUGD(&vrrp_dbg_proto,
823 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
824 "Received VRRP Advertisement from %s:\n%s",
825 r->vr->vrid, family2str(r->family), sipstr, dumpbuf);
826
827 /* Check that VRID matches our configured VRID */
828 if (pkt->hdr.vrid != r->vr->vrid) {
829 DEBUGD(&vrrp_dbg_proto,
830 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
831 "Datagram invalid: Advertisement contains VRID %" PRIu8
832 " which does not match our instance",
833 r->vr->vrid, family2str(r->family), pkt->hdr.vrid);
834 return -1;
835 }
836
837 /* Verify that we are not the IPvX address owner */
838 if (r->is_owner) {
839 DEBUGD(&vrrp_dbg_proto,
840 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
841 "Datagram invalid: Received advertisement but we are the address owner",
842 r->vr->vrid, family2str(r->family));
843 return -1;
844 }
845
846 /* If v2, verify that adver time matches ours */
847 bool adveq = (pkt->hdr.v2.adver_int
848 == MAX(r->vr->advertisement_interval / 100, 1));
849 if (r->vr->version == 2 && !adveq) {
850 DEBUGD(&vrrp_dbg_proto,
851 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
852 "Datagram invalid: Received advertisement with advertisement interval %" PRIu8
853 " unequal to our configured value %u",
854 r->vr->vrid, family2str(r->family),
855 pkt->hdr.v2.adver_int,
856 MAX(r->vr->advertisement_interval / 100, 1));
857 return -1;
858 }
859
860
861 /* Check that # IPs received matches our # configured IPs */
862 if (pkt->hdr.naddr != r->addrs->count)
863 DEBUGD(&vrrp_dbg_proto,
864 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
865 "Datagram has %" PRIu8
866 " addresses, but this VRRP instance has %u",
867 r->vr->vrid, family2str(r->family), pkt->hdr.naddr,
868 r->addrs->count);
869
870 ++r->stats.adver_rx_cnt;
871
872 int addrcmp;
873
874 switch (r->fsm.state) {
875 case VRRP_STATE_MASTER:
876 addrcmp = memcmp(&src->ip, &r->src.ip, IPADDRSZ(src));
877
878 if (pkt->hdr.priority == 0) {
879 vrrp_send_advertisement(r);
880 THREAD_OFF(r->t_adver_timer);
881 thread_add_timer_msec(
882 master, vrrp_adver_timer_expire, r,
883 r->vr->advertisement_interval * 10,
884 &r->t_adver_timer);
885 } else if (pkt->hdr.priority > r->priority
886 || ((pkt->hdr.priority == r->priority)
887 && addrcmp > 0)) {
888 zlog_info(
889 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
890 "Received advertisement from %s w/ priority %" PRIu8
891 "; switching to Backup",
892 r->vr->vrid, family2str(r->family), sipstr,
893 pkt->hdr.priority);
894 THREAD_OFF(r->t_adver_timer);
895 if (r->vr->version == 3) {
896 r->master_adver_interval =
897 htons(pkt->hdr.v3.adver_int);
898 }
899 vrrp_recalculate_timers(r);
900 THREAD_OFF(r->t_master_down_timer);
901 thread_add_timer_msec(master,
902 vrrp_master_down_timer_expire, r,
903 r->master_down_interval * 10,
904 &r->t_master_down_timer);
905 vrrp_change_state(r, VRRP_STATE_BACKUP);
906 } else {
907 /* Discard advertisement */
908 DEBUGD(&vrrp_dbg_proto,
909 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
910 "Discarding advertisement from %s (%" PRIu8
911 " <= %" PRIu8 " & %s <= %s)",
912 r->vr->vrid, family2str(r->family), sipstr,
913 pkt->hdr.priority, r->priority, sipstr, dipstr);
914 }
915 break;
916 case VRRP_STATE_BACKUP:
917 if (pkt->hdr.priority == 0) {
918 THREAD_OFF(r->t_master_down_timer);
919 thread_add_timer_msec(
920 master, vrrp_master_down_timer_expire, r,
921 r->skew_time * 10, &r->t_master_down_timer);
922 } else if (r->vr->preempt_mode == false
923 || pkt->hdr.priority >= r->priority) {
924 if (r->vr->version == 3) {
925 r->master_adver_interval =
926 ntohs(pkt->hdr.v3.adver_int);
927 }
928 vrrp_recalculate_timers(r);
929 THREAD_OFF(r->t_master_down_timer);
930 thread_add_timer_msec(master,
931 vrrp_master_down_timer_expire, r,
932 r->master_down_interval * 10,
933 &r->t_master_down_timer);
934 } else if (r->vr->preempt_mode == true
935 && pkt->hdr.priority < r->priority) {
936 /* Discard advertisement */
937 DEBUGD(&vrrp_dbg_proto,
938 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
939 "Discarding advertisement from %s (%" PRIu8
940 " < %" PRIu8 " & preempt = true)",
941 r->vr->vrid, family2str(r->family), sipstr,
942 pkt->hdr.priority, r->priority);
943 }
944 break;
945 case VRRP_STATE_INITIALIZE:
946 zlog_err(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
947 "Received ADVERTISEMENT in state %s; this is a bug",
948 r->vr->vrid, family2str(r->family),
949 vrrp_state_names[r->fsm.state]);
950 break;
951 }
952
953 return 0;
954 }
955
956 /*
957 * Read and process next IPvX datagram.
958 */
959 static int vrrp_read(struct thread *thread)
960 {
961 struct vrrp_router *r = thread->arg;
962
963 struct vrrp_pkt *pkt;
964 ssize_t pktsize;
965 ssize_t nbytes;
966 bool resched;
967 char errbuf[BUFSIZ];
968 struct sockaddr_storage sa;
969 uint8_t control[64];
970 struct ipaddr src = {};
971
972 struct msghdr m = {};
973 struct iovec iov;
974
975 iov.iov_base = r->ibuf;
976 iov.iov_len = sizeof(r->ibuf);
977 m.msg_name = &sa;
978 m.msg_namelen = sizeof(sa);
979 m.msg_iov = &iov;
980 m.msg_iovlen = 1;
981 m.msg_control = control;
982 m.msg_controllen = sizeof(control);
983
984 nbytes = recvmsg(r->sock_rx, &m, MSG_DONTWAIT);
985
986 if ((nbytes < 0 && ERRNO_IO_RETRY(errno))) {
987 resched = true;
988 goto done;
989 } else if (nbytes <= 0) {
990 vrrp_event(r, VRRP_EVENT_SHUTDOWN);
991 resched = false;
992 goto done;
993 }
994
995 if (DEBUG_MODE_CHECK(&vrrp_dbg_pkt, DEBUG_MODE_ALL)) {
996 DEBUGD(&vrrp_dbg_pkt,
997 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
998 "Datagram rx: ",
999 r->vr->vrid, family2str(r->family));
1000 zlog_hexdump(r->ibuf, nbytes);
1001 }
1002
1003 pktsize = vrrp_pkt_parse_datagram(r->family, r->vr->version, &m, nbytes,
1004 &src, &pkt, errbuf, sizeof(errbuf));
1005
1006 if (pktsize < 0)
1007 DEBUGD(&vrrp_dbg_pkt,
1008 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1009 "Datagram invalid: %s",
1010 r->vr->vrid, family2str(r->family), errbuf);
1011 else
1012 vrrp_recv_advertisement(r, &src, pkt, pktsize);
1013
1014 resched = true;
1015
1016 done:
1017 memset(r->ibuf, 0x00, sizeof(r->ibuf));
1018
1019 if (resched)
1020 thread_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
1021
1022 return 0;
1023 }
1024
1025 /*
1026 * Creates and configures VRRP router sockets.
1027 *
1028 * This function:
1029 * - Creates two sockets, one for Tx, one for Rx
1030 * - Joins the Rx socket to the appropriate VRRP multicast group
1031 * - Sets the Tx socket to set the TTL (v4) or Hop Limit (v6) field to 255 for
1032 * all transmitted IPvX packets
1033 * - Requests the kernel to deliver IPv6 header values needed to validate VRRP
1034 * packets
1035 *
1036 * If any of the above fail, the sockets are closed. The only exception is if
1037 * the TTL / Hop Limit settings fail; these are logged, but configuration
1038 * proceeds.
1039 *
1040 * The first connected address on the Virtual Router's interface is used as the
1041 * interface address.
1042 *
1043 * r
1044 * VRRP Router for which to create listen socket
1045 *
1046 * Returns:
1047 * 0 on success
1048 * -1 on failure
1049 */
1050 static int vrrp_socket(struct vrrp_router *r)
1051 {
1052 int ret;
1053 bool failed = false;
1054
1055 frr_elevate_privs(&vrrp_privs)
1056 {
1057 r->sock_rx = socket(r->family, SOCK_RAW, IPPROTO_VRRP);
1058 r->sock_tx = socket(r->family, SOCK_RAW, IPPROTO_VRRP);
1059 }
1060
1061 if (r->sock_rx < 0 || r->sock_tx < 0) {
1062 const char *rxtx = r->sock_rx < 0 ? "Rx" : "Tx";
1063
1064 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1065 "Can't create VRRP %s socket",
1066 r->vr->vrid, family2str(r->family), rxtx);
1067 failed = true;
1068 goto done;
1069 }
1070
1071 /* Configure sockets */
1072 if (r->family == AF_INET) {
1073 /* Set Tx socket to always Tx with TTL set to 255 */
1074 int ttl = 255;
1075
1076 ret = setsockopt(r->sock_tx, IPPROTO_IP, IP_MULTICAST_TTL, &ttl,
1077 sizeof(ttl));
1078 if (ret < 0) {
1079 zlog_warn(
1080 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1081 "Failed to set outgoing multicast TTL count to 255; RFC 5798 compliant implementations will drop our packets",
1082 r->vr->vrid, family2str(r->family));
1083 }
1084
1085 /* Set Tx socket DSCP byte */
1086 setsockopt_ipv4_tos(r->sock_tx, IPTOS_PREC_INTERNETCONTROL);
1087
1088 /* Turn off multicast loop on Tx */
1089 setsockopt_ipv4_multicast_loop(r->sock_tx, 0);
1090
1091 /* Bind Rx socket to exact interface */
1092 frr_elevate_privs(&vrrp_privs)
1093 {
1094 ret = setsockopt(r->sock_rx, SOL_SOCKET,
1095 SO_BINDTODEVICE, r->vr->ifp->name,
1096 strlen(r->vr->ifp->name));
1097 }
1098 if (ret) {
1099 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1100 "Failed to bind Rx socket to %s: %s",
1101 r->vr->vrid, family2str(r->family),
1102 r->vr->ifp->name, safe_strerror(errno));
1103 failed = true;
1104 goto done;
1105 }
1106 DEBUGD(&vrrp_dbg_sock,
1107 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1108 "Bound Rx socket to %s",
1109 r->vr->vrid, family2str(r->family), r->vr->ifp->name);
1110
1111 /* Bind Rx socket to v4 multicast address */
1112 struct sockaddr_in sa = {0};
1113
1114 sa.sin_family = AF_INET;
1115 sa.sin_addr.s_addr = htonl(VRRP_MCASTV4_GROUP);
1116 if (bind(r->sock_rx, (struct sockaddr *)&sa, sizeof(sa))) {
1117 zlog_err(
1118 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1119 "Failed to bind Rx socket to VRRP multicast group: %s",
1120 r->vr->vrid, family2str(r->family),
1121 safe_strerror(errno));
1122 failed = true;
1123 goto done;
1124 }
1125 DEBUGD(&vrrp_dbg_sock,
1126 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1127 "Bound Rx socket to VRRP multicast group",
1128 r->vr->vrid, family2str(r->family));
1129
1130 /* Join Rx socket to VRRP IPv4 multicast group */
1131 assert(listhead(r->vr->ifp->connected));
1132 struct connected *c = listhead(r->vr->ifp->connected)->data;
1133 struct in_addr v4 = c->address->u.prefix4;
1134
1135 ret = setsockopt_ipv4_multicast(r->sock_rx, IP_ADD_MEMBERSHIP,
1136 v4, htonl(VRRP_MCASTV4_GROUP),
1137 r->vr->ifp->ifindex);
1138 if (ret < 0) {
1139 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID
1140 "Failed to join VRRP %s multicast group",
1141 r->vr->vrid, family2str(r->family));
1142 failed = true;
1143 goto done;
1144 }
1145 DEBUGD(&vrrp_dbg_sock,
1146 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1147 "Joined VRRP multicast group",
1148 r->vr->vrid, family2str(r->family));
1149
1150 /* Set outgoing interface for advertisements */
1151 struct ip_mreqn mreqn = {};
1152
1153 mreqn.imr_ifindex = r->mvl_ifp->ifindex;
1154 ret = setsockopt(r->sock_tx, IPPROTO_IP, IP_MULTICAST_IF,
1155 (void *)&mreqn, sizeof(mreqn));
1156 if (ret < 0) {
1157 zlog_warn(
1158 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1159 "Could not set %s as outgoing multicast interface",
1160 r->vr->vrid, family2str(r->family),
1161 r->mvl_ifp->name);
1162 failed = true;
1163 goto done;
1164 }
1165 DEBUGD(&vrrp_dbg_sock,
1166 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1167 "Set %s as outgoing multicast interface",
1168 r->vr->vrid, family2str(r->family), r->mvl_ifp->name);
1169
1170 /* Select and bind source address */
1171 if (vrrp_bind_to_primary_connected(r) < 0) {
1172 failed = true;
1173 goto done;
1174 }
1175
1176 } else if (r->family == AF_INET6) {
1177 /* Always transmit IPv6 packets with hop limit set to 255 */
1178 ret = setsockopt_ipv6_multicast_hops(r->sock_tx, 255);
1179 if (ret < 0) {
1180 zlog_warn(
1181 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1182 "Failed to set outgoing multicast hop count to 255; RFC 5798 compliant implementations will drop our packets",
1183 r->vr->vrid, family2str(r->family));
1184 }
1185
1186 /* Set Tx socket DSCP byte */
1187 setsockopt_ipv6_tclass(r->sock_tx, IPTOS_PREC_INTERNETCONTROL);
1188
1189 /* Request hop limit delivery */
1190 setsockopt_ipv6_hoplimit(r->sock_rx, 1);
1191 if (ret < 0) {
1192 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1193 "Failed to request IPv6 Hop Limit delivery",
1194 r->vr->vrid, family2str(r->family));
1195 failed = true;
1196 goto done;
1197 }
1198
1199 /* Turn off multicast loop on Tx */
1200 setsockopt_ipv6_multicast_loop(r->sock_tx, 0);
1201
1202 /* Bind Rx socket to exact interface */
1203 frr_elevate_privs(&vrrp_privs)
1204 {
1205 ret = setsockopt(r->sock_rx, SOL_SOCKET,
1206 SO_BINDTODEVICE, r->vr->ifp->name,
1207 strlen(r->vr->ifp->name));
1208 }
1209 if (ret) {
1210 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1211 "Failed to bind Rx socket to %s: %s",
1212 r->vr->vrid, family2str(r->family),
1213 r->vr->ifp->name, safe_strerror(errno));
1214 failed = true;
1215 goto done;
1216 }
1217 DEBUGD(&vrrp_dbg_sock,
1218 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1219 "Bound Rx socket to %s",
1220 r->vr->vrid, family2str(r->family), r->vr->ifp->name);
1221
1222 /* Bind Rx socket to v6 multicast address */
1223 struct sockaddr_in6 sa = {0};
1224
1225 sa.sin6_family = AF_INET6;
1226 inet_pton(AF_INET6, VRRP_MCASTV6_GROUP_STR, &sa.sin6_addr);
1227 if (bind(r->sock_rx, (struct sockaddr *)&sa, sizeof(sa))) {
1228 zlog_err(
1229 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1230 "Failed to bind Rx socket to VRRP multicast group: %s",
1231 r->vr->vrid, family2str(r->family),
1232 safe_strerror(errno));
1233 failed = true;
1234 goto done;
1235 }
1236 DEBUGD(&vrrp_dbg_sock,
1237 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1238 "Bound Rx socket to VRRP multicast group",
1239 r->vr->vrid, family2str(r->family));
1240
1241 /* Join VRRP IPv6 multicast group */
1242 struct ipv6_mreq mreq;
1243
1244 inet_pton(AF_INET6, VRRP_MCASTV6_GROUP_STR,
1245 &mreq.ipv6mr_multiaddr);
1246 mreq.ipv6mr_interface = r->vr->ifp->ifindex;
1247 ret = setsockopt(r->sock_rx, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1248 &mreq, sizeof(mreq));
1249 if (ret < 0) {
1250 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1251 "Failed to join VRRP multicast group",
1252 r->vr->vrid, family2str(r->family));
1253 failed = true;
1254 goto done;
1255 }
1256 DEBUGD(&vrrp_dbg_sock,
1257 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1258 "Joined VRRP multicast group",
1259 r->vr->vrid, family2str(r->family));
1260
1261 /* Set outgoing interface for advertisements */
1262 ret = setsockopt(r->sock_tx, IPPROTO_IPV6, IPV6_MULTICAST_IF,
1263 &r->mvl_ifp->ifindex, sizeof(ifindex_t));
1264 if (ret < 0) {
1265 zlog_warn(
1266 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1267 "Could not set %s as outgoing multicast interface",
1268 r->vr->vrid, family2str(r->family),
1269 r->mvl_ifp->name);
1270 failed = true;
1271 goto done;
1272 }
1273 DEBUGD(&vrrp_dbg_sock,
1274 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1275 "Set %s as outgoing multicast interface",
1276 r->vr->vrid, family2str(r->family), r->mvl_ifp->name);
1277 }
1278
1279 done:
1280 ret = 0;
1281 if (failed) {
1282 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1283 "Failed to initialize VRRP router",
1284 r->vr->vrid, family2str(r->family));
1285 if (r->sock_rx >= 0) {
1286 close(r->sock_rx);
1287 r->sock_rx = -1;
1288 }
1289 if (r->sock_tx >= 0) {
1290 close(r->sock_tx);
1291 r->sock_tx = -1;
1292 }
1293 ret = -1;
1294 }
1295
1296 return ret;
1297 }
1298
1299
1300 /* State machine ----------------------------------------------------------- */
1301
1302 DEFINE_HOOK(vrrp_change_state_hook, (struct vrrp_router *r, int to), (r, to));
1303
1304 /*
1305 * Handle any necessary actions during state change to MASTER state.
1306 *
1307 * r
1308 * VRRP Router to operate on
1309 */
1310 static void vrrp_change_state_master(struct vrrp_router *r)
1311 {
1312 /* Enable ND Router Advertisements */
1313 if (r->family == AF_INET6)
1314 vrrp_zebra_radv_set(r, true);
1315
1316 /* Set protodown off */
1317 vrrp_zclient_send_interface_protodown(r->mvl_ifp, false);
1318
1319 /*
1320 * If protodown is already off, we can send our stuff, otherwise we
1321 * have to delay until the interface is all the way up
1322 */
1323 if (if_is_operative(r->mvl_ifp)) {
1324 vrrp_send_advertisement(r);
1325
1326 if (r->family == AF_INET)
1327 vrrp_garp_send_all(r);
1328 else if (r->family == AF_INET6)
1329 vrrp_ndisc_una_send_all(r);
1330 } else {
1331 DEBUGD(&vrrp_dbg_proto,
1332 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1333 "Delaying VRRP advertisement until interface is up",
1334 r->vr->vrid, family2str(r->family));
1335 r->advert_pending = true;
1336
1337 if (r->family == AF_INET) {
1338 DEBUGD(&vrrp_dbg_proto,
1339 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1340 "Delaying VRRP gratuitous ARPs until interface is up",
1341 r->vr->vrid, family2str(r->family));
1342 r->garp_pending = true;
1343 } else if (r->family == AF_INET6) {
1344 DEBUGD(&vrrp_dbg_proto,
1345 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1346 "Delaying VRRP unsolicited neighbor advertisement until interface is up",
1347 r->vr->vrid, family2str(r->family));
1348 r->ndisc_pending = true;
1349 }
1350 }
1351 }
1352
1353 /*
1354 * Handle any necessary actions during state change to BACKUP state.
1355 *
1356 * r
1357 * Virtual Router to operate on
1358 */
1359 static void vrrp_change_state_backup(struct vrrp_router *r)
1360 {
1361 /* Disable ND Router Advertisements */
1362 if (r->family == AF_INET6)
1363 vrrp_zebra_radv_set(r, false);
1364
1365 /* Disable Adver_Timer */
1366 THREAD_OFF(r->t_adver_timer);
1367
1368 r->advert_pending = false;
1369 r->garp_pending = false;
1370 r->ndisc_pending = false;
1371 memset(&r->src, 0x00, sizeof(r->src));
1372
1373 vrrp_zclient_send_interface_protodown(r->mvl_ifp, true);
1374 }
1375
1376 /*
1377 * Handle any necessary actions during state change to INITIALIZE state.
1378 *
1379 * This is not called for initial startup, only when transitioning from MASTER
1380 * or BACKUP.
1381 *
1382 * r
1383 * VRRP Router to operate on
1384 */
1385 static void vrrp_change_state_initialize(struct vrrp_router *r)
1386 {
1387 r->master_adver_interval = 0;
1388 vrrp_recalculate_timers(r);
1389
1390 r->advert_pending = false;
1391 r->garp_pending = false;
1392 r->ndisc_pending = false;
1393
1394 /* Disable ND Router Advertisements */
1395 if (r->family == AF_INET6)
1396 vrrp_zebra_radv_set(r, false);
1397 }
1398
1399 void (*vrrp_change_state_handlers[])(struct vrrp_router *vr) = {
1400 [VRRP_STATE_MASTER] = vrrp_change_state_master,
1401 [VRRP_STATE_BACKUP] = vrrp_change_state_backup,
1402 [VRRP_STATE_INITIALIZE] = vrrp_change_state_initialize,
1403 };
1404
1405 /*
1406 * Change Virtual Router FSM position. Handles transitional actions and calls
1407 * any subscribers to the state change hook.
1408 *
1409 * r
1410 * Virtual Router for which to change state
1411 *
1412 * to
1413 * State to change to
1414 */
1415 static void vrrp_change_state(struct vrrp_router *r, int to)
1416 {
1417 if (r->fsm.state == to)
1418 return;
1419
1420 /* Call our handlers, then any subscribers */
1421 vrrp_change_state_handlers[to](r);
1422 hook_call(vrrp_change_state_hook, r, to);
1423 zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM "%s -> %s",
1424 r->vr->vrid, family2str(r->family),
1425 vrrp_state_names[r->fsm.state], vrrp_state_names[to]);
1426 r->fsm.state = to;
1427
1428 ++r->stats.trans_cnt;
1429 }
1430
1431 /*
1432 * Called when Adver_Timer expires.
1433 */
1434 static int vrrp_adver_timer_expire(struct thread *thread)
1435 {
1436 struct vrrp_router *r = thread->arg;
1437
1438 DEBUGD(&vrrp_dbg_proto,
1439 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1440 "Adver_Timer expired",
1441 r->vr->vrid, family2str(r->family));
1442
1443 if (r->fsm.state == VRRP_STATE_MASTER) {
1444 /* Send an ADVERTISEMENT */
1445 vrrp_send_advertisement(r);
1446
1447 /* Reset the Adver_Timer to Advertisement_Interval */
1448 thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
1449 r->vr->advertisement_interval * 10,
1450 &r->t_adver_timer);
1451 } else {
1452 zlog_err(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1453 "Adver_Timer expired in state '%s'; this is a bug",
1454 r->vr->vrid, family2str(r->family),
1455 vrrp_state_names[r->fsm.state]);
1456 }
1457
1458 return 0;
1459 }
1460
1461 /*
1462 * Called when Master_Down_Timer expires.
1463 */
1464 static int vrrp_master_down_timer_expire(struct thread *thread)
1465 {
1466 struct vrrp_router *r = thread->arg;
1467
1468 zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1469 "Master_Down_Timer expired",
1470 r->vr->vrid, family2str(r->family));
1471
1472 thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
1473 r->vr->advertisement_interval * 10,
1474 &r->t_adver_timer);
1475 vrrp_change_state(r, VRRP_STATE_MASTER);
1476
1477 return 0;
1478 }
1479
1480 /*
1481 * Event handler for Startup event.
1482 *
1483 * Creates sockets, sends advertisements and ARP requests, starts timers,
1484 * and transitions the Virtual Router to either Master or Backup states.
1485 *
1486 * This function will also initialize the program's global ARP subsystem if it
1487 * has not yet been initialized.
1488 *
1489 * r
1490 * VRRP Router on which to apply Startup event
1491 *
1492 * Returns:
1493 * < 0 if the session socket could not be created, or the state is not
1494 * Initialize
1495 * 0 on success
1496 */
1497 static int vrrp_startup(struct vrrp_router *r)
1498 {
1499 /* May only be called when the state is Initialize */
1500 if (r->fsm.state != VRRP_STATE_INITIALIZE)
1501 return -1;
1502
1503 /* Must have a valid macvlan interface available */
1504 if (r->mvl_ifp == NULL && !vrrp_attach_interface(r)) {
1505 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1506 "No appropriate interface found",
1507 r->vr->vrid, family2str(r->family));
1508 return -1;
1509 }
1510
1511 /* Initialize global gratuitous ARP socket if necessary */
1512 if (r->family == AF_INET && !vrrp_garp_is_init())
1513 vrrp_garp_init();
1514 if (r->family == AF_INET6 && !vrrp_ndisc_is_init())
1515 vrrp_ndisc_init();
1516
1517 /* Create socket */
1518 if (r->sock_rx < 0 || r->sock_tx < 0) {
1519 int ret = vrrp_socket(r);
1520
1521 if (ret < 0 || r->sock_tx < 0 || r->sock_rx < 0)
1522 return ret;
1523 }
1524
1525 /* Schedule listener */
1526 thread_add_read(master, vrrp_read, r, r->sock_rx, &r->t_read);
1527
1528 /* Configure effective priority */
1529 assert(listhead(r->addrs));
1530 struct ipaddr *primary = (struct ipaddr *)listhead(r->addrs)->data;
1531 char ipbuf[INET6_ADDRSTRLEN];
1532
1533 inet_ntop(r->family, &primary->ip.addr, ipbuf, sizeof(ipbuf));
1534
1535 if (r->vr->priority == VRRP_PRIO_MASTER
1536 || vrrp_is_owner(r->vr->ifp, primary)) {
1537 r->priority = VRRP_PRIO_MASTER;
1538 vrrp_recalculate_timers(r);
1539
1540 zlog_info(
1541 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1542 "%s has priority set to 255 or owns primary Virtual Router IP %s; electing self as Master",
1543 r->vr->vrid, family2str(r->family), r->vr->ifp->name,
1544 ipbuf);
1545 }
1546
1547 if (r->priority == VRRP_PRIO_MASTER) {
1548 thread_add_timer_msec(master, vrrp_adver_timer_expire, r,
1549 r->vr->advertisement_interval * 10,
1550 &r->t_adver_timer);
1551 vrrp_change_state(r, VRRP_STATE_MASTER);
1552 } else {
1553 r->master_adver_interval = r->vr->advertisement_interval;
1554 vrrp_recalculate_timers(r);
1555 thread_add_timer_msec(master, vrrp_master_down_timer_expire, r,
1556 r->master_down_interval * 10,
1557 &r->t_master_down_timer);
1558 vrrp_change_state(r, VRRP_STATE_BACKUP);
1559 }
1560
1561 r->is_active = true;
1562
1563 return 0;
1564 }
1565
1566 /*
1567 * Shuts down a Virtual Router and transitions it to Initialize.
1568 *
1569 * This call must be idempotent; it is safe to call multiple times on the same
1570 * VRRP Router.
1571 */
1572 static int vrrp_shutdown(struct vrrp_router *r)
1573 {
1574 uint8_t saved_prio;
1575
1576 switch (r->fsm.state) {
1577 case VRRP_STATE_MASTER:
1578 /* Send an ADVERTISEMENT with Priority = 0 */
1579 saved_prio = r->priority;
1580 r->priority = 0;
1581 vrrp_send_advertisement(r);
1582 r->priority = saved_prio;
1583 break;
1584 case VRRP_STATE_BACKUP:
1585 break;
1586 case VRRP_STATE_INITIALIZE:
1587 DEBUGD(&vrrp_dbg_proto,
1588 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1589 "Received '%s' event in '%s' state; ignoring",
1590 r->vr->vrid, family2str(r->family),
1591 vrrp_event_names[VRRP_EVENT_SHUTDOWN],
1592 vrrp_state_names[VRRP_STATE_INITIALIZE]);
1593 break;
1594 }
1595
1596 /* Cancel all timers */
1597 THREAD_OFF(r->t_adver_timer);
1598 THREAD_OFF(r->t_master_down_timer);
1599 THREAD_OFF(r->t_read);
1600 THREAD_OFF(r->t_write);
1601
1602 /* Protodown macvlan */
1603 vrrp_zclient_send_interface_protodown(r->mvl_ifp, true);
1604
1605 /* Throw away our source address */
1606 memset(&r->src, 0x00, sizeof(r->src));
1607
1608 if (r->sock_rx > 0) {
1609 close(r->sock_rx);
1610 r->sock_rx = -1;
1611 }
1612 if (r->sock_tx > 0) {
1613 close(r->sock_tx);
1614 r->sock_tx = -1;
1615 }
1616
1617 vrrp_change_state(r, VRRP_STATE_INITIALIZE);
1618
1619 r->is_active = false;
1620
1621 return 0;
1622 }
1623
1624 static int (*vrrp_event_handlers[])(struct vrrp_router *r) = {
1625 [VRRP_EVENT_STARTUP] = vrrp_startup,
1626 [VRRP_EVENT_SHUTDOWN] = vrrp_shutdown,
1627 };
1628
1629 /*
1630 * Spawn a VRRP FSM event on a VRRP Router.
1631 *
1632 * vr
1633 * VRRP Router on which to spawn event
1634 *
1635 * event
1636 * The event to spawn
1637 *
1638 * Returns:
1639 * -1 on failure
1640 * 0 otherwise
1641 */
1642 int vrrp_event(struct vrrp_router *r, int event)
1643 {
1644 zlog_info(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM "'%s' event",
1645 r->vr->vrid, family2str(r->family), vrrp_event_names[event]);
1646 return vrrp_event_handlers[event](r);
1647 }
1648
1649
1650 /* Autoconfig -------------------------------------------------------------- */
1651
1652 /*
1653 * Set the configured addresses for this VRRP instance to exactly the addresses
1654 * present on its macvlan subinterface(s).
1655 *
1656 * vr
1657 * VRRP router to act on
1658 */
1659 static void vrrp_autoconfig_autoaddrupdate(struct vrrp_router *r)
1660 {
1661 struct listnode *ln;
1662 struct connected *c = NULL;
1663 bool is_v6_ll;
1664 char ipbuf[INET6_ADDRSTRLEN];
1665
1666 if (!r->mvl_ifp)
1667 return;
1668
1669 DEBUGD(&vrrp_dbg_auto,
1670 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1671 "Setting Virtual IP list to match IPv4 addresses on %s",
1672 r->vr->vrid, family2str(r->family), r->mvl_ifp->name);
1673 for (ALL_LIST_ELEMENTS_RO(r->mvl_ifp->connected, ln, c)) {
1674 is_v6_ll = (c->address->family == AF_INET6
1675 && IN6_IS_ADDR_LINKLOCAL(&c->address->u.prefix6));
1676 if (c->address->family == r->family && !is_v6_ll) {
1677 inet_ntop(r->family, &c->address->u.prefix, ipbuf,
1678 sizeof(ipbuf));
1679 DEBUGD(&vrrp_dbg_auto,
1680 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1681 "Adding %s",
1682 r->vr->vrid, family2str(r->family), ipbuf);
1683 if (r->family == AF_INET)
1684 vrrp_add_ipv4(r->vr, c->address->u.prefix4);
1685 else if (r->vr->version == 3)
1686 vrrp_add_ipv6(r->vr, c->address->u.prefix6);
1687 }
1688 }
1689
1690 vrrp_check_start(r->vr);
1691
1692 if (r->addrs->count == 0 && r->fsm.state != VRRP_STATE_INITIALIZE) {
1693 DEBUGD(&vrrp_dbg_auto,
1694 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1695 "Virtual IP list is empty; shutting down",
1696 r->vr->vrid, family2str(r->family));
1697 vrrp_event(r, VRRP_EVENT_SHUTDOWN);
1698 }
1699 }
1700
1701 static struct vrrp_vrouter *
1702 vrrp_autoconfig_autocreate(struct interface *mvl_ifp)
1703 {
1704 struct interface *p;
1705 struct vrrp_vrouter *vr;
1706
1707 p = if_lookup_by_index(mvl_ifp->link_ifindex, VRF_DEFAULT);
1708
1709 if (!p)
1710 return NULL;
1711
1712 uint8_t vrid = mvl_ifp->hw_addr[5];
1713 uint8_t fam = mvl_ifp->hw_addr[4];
1714
1715 DEBUGD(&vrrp_dbg_auto,
1716 VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1717 "Autoconfiguring VRRP on %s",
1718 vrid, family2str(fam), p->name);
1719
1720 vr = vrrp_vrouter_create(p, vrid, vrrp_autoconfig_version);
1721
1722 if (!vr) {
1723 zlog_warn(VRRP_LOGPFX VRRP_LOGPFX_VRID VRRP_LOGPFX_FAM
1724 "Failed to autoconfigure VRRP on %s",
1725 vrid, family2str(fam), p->name);
1726 return NULL;
1727 }
1728
1729 vr->autoconf = true;
1730
1731 /*
1732 * If these interfaces are protodown on, we need to un-protodown them
1733 * in order to get Zebra to send us their addresses so we can
1734 * autoconfigure them.
1735 */
1736 if (vr->v4->mvl_ifp)
1737 vrrp_zclient_send_interface_protodown(vr->v4->mvl_ifp, false);
1738 if (vr->v6->mvl_ifp)
1739 vrrp_zclient_send_interface_protodown(vr->v6->mvl_ifp, false);
1740
1741 /* If they're not, we can go ahead and add the addresses we have */
1742 vrrp_autoconfig_autoaddrupdate(vr->v4);
1743 vrrp_autoconfig_autoaddrupdate(vr->v6);
1744
1745 return vr;
1746 }
1747
1748 /*
1749 * Callback to notify autoconfig of interface add.
1750 *
1751 * If the interface is a VRRP-compatible device, and there is no existing VRRP
1752 * router running on it, one is created. All addresses on the interface are
1753 * added to the router.
1754 *
1755 * ifp
1756 * Interface to operate on
1757 *
1758 * Returns:
1759 * -1 on failure
1760 * 0 otherwise
1761 */
1762 static int vrrp_autoconfig_if_add(struct interface *ifp)
1763 {
1764 bool created = false;
1765 struct vrrp_vrouter *vr;
1766
1767 if (!vrrp_autoconfig_is_on)
1768 return 0;
1769
1770 if (!ifp || !ifp->link_ifindex || !vrrp_ifp_has_vrrp_mac(ifp))
1771 return -1;
1772
1773 vr = vrrp_lookup_by_if_mvl(ifp);
1774
1775 if (!vr) {
1776 vr = vrrp_autoconfig_autocreate(ifp);
1777 created = true;
1778 }
1779
1780 if (!vr || vr->autoconf == false)
1781 return 0;
1782
1783 if (!created) {
1784 /*
1785 * We didn't create it, but it has already been autoconfigured.
1786 * Try to attach this interface to the existing instance.
1787 */
1788 if (!vr->v4->mvl_ifp) {
1789 vrrp_attach_interface(vr->v4);
1790 /* If we just attached it, make sure it's turned on */
1791 if (vr->v4->mvl_ifp) {
1792 vrrp_zclient_send_interface_protodown(
1793 vr->v4->mvl_ifp, false);
1794 /*
1795 * If it's already up, we can go ahead and add
1796 * the addresses we have
1797 */
1798 vrrp_autoconfig_autoaddrupdate(vr->v4);
1799 }
1800 }
1801 if (!vr->v6->mvl_ifp) {
1802 vrrp_attach_interface(vr->v6);
1803 /* If we just attached it, make sure it's turned on */
1804 if (vr->v6->mvl_ifp) {
1805 vrrp_zclient_send_interface_protodown(
1806 vr->v6->mvl_ifp, false);
1807 /*
1808 * If it's already up, we can go ahead and add
1809 * the addresses we have
1810 */
1811 vrrp_autoconfig_autoaddrupdate(vr->v6);
1812 }
1813 }
1814 }
1815
1816 return 0;
1817 }
1818
1819 /*
1820 * Callback to notify autoconfig of interface delete.
1821 *
1822 * If the interface is a VRRP-compatible device, and a VRRP router is running
1823 * on it, and that VRRP router was automatically configured, it will be
1824 * deleted. If that was the last router for the corresponding VRID (i.e., if
1825 * this interface was a v4 VRRP interface and no v6 router is configured for
1826 * the same VRID) then the entire virtual router is deleted.
1827 *
1828 * ifp
1829 * Interface to operate on
1830 *
1831 * Returns:
1832 * -1 on failure
1833 * 0 otherwise
1834 */
1835 static int vrrp_autoconfig_if_del(struct interface *ifp)
1836 {
1837 if (!vrrp_autoconfig_is_on)
1838 return 0;
1839
1840 struct vrrp_vrouter *vr;
1841 struct listnode *ln;
1842 struct list *vrs;
1843
1844 vrs = vrrp_lookup_by_if_any(ifp);
1845
1846 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr))
1847 if (vr->autoconf
1848 && (!vr->ifp || (!vr->v4->mvl_ifp && !vr->v6->mvl_ifp))) {
1849 DEBUGD(&vrrp_dbg_auto,
1850 VRRP_LOGPFX VRRP_LOGPFX_VRID
1851 "All VRRP interfaces for instance deleted; destroying autoconfigured VRRP router",
1852 vr->vrid);
1853 vrrp_vrouter_destroy(vr);
1854 }
1855
1856 list_delete(&vrs);
1857
1858 return 0;
1859 }
1860
1861 /*
1862 * Callback to notify autoconfig of interface up.
1863 *
1864 * Creates VRRP instance on interface if it does not exist. Otherwise does
1865 * nothing.
1866 *
1867 * ifp
1868 * Interface to operate on
1869 *
1870 * Returns:
1871 * -1 on failure
1872 * 0 otherwise
1873 */
1874 static int vrrp_autoconfig_if_up(struct interface *ifp)
1875 {
1876 if (!vrrp_autoconfig_is_on)
1877 return 0;
1878
1879 struct vrrp_vrouter *vr = vrrp_lookup_by_if_mvl(ifp);
1880
1881 if (vr && !vr->autoconf)
1882 return 0;
1883
1884 if (!vr) {
1885 vrrp_autoconfig_if_add(ifp);
1886 return 0;
1887 }
1888
1889 return 0;
1890 }
1891
1892 /*
1893 * Callback to notify autoconfig of interface down.
1894 *
1895 * Does nothing. An interface down event is accompanied by address deletion
1896 * events for all the addresses on the interface; if an autoconfigured VRRP
1897 * router exists on this interface, then it will have all its addresses deleted
1898 * and end up in Initialize.
1899 *
1900 * ifp
1901 * Interface to operate on
1902 *
1903 * Returns:
1904 * -1 on failure
1905 * 0 otherwise
1906 */
1907 static int vrrp_autoconfig_if_down(struct interface *ifp)
1908 {
1909 if (!vrrp_autoconfig_is_on)
1910 return 0;
1911
1912 return 0;
1913 }
1914
1915 /*
1916 * Callback to notify autoconfig of a new interface address.
1917 *
1918 * If a VRRP router exists on this interface, its address list is updated to
1919 * match the new address list. If no addresses remain, a Shutdown event is
1920 * issued to the VRRP router.
1921 *
1922 * ifp
1923 * Interface to operate on
1924 *
1925 * Returns:
1926 * -1 on failure
1927 * 0 otherwise
1928 *
1929 */
1930 static int vrrp_autoconfig_if_address_add(struct interface *ifp)
1931 {
1932 if (!vrrp_autoconfig_is_on)
1933 return 0;
1934
1935 struct vrrp_vrouter *vr = vrrp_lookup_by_if_mvl(ifp);
1936
1937 if (vr && vr->autoconf) {
1938 if (vr->v4->mvl_ifp == ifp)
1939 vrrp_autoconfig_autoaddrupdate(vr->v4);
1940 else if (vr->v6->mvl_ifp == ifp)
1941 vrrp_autoconfig_autoaddrupdate(vr->v6);
1942 }
1943
1944 return 0;
1945 }
1946
1947 /*
1948 * Callback to notify autoconfig of a removed interface address.
1949 *
1950 * If a VRRP router exists on this interface, its address list is updated to
1951 * match the new address list. If no addresses remain, a Shutdown event is
1952 * issued to the VRRP router.
1953 *
1954 * ifp
1955 * Interface to operate on
1956 *
1957 * Returns:
1958 * -1 on failure
1959 * 0 otherwise
1960 *
1961 */
1962 static int vrrp_autoconfig_if_address_del(struct interface *ifp)
1963 {
1964 if (!vrrp_autoconfig_is_on)
1965 return 0;
1966
1967 struct vrrp_vrouter *vr = vrrp_lookup_by_if_mvl(ifp);
1968
1969 if (vr && vr->autoconf) {
1970 if (vr->v4->mvl_ifp == ifp)
1971 vrrp_autoconfig_autoaddrupdate(vr->v4);
1972 else if (vr->v6->mvl_ifp == ifp)
1973 vrrp_autoconfig_autoaddrupdate(vr->v6);
1974 }
1975
1976 return 0;
1977 }
1978
1979 int vrrp_autoconfig(void)
1980 {
1981 if (!vrrp_autoconfig_is_on)
1982 return 0;
1983
1984 struct vrf *vrf = vrf_lookup_by_id(VRF_DEFAULT);
1985 struct interface *ifp;
1986
1987 FOR_ALL_INTERFACES (vrf, ifp)
1988 vrrp_autoconfig_if_add(ifp);
1989
1990 return 0;
1991 }
1992
1993 void vrrp_autoconfig_on(int version)
1994 {
1995 vrrp_autoconfig_is_on = true;
1996 vrrp_autoconfig_version = version;
1997
1998 vrrp_autoconfig();
1999 }
2000
2001 void vrrp_autoconfig_off(void)
2002 {
2003 vrrp_autoconfig_is_on = false;
2004
2005 struct list *ll = hash_to_list(vrrp_vrouters_hash);
2006
2007 struct listnode *ln;
2008 struct vrrp_vrouter *vr;
2009
2010 for (ALL_LIST_ELEMENTS_RO(ll, ln, vr))
2011 if (vr->autoconf)
2012 vrrp_vrouter_destroy(vr);
2013
2014 list_delete(&ll);
2015 }
2016
2017 /* Interface tracking ------------------------------------------------------ */
2018
2019 /*
2020 * Bind any pending interfaces.
2021 *
2022 * mvl_ifp
2023 * macvlan interface that some VRRP instances might want to bind to
2024 */
2025 static void vrrp_bind_pending(struct interface *mvl_ifp)
2026 {
2027 struct vrrp_vrouter *vr;
2028
2029 vr = vrrp_lookup_by_if_mvl(mvl_ifp);
2030
2031 if (vr) {
2032 if (mvl_ifp->hw_addr[4] == 0x01 && !vr->v4->mvl_ifp)
2033 vrrp_attach_interface(vr->v4);
2034 else if (mvl_ifp->hw_addr[4] == 0x02 && !vr->v6->mvl_ifp)
2035 vrrp_attach_interface(vr->v6);
2036 }
2037 }
2038
2039 void vrrp_if_up(struct interface *ifp)
2040 {
2041 struct vrrp_vrouter *vr;
2042 struct listnode *ln;
2043 struct list *vrs;
2044
2045 vrrp_bind_pending(ifp);
2046
2047 vrs = vrrp_lookup_by_if_any(ifp);
2048
2049 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr)) {
2050 vrrp_check_start(vr);
2051
2052 if (!if_is_operative(ifp))
2053 continue;
2054
2055 /*
2056 * Handle the situation in which we performed a state
2057 * transition on this VRRP router but needed to wait for the
2058 * macvlan interface to come up to perform some actions
2059 */
2060 if (ifp == vr->v4->mvl_ifp) {
2061 if (vr->v4->advert_pending) {
2062 DEBUGD(&vrrp_dbg_proto,
2063 VRRP_LOGPFX VRRP_LOGPFX_VRID
2064 VRRP_LOGPFX_FAM
2065 "Interface up; sending pending advertisement",
2066 vr->vrid, family2str(vr->v4->family));
2067 vrrp_send_advertisement(vr->v4);
2068 vr->v4->advert_pending = false;
2069 }
2070 if (vr->v4->garp_pending) {
2071 DEBUGD(&vrrp_dbg_proto,
2072 VRRP_LOGPFX VRRP_LOGPFX_VRID
2073 VRRP_LOGPFX_FAM
2074 "Interface up; sending pending gratuitous ARP",
2075 vr->vrid, family2str(vr->v4->family));
2076 vrrp_garp_send_all(vr->v4);
2077 vr->v4->garp_pending = false;
2078 }
2079 }
2080 if (ifp == vr->v6->mvl_ifp) {
2081 if (vr->v6->advert_pending) {
2082 DEBUGD(&vrrp_dbg_proto,
2083 VRRP_LOGPFX VRRP_LOGPFX_VRID
2084 VRRP_LOGPFX_FAM
2085 "Interface up; sending pending advertisement",
2086 vr->vrid, family2str(vr->v6->family));
2087 vrrp_send_advertisement(vr->v6);
2088 vr->v6->advert_pending = false;
2089 }
2090 if (vr->v6->ndisc_pending) {
2091 DEBUGD(&vrrp_dbg_proto,
2092 VRRP_LOGPFX VRRP_LOGPFX_VRID
2093 VRRP_LOGPFX_FAM
2094 "Interface up; sending pending Unsolicited Neighbor Advertisement",
2095 vr->vrid, family2str(vr->v6->family));
2096 vrrp_ndisc_una_send_all(vr->v6);
2097 vr->v6->ndisc_pending = false;
2098 }
2099 }
2100 }
2101
2102 list_delete(&vrs);
2103
2104 vrrp_autoconfig_if_up(ifp);
2105 }
2106
2107 void vrrp_if_down(struct interface *ifp)
2108 {
2109 struct vrrp_vrouter *vr;
2110 struct listnode *ln;
2111 struct list *vrs;
2112
2113 vrs = vrrp_lookup_by_if_any(ifp);
2114
2115 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr)) {
2116 if (vr->ifp == ifp || vr->v4->mvl_ifp == ifp
2117 || vr->v6->mvl_ifp == ifp) {
2118 DEBUGD(&vrrp_dbg_auto,
2119 VRRP_LOGPFX VRRP_LOGPFX_VRID "Interface %s down",
2120 vr->vrid, ifp->name);
2121 }
2122 }
2123
2124 list_delete(&vrs);
2125
2126 vrrp_autoconfig_if_down(ifp);
2127 }
2128
2129 void vrrp_if_add(struct interface *ifp)
2130 {
2131 vrrp_bind_pending(ifp);
2132
2133 /* thanks, zebra */
2134 if (CHECK_FLAG(ifp->flags, IFF_UP))
2135 vrrp_if_up(ifp);
2136
2137 vrrp_autoconfig_if_add(ifp);
2138 }
2139
2140 void vrrp_if_del(struct interface *ifp)
2141 {
2142 struct listnode *ln;
2143 struct vrrp_vrouter *vr;
2144 struct list *vrs = vrrp_lookup_by_if_any(ifp);
2145
2146 vrrp_if_down(ifp);
2147
2148 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr)) {
2149 if ((vr->v4->mvl_ifp == ifp || vr->ifp == ifp)
2150 && vr->v4->fsm.state != VRRP_STATE_INITIALIZE) {
2151 vrrp_event(vr->v4, VRRP_EVENT_SHUTDOWN);
2152 vr->v4->mvl_ifp = NULL;
2153 } else if ((vr->v6->mvl_ifp == ifp || vr->ifp == ifp)
2154 && vr->v6->fsm.state != VRRP_STATE_INITIALIZE) {
2155 vrrp_event(vr->v6, VRRP_EVENT_SHUTDOWN);
2156 vr->v6->mvl_ifp = NULL;
2157 }
2158 }
2159
2160 list_delete(&vrs);
2161
2162 vrrp_autoconfig_if_del(ifp);
2163 }
2164
2165 void vrrp_if_address_add(struct interface *ifp)
2166 {
2167 struct vrrp_vrouter *vr;
2168 struct listnode *ln;
2169 struct list *vrs;
2170
2171 /*
2172 * We have to do a wide search here, because we need to know when a v6
2173 * macvlan device gets a new address. This is because the macvlan link
2174 * local is used as the source address for v6 advertisements, and hence
2175 * "do I have a link local" constitutes an activation condition for v6
2176 * virtual routers.
2177 */
2178 vrs = vrrp_lookup_by_if_any(ifp);
2179
2180 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr))
2181 vrrp_check_start(vr);
2182
2183 list_delete(&vrs);
2184
2185 vrrp_autoconfig_if_address_add(ifp);
2186 }
2187
2188 void vrrp_if_address_del(struct interface *ifp)
2189 {
2190 /*
2191 * Zebra is stupid and sends us address deletion notifications
2192 * when any of the following condition sets are met:
2193 *
2194 * - if_is_operative && address deleted
2195 * - if_is_operative -> !if_is_operative
2196 *
2197 * Note that the second one is nonsense, because Zebra behaves as
2198 * though an interface going down means all the addresses on that
2199 * interface got deleted. Which is a problem for autoconfig because all
2200 * the addresses on an interface going away means the VRRP session goes
2201 * to Initialize. However interfaces go down whenever we transition to
2202 * Backup, so this effectively means that for autoconfigured instances
2203 * we actually end up in Initialize whenever we try to go into Backup.
2204 *
2205 * Also, Zebra does NOT send us notifications when:
2206 * - !if_is_operative && address deleted
2207 *
2208 * Which means if we're in backup and an address is deleted out from
2209 * under us, we won't even know.
2210 *
2211 * The only solution here is to only resynchronize our address list
2212 * when:
2213 *
2214 * - An interfaces comes up
2215 * - An interface address is added
2216 * - An interface address is deleted AND the interface is up
2217 *
2218 * Even though this is only a problem with autoconfig at the moment I'm
2219 * papering over Zebra's braindead semantics here. Every piece of code
2220 * in this function should be protected by a check that the interface
2221 * is up.
2222 */
2223 if (if_is_operative(ifp))
2224 vrrp_autoconfig_if_address_del(ifp);
2225 }
2226
2227 /* Other ------------------------------------------------------------------- */
2228
2229 int vrrp_config_write_interface(struct vty *vty)
2230 {
2231 struct list *vrs = hash_to_list(vrrp_vrouters_hash);
2232 struct listnode *ln, *ipln;
2233 struct vrrp_vrouter *vr;
2234 int writes = 0;
2235
2236 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr)) {
2237 vty_frame(vty, "interface %s\n", vr->ifp->name);
2238 ++writes;
2239
2240 vty_out(vty, " vrrp %" PRIu8 "%s\n", vr->vrid,
2241 vr->version == 2 ? " version 2" : "");
2242 ++writes;
2243
2244 if (vr->shutdown != vd.shutdown && ++writes)
2245 vty_out(vty, " %svrrp %" PRIu8 " shutdown\n",
2246 vr->shutdown ? "" : "no ", vr->vrid);
2247
2248 if (vr->preempt_mode != vd.preempt_mode && ++writes)
2249 vty_out(vty, " %svrrp %" PRIu8 " preempt\n",
2250 vr->preempt_mode ? "" : "no ", vr->vrid);
2251
2252 if (vr->accept_mode != vd.accept_mode && ++writes)
2253 vty_out(vty, " %svrrp %" PRIu8 " accept\n",
2254 vr->accept_mode ? "" : "no ", vr->vrid);
2255
2256 if (vr->advertisement_interval != vd.advertisement_interval
2257 && ++writes)
2258 vty_out(vty,
2259 " vrrp %" PRIu8
2260 " advertisement-interval %d\n",
2261 vr->vrid, vr->advertisement_interval * CS2MS);
2262
2263 if (vr->priority != vd.priority && ++writes)
2264 vty_out(vty, " vrrp %" PRIu8 " priority %" PRIu8 "\n",
2265 vr->vrid, vr->priority);
2266
2267 struct ipaddr *ip;
2268
2269 for (ALL_LIST_ELEMENTS_RO(vr->v4->addrs, ipln, ip)) {
2270 char ipbuf[INET6_ADDRSTRLEN];
2271
2272 ipaddr2str(ip, ipbuf, sizeof(ipbuf));
2273 vty_out(vty, " vrrp %" PRIu8 " ip %s\n", vr->vrid,
2274 ipbuf);
2275 ++writes;
2276 }
2277
2278 for (ALL_LIST_ELEMENTS_RO(vr->v6->addrs, ipln, ip)) {
2279 char ipbuf[INET6_ADDRSTRLEN];
2280
2281 ipaddr2str(ip, ipbuf, sizeof(ipbuf));
2282 vty_out(vty, " vrrp %" PRIu8 " ipv6 %s\n", vr->vrid,
2283 ipbuf);
2284 ++writes;
2285 }
2286 vty_endframe(vty, "!\n");
2287 }
2288
2289 list_delete(&vrs);
2290
2291 return writes;
2292 }
2293
2294 int vrrp_config_write_global(struct vty *vty)
2295 {
2296 unsigned int writes = 0;
2297
2298 if (vrrp_autoconfig_is_on && ++writes)
2299 vty_out(vty, "vrrp autoconfigure%s\n",
2300 vrrp_autoconfig_version == 2 ? " version 2" : "");
2301
2302 if (vd.priority != VRRP_DEFAULT_PRIORITY && ++writes)
2303 vty_out(vty, "vrrp default priority %" PRIu8 "\n", vd.priority);
2304
2305 if (vd.advertisement_interval != VRRP_DEFAULT_ADVINT && ++writes)
2306 vty_out(vty,
2307 "vrrp default advertisement-interval %" PRIu16 "\n",
2308 vd.advertisement_interval * CS2MS);
2309
2310 if (vd.preempt_mode != VRRP_DEFAULT_PREEMPT && ++writes)
2311 vty_out(vty, "%svrrp default preempt\n",
2312 !vd.preempt_mode ? "no " : "");
2313
2314 if (vd.accept_mode != VRRP_DEFAULT_ACCEPT && ++writes)
2315 vty_out(vty, "%svrrp default accept\n",
2316 !vd.accept_mode ? "no " : "");
2317
2318 if (vd.shutdown != VRRP_DEFAULT_SHUTDOWN && ++writes)
2319 vty_out(vty, "%svrrp default shutdown\n",
2320 !vd.shutdown ? "no " : "");
2321
2322 return writes;
2323 }
2324
2325 static unsigned int vrrp_hash_key(const void *arg)
2326 {
2327 const struct vrrp_vrouter *vr = arg;
2328 char key[IFNAMSIZ + 64];
2329
2330 snprintf(key, sizeof(key), "%s@%" PRIu8, vr->ifp->name, vr->vrid);
2331
2332 return string_hash_make(key);
2333 }
2334
2335 static bool vrrp_hash_cmp(const void *arg1, const void *arg2)
2336 {
2337 const struct vrrp_vrouter *vr1 = arg1;
2338 const struct vrrp_vrouter *vr2 = arg2;
2339
2340 if (vr1->ifp != vr2->ifp)
2341 return 0;
2342 if (vr1->vrid != vr2->vrid)
2343 return 0;
2344
2345 return 1;
2346 }
2347
2348 void vrrp_init(void)
2349 {
2350 /* Set default defaults */
2351 vd.priority = VRRP_DEFAULT_PRIORITY;
2352 vd.advertisement_interval = VRRP_DEFAULT_ADVINT;
2353 vd.preempt_mode = VRRP_DEFAULT_PREEMPT;
2354 vd.accept_mode = VRRP_DEFAULT_ACCEPT;
2355 vd.shutdown = VRRP_DEFAULT_SHUTDOWN;
2356
2357 vrrp_autoconfig_version = 3;
2358 vrrp_vrouters_hash = hash_create(&vrrp_hash_key, vrrp_hash_cmp,
2359 "VRRP virtual router hash");
2360 vrf_init(NULL, NULL, NULL, NULL, NULL);
2361 }
2362
2363 void vrrp_fini(void)
2364 {
2365 /* Destroy all instances */
2366 struct list *vrs = hash_to_list(vrrp_vrouters_hash);
2367
2368 struct listnode *ln;
2369 struct vrrp_vrouter *vr;
2370
2371 for (ALL_LIST_ELEMENTS_RO(vrs, ln, vr))
2372 vrrp_vrouter_destroy(vr);
2373
2374 list_delete(&vrs);
2375
2376 hash_clean(vrrp_vrouters_hash, NULL);
2377 hash_free(vrrp_vrouters_hash);
2378 }