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