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