]> git.proxmox.com Git - mirror_frr.git/blob - zebra/connected.c
Merge pull request #13235 from Orange-OpenSource/link-state
[mirror_frr.git] / zebra / connected.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Address linked list routine.
4 * Copyright (C) 1997, 98 Kunihiro Ishiguro
5 */
6
7 #include <zebra.h>
8
9 #include "prefix.h"
10 #include "linklist.h"
11 #include "if.h"
12 #include "table.h"
13 #include "rib.h"
14 #include "table.h"
15 #include "log.h"
16 #include "memory.h"
17
18 #include "vty.h"
19 #include "zebra/debug.h"
20 #include "zebra/zserv.h"
21 #include "zebra/redistribute.h"
22 #include "zebra/interface.h"
23 #include "zebra/connected.h"
24 #include "zebra/rtadv.h"
25 #include "zebra/zebra_mpls.h"
26 #include "zebra/zebra_errors.h"
27 #include "zebra/zebra_router.h"
28
29 /* communicate the withdrawal of a connected address */
30 static void connected_withdraw(struct connected *ifc)
31 {
32 if (!ifc)
33 return;
34
35 /* Update interface address information to protocol daemon. */
36 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL)) {
37 zebra_interface_address_delete_update(ifc->ifp, ifc);
38
39 if (ifc->address->family == AF_INET)
40 if_subnet_delete(ifc->ifp, ifc);
41
42 connected_down(ifc->ifp, ifc);
43
44 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
45 }
46
47 /* The address is not in the kernel anymore, so clear the flag */
48 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
49
50 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
51 listnode_delete(ifc->ifp->connected, ifc);
52 connected_free(&ifc);
53 }
54 }
55
56 static void connected_announce(struct interface *ifp, struct connected *ifc)
57 {
58 if (!ifc)
59 return;
60
61 if (!if_is_loopback(ifp) && ifc->address->family == AF_INET) {
62 if (ifc->address->prefixlen == IPV4_MAX_BITLEN)
63 SET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
64 else
65 UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
66 }
67
68 listnode_add(ifp->connected, ifc);
69
70 /* Update interface address information to protocol daemon. */
71 if (ifc->address->family == AF_INET)
72 if_subnet_add(ifp, ifc);
73
74 zebra_interface_address_add_update(ifp, ifc);
75
76 if (if_is_operative(ifp)) {
77 connected_up(ifp, ifc);
78 }
79 }
80
81 /* If same interface address is already exist... */
82 struct connected *connected_check(struct interface *ifp,
83 union prefixconstptr pu)
84 {
85 const struct prefix *p = pu.p;
86 struct connected *ifc;
87 struct listnode *node;
88
89 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc))
90 if (prefix_same(ifc->address, p))
91 return ifc;
92
93 return NULL;
94 }
95
96 /* same, but with peer address */
97 struct connected *connected_check_ptp(struct interface *ifp,
98 union prefixconstptr pu,
99 union prefixconstptr du)
100 {
101 const struct prefix *p = pu.p;
102 const struct prefix *d = du.p;
103 struct connected *ifc;
104 struct listnode *node;
105
106 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
107 if (!prefix_same(ifc->address, p))
108 continue;
109 if (!CONNECTED_PEER(ifc) && !d)
110 return ifc;
111 if (CONNECTED_PEER(ifc) && d
112 && prefix_same(ifc->destination, d))
113 return ifc;
114 }
115
116 return NULL;
117 }
118
119 /* Check if two ifc's describe the same address in the same state */
120 static int connected_same(struct connected *ifc1, struct connected *ifc2)
121 {
122 if (ifc1->ifp != ifc2->ifp)
123 return 0;
124
125 if (ifc1->flags != ifc2->flags)
126 return 0;
127
128 if (ifc1->conf != ifc2->conf)
129 return 0;
130
131 if (ifc1->destination)
132 if (!ifc2->destination)
133 return 0;
134 if (ifc2->destination)
135 if (!ifc1->destination)
136 return 0;
137
138 if (ifc1->destination && ifc2->destination)
139 if (!prefix_same(ifc1->destination, ifc2->destination))
140 return 0;
141
142 return 1;
143 }
144
145 /* Handle changes to addresses and send the neccesary announcements
146 * to clients. */
147 static void connected_update(struct interface *ifp, struct connected *ifc)
148 {
149 struct connected *current;
150
151 /* Check same connected route. */
152 current = connected_check_ptp(ifp, ifc->address, ifc->destination);
153 if (current) {
154 if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
155 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
156
157 /* Avoid spurious withdraws, this might be just the kernel
158 * 'reflecting'
159 * back an address we have already added.
160 */
161 if (connected_same(current, ifc)) {
162 /* nothing to do */
163 connected_free(&ifc);
164 return;
165 }
166
167 /* Clear the configured flag on the old ifc, so it will be freed
168 * by
169 * connected withdraw. */
170 UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
171 connected_withdraw(
172 current); /* implicit withdraw - freebsd does this */
173 }
174
175 /* If the connected is new or has changed, announce it, if it is usable
176 */
177 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
178 connected_announce(ifp, ifc);
179 }
180
181 /* Called from if_up(). */
182 void connected_up(struct interface *ifp, struct connected *ifc)
183 {
184 afi_t afi;
185 struct prefix p;
186 struct nexthop nh = {
187 .type = NEXTHOP_TYPE_IFINDEX,
188 .ifindex = ifp->ifindex,
189 .vrf_id = ifp->vrf->vrf_id,
190 };
191 struct zebra_vrf *zvrf;
192 uint32_t metric;
193 uint32_t flags = 0;
194 uint32_t count = 0;
195 struct listnode *cnode;
196 struct connected *c;
197
198 zvrf = ifp->vrf->info;
199 if (!zvrf) {
200 flog_err(
201 EC_ZEBRA_VRF_NOT_FOUND,
202 "%s: Received Up for interface but no associated zvrf: %s(%d)",
203 __func__, ifp->vrf->name, ifp->vrf->vrf_id);
204 return;
205 }
206 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
207 return;
208
209 /* Ensure 'down' flag is cleared */
210 UNSET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
211
212 prefix_copy(&p, CONNECTED_PREFIX(ifc));
213
214 /* Apply mask to the network. */
215 apply_mask(&p);
216
217 afi = family2afi(p.family);
218
219 switch (afi) {
220 case AFI_IP:
221 /*
222 * In case of connected address is 0.0.0.0/0 we treat it tunnel
223 * address.
224 */
225 if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
226 return;
227 break;
228 case AFI_IP6:
229 #ifndef GNU_LINUX
230 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
231 if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
232 return;
233 #endif
234 break;
235 case AFI_UNSPEC:
236 case AFI_L2VPN:
237 case AFI_MAX:
238 flog_warn(EC_ZEBRA_CONNECTED_AFI_UNKNOWN,
239 "Received unknown AFI: %s", afi2str(afi));
240 return;
241 break;
242 }
243
244 metric = (ifc->metric < (uint32_t)METRIC_MAX) ?
245 ifc->metric : ifp->metric;
246
247 /*
248 * Since we are hand creating the connected routes
249 * in our main routing table, *if* we are working
250 * in an offloaded environment then we need to
251 * pretend like the route is offloaded so everything
252 * else will work
253 */
254 if (zrouter.asic_offloaded)
255 flags |= ZEBRA_FLAG_OFFLOADED;
256
257 /*
258 * It's possible to add the same network and mask
259 * to an interface over and over. This would
260 * result in an equivalent number of connected
261 * routes. Just add one connected route in
262 * for all the addresses on an interface that
263 * resolve to the same network and mask
264 */
265 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
266 struct prefix cp;
267
268 prefix_copy(&cp, CONNECTED_PREFIX(c));
269 apply_mask(&cp);
270
271 if (prefix_same(&cp, &p) &&
272 !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
273 count++;
274
275 if (count >= 2)
276 return;
277 }
278
279 rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
280 flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0,
281 false);
282
283 rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
284 flags, &p, NULL, &nh, 0, zvrf->table_id, metric, 0, 0, 0,
285 false);
286
287 /* Schedule LSP forwarding entries for processing, if appropriate. */
288 if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
289 if (IS_ZEBRA_DEBUG_MPLS)
290 zlog_debug(
291 "%u: IF %s IP %pFX address add/up, scheduling MPLS processing",
292 zvrf->vrf->vrf_id, ifp->name, &p);
293 mpls_mark_lsps_for_processing(zvrf, &p);
294 }
295 }
296
297 /* Add connected IPv4 route to the interface. */
298 void connected_add_ipv4(struct interface *ifp, int flags,
299 const struct in_addr *addr, uint16_t prefixlen,
300 const struct in_addr *dest, const char *label,
301 uint32_t metric)
302 {
303 struct prefix_ipv4 *p;
304 struct connected *ifc;
305
306 if (ipv4_martian(addr))
307 return;
308
309 /* Make connected structure. */
310 ifc = connected_new();
311 ifc->ifp = ifp;
312 ifc->flags = flags;
313 ifc->metric = metric;
314 /* If we get a notification from the kernel,
315 * we can safely assume the address is known to the kernel */
316 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
317 if (!if_is_operative(ifp))
318 SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
319
320 /* Allocate new connected address. */
321 p = prefix_ipv4_new();
322 p->family = AF_INET;
323 p->prefix = *addr;
324 p->prefixlen =
325 CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_BITLEN : prefixlen;
326 ifc->address = (struct prefix *)p;
327
328 /* If there is a peer address. */
329 if (CONNECTED_PEER(ifc)) {
330 /* validate the destination address */
331 if (dest) {
332 p = prefix_ipv4_new();
333 p->family = AF_INET;
334 p->prefix = *dest;
335 p->prefixlen = prefixlen;
336 ifc->destination = (struct prefix *)p;
337
338 if (IPV4_ADDR_SAME(addr, dest))
339 flog_warn(
340 EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
341 "interface %s has same local and peer address %pI4, routing protocols may malfunction",
342 ifp->name, addr);
343 } else {
344 zlog_debug(
345 "%s called for interface %s with peer flag set, but no peer address supplied",
346 __func__, ifp->name);
347 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
348 }
349 }
350
351 /* no destination address was supplied */
352 if (!dest && (prefixlen == IPV4_MAX_BITLEN) && if_is_pointopoint(ifp))
353 zlog_debug(
354 "PtP interface %s with addr %pI4/%d needs a peer address",
355 ifp->name, addr, prefixlen);
356
357 /* Label of this address. */
358 if (label)
359 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
360
361 /* For all that I know an IPv4 address is always ready when we receive
362 * the notification. So it should be safe to set the REAL flag here. */
363 SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
364
365 connected_update(ifp, ifc);
366 }
367
368 void connected_down(struct interface *ifp, struct connected *ifc)
369 {
370 afi_t afi;
371 struct prefix p;
372 struct nexthop nh = {
373 .type = NEXTHOP_TYPE_IFINDEX,
374 .ifindex = ifp->ifindex,
375 .vrf_id = ifp->vrf->vrf_id,
376 };
377 struct zebra_vrf *zvrf;
378 uint32_t count = 0;
379 struct listnode *cnode;
380 struct connected *c;
381
382 zvrf = ifp->vrf->info;
383 if (!zvrf) {
384 flog_err(
385 EC_ZEBRA_VRF_NOT_FOUND,
386 "%s: Received Down for interface but no associated zvrf: %s(%d)",
387 __func__, ifp->vrf->name, ifp->vrf->vrf_id);
388 return;
389 }
390
391 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
392 return;
393
394 /* Skip if we've already done this; this can happen if we have a
395 * config change that takes an interface down, then we receive kernel
396 * notifications about the downed interface and its addresses.
397 */
398 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_DOWN)) {
399 if (IS_ZEBRA_DEBUG_RIB)
400 zlog_debug("%s: ifc %p, %pFX already DOWN",
401 __func__, ifc, ifc->address);
402 return;
403 }
404
405 prefix_copy(&p, CONNECTED_PREFIX(ifc));
406
407 /* Apply mask to the network. */
408 apply_mask(&p);
409
410 afi = family2afi(p.family);
411
412 switch (afi) {
413 case AFI_IP:
414 /*
415 * In case of connected address is 0.0.0.0/0 we treat it tunnel
416 * address.
417 */
418 if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
419 return;
420 break;
421 case AFI_IP6:
422 if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
423 return;
424 break;
425 case AFI_UNSPEC:
426 case AFI_L2VPN:
427 case AFI_MAX:
428 zlog_warn("Unknown AFI: %s", afi2str(afi));
429 break;
430 }
431
432 /* Mark the address as 'down' */
433 SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
434
435 /*
436 * It's possible to have X number of addresses
437 * on a interface that all resolve to the same
438 * network and mask. Find them and just
439 * allow the deletion when are removing the last
440 * one.
441 */
442 for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
443 struct prefix cp;
444
445 prefix_copy(&cp, CONNECTED_PREFIX(c));
446 apply_mask(&cp);
447
448 if (prefix_same(&p, &cp) &&
449 !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN))
450 count++;
451
452 if (count >= 1)
453 return;
454 }
455
456 /*
457 * Same logic as for connected_up(): push the changes into the
458 * head.
459 */
460 rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
461 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false);
462
463 rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
464 0, 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false);
465
466 /* Schedule LSP forwarding entries for processing, if appropriate. */
467 if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
468 if (IS_ZEBRA_DEBUG_MPLS)
469 zlog_debug(
470 "%u: IF %s IP %pFX address down, scheduling MPLS processing",
471 zvrf->vrf->vrf_id, ifp->name, &p);
472 mpls_mark_lsps_for_processing(zvrf, &p);
473 }
474 }
475
476 static void connected_delete_helper(struct connected *ifc, struct prefix *p)
477 {
478 struct interface *ifp;
479
480 if (!ifc)
481 return;
482 ifp = ifc->ifp;
483
484 connected_withdraw(ifc);
485
486 /* Schedule LSP forwarding entries for processing, if appropriate. */
487 if (ifp->vrf->vrf_id == VRF_DEFAULT) {
488 if (IS_ZEBRA_DEBUG_MPLS)
489 zlog_debug(
490 "%u: IF %s IP %pFX address delete, scheduling MPLS processing",
491 ifp->vrf->vrf_id, ifp->name, p);
492 mpls_mark_lsps_for_processing(ifp->vrf->info, p);
493 }
494 }
495
496 /* Delete connected IPv4 route to the interface. */
497 void connected_delete_ipv4(struct interface *ifp, int flags,
498 const struct in_addr *addr, uint16_t prefixlen,
499 const struct in_addr *dest)
500 {
501 struct prefix p, d;
502 struct connected *ifc;
503
504 memset(&p, 0, sizeof(p));
505 p.family = AF_INET;
506 p.u.prefix4 = *addr;
507 p.prefixlen =
508 CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_BITLEN : prefixlen;
509
510 if (dest) {
511 memset(&d, 0, sizeof(d));
512 d.family = AF_INET;
513 d.u.prefix4 = *dest;
514 d.prefixlen = prefixlen;
515 ifc = connected_check_ptp(ifp, &p, &d);
516 } else
517 ifc = connected_check_ptp(ifp, &p, NULL);
518
519 connected_delete_helper(ifc, &p);
520 }
521
522 /* Add connected IPv6 route to the interface. */
523 void connected_add_ipv6(struct interface *ifp, int flags,
524 const struct in6_addr *addr,
525 const struct in6_addr *dest, uint16_t prefixlen,
526 const char *label, uint32_t metric)
527 {
528 struct prefix_ipv6 *p;
529 struct connected *ifc;
530
531 if (ipv6_martian(addr))
532 return;
533
534 /* Make connected structure. */
535 ifc = connected_new();
536 ifc->ifp = ifp;
537 ifc->flags = flags;
538 ifc->metric = metric;
539 /* If we get a notification from the kernel,
540 * we can safely assume the address is known to the kernel */
541 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
542 if (!if_is_operative(ifp))
543 SET_FLAG(ifc->conf, ZEBRA_IFC_DOWN);
544
545 /* Allocate new connected address. */
546 p = prefix_ipv6_new();
547 p->family = AF_INET6;
548 IPV6_ADDR_COPY(&p->prefix, addr);
549 p->prefixlen = prefixlen;
550 ifc->address = (struct prefix *)p;
551
552 /* Add global ipv6 address to the RA prefix list */
553 if (!IN6_IS_ADDR_LINKLOCAL(&p->prefix))
554 rtadv_add_prefix(ifp->info, p);
555
556 if (dest) {
557 p = prefix_ipv6_new();
558 p->family = AF_INET6;
559 IPV6_ADDR_COPY(&p->prefix, dest);
560 p->prefixlen = prefixlen;
561 ifc->destination = (struct prefix *)p;
562 } else {
563 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
564 zlog_debug(
565 "%s called for interface %s with peer flag set, but no peer address supplied",
566 __func__, ifp->name);
567 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
568 }
569 }
570
571 /* Label of this address. */
572 if (label)
573 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
574
575 /* On Linux, we only get here when DAD is complete, therefore we can set
576 * ZEBRA_IFC_REAL.
577 *
578 * On BSD, there currently doesn't seem to be a way to check for
579 * completion of
580 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
581 * although DAD
582 * might still be running.
583 */
584 SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
585 connected_update(ifp, ifc);
586 }
587
588 void connected_delete_ipv6(struct interface *ifp,
589 const struct in6_addr *address,
590 const struct in6_addr *dest, uint16_t prefixlen)
591 {
592 struct prefix p, d;
593 struct connected *ifc;
594
595 memset(&p, 0, sizeof(p));
596 p.family = AF_INET6;
597 memcpy(&p.u.prefix6, address, sizeof(struct in6_addr));
598 p.prefixlen = prefixlen;
599
600 /* Delete global ipv6 address from RA prefix list */
601 if (!IN6_IS_ADDR_LINKLOCAL(&p.u.prefix6))
602 rtadv_delete_prefix(ifp->info, &p);
603
604 if (dest) {
605 memset(&d, 0, sizeof(d));
606 d.family = AF_INET6;
607 IPV6_ADDR_COPY(&d.u.prefix6, dest);
608 d.prefixlen = prefixlen;
609 ifc = connected_check_ptp(ifp, &p, &d);
610 } else
611 ifc = connected_check_ptp(ifp, &p, NULL);
612
613 connected_delete_helper(ifc, &p);
614 }
615
616 int connected_is_unnumbered(struct interface *ifp)
617 {
618 struct connected *connected;
619 struct listnode *node;
620
621 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
622 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
623 && connected->address->family == AF_INET)
624 return CHECK_FLAG(connected->flags,
625 ZEBRA_IFA_UNNUMBERED);
626 }
627 return 0;
628 }