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