1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Address linked list routine.
4 * Copyright (C) 1997, 98 Kunihiro Ishiguro
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"
29 /* communicate the withdrawal of a connected address */
30 static void connected_withdraw(struct connected
*ifc
)
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
);
39 if (ifc
->address
->family
== AF_INET
)
40 if_subnet_delete(ifc
->ifp
, ifc
);
42 connected_down(ifc
->ifp
, ifc
);
44 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
47 /* The address is not in the kernel anymore, so clear the flag */
48 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
50 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)) {
51 listnode_delete(ifc
->ifp
->connected
, ifc
);
56 static void connected_announce(struct interface
*ifp
, struct connected
*ifc
)
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
);
65 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_UNNUMBERED
);
68 listnode_add(ifp
->connected
, ifc
);
70 /* Update interface address information to protocol daemon. */
71 if (ifc
->address
->family
== AF_INET
)
72 if_subnet_add(ifp
, ifc
);
74 zebra_interface_address_add_update(ifp
, ifc
);
76 if (if_is_operative(ifp
)) {
77 connected_up(ifp
, ifc
);
81 /* If same interface address is already exist... */
82 struct connected
*connected_check(struct interface
*ifp
,
83 union prefixconstptr pu
)
85 const struct prefix
*p
= pu
.p
;
86 struct connected
*ifc
;
87 struct listnode
*node
;
89 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
))
90 if (prefix_same(ifc
->address
, p
))
96 /* same, but with peer address */
97 struct connected
*connected_check_ptp(struct interface
*ifp
,
98 union prefixconstptr pu
,
99 union prefixconstptr du
)
101 const struct prefix
*p
= pu
.p
;
102 const struct prefix
*d
= du
.p
;
103 struct connected
*ifc
;
104 struct listnode
*node
;
106 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
107 if (!prefix_same(ifc
->address
, p
))
109 if (!CONNECTED_PEER(ifc
) && !d
)
111 if (CONNECTED_PEER(ifc
) && d
112 && prefix_same(ifc
->destination
, d
))
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
)
122 if (ifc1
->ifp
!= ifc2
->ifp
)
125 if (ifc1
->flags
!= ifc2
->flags
)
128 if (ifc1
->conf
!= ifc2
->conf
)
131 if (ifc1
->destination
)
132 if (!ifc2
->destination
)
134 if (ifc2
->destination
)
135 if (!ifc1
->destination
)
138 if (ifc1
->destination
&& ifc2
->destination
)
139 if (!prefix_same(ifc1
->destination
, ifc2
->destination
))
145 /* Handle changes to addresses and send the neccesary announcements
147 static void connected_update(struct interface
*ifp
, struct connected
*ifc
)
149 struct connected
*current
;
151 /* Check same connected route. */
152 current
= connected_check_ptp(ifp
, ifc
->address
, ifc
->destination
);
154 if (CHECK_FLAG(current
->conf
, ZEBRA_IFC_CONFIGURED
))
155 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
157 /* Avoid spurious withdraws, this might be just the kernel
159 * back an address we have already added.
161 if (connected_same(current
, ifc
)) {
163 connected_free(&ifc
);
167 /* Clear the configured flag on the old ifc, so it will be freed
169 * connected withdraw. */
170 UNSET_FLAG(current
->conf
, ZEBRA_IFC_CONFIGURED
);
172 current
); /* implicit withdraw - freebsd does this */
175 /* If the connected is new or has changed, announce it, if it is usable
177 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
178 connected_announce(ifp
, ifc
);
181 /* Called from if_up(). */
182 void connected_up(struct interface
*ifp
, struct connected
*ifc
)
186 struct nexthop nh
= {
187 .type
= NEXTHOP_TYPE_IFINDEX
,
188 .ifindex
= ifp
->ifindex
,
189 .vrf_id
= ifp
->vrf
->vrf_id
,
191 struct zebra_vrf
*zvrf
;
195 struct listnode
*cnode
;
198 zvrf
= ifp
->vrf
->info
;
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
);
206 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
209 /* Ensure 'down' flag is cleared */
210 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_DOWN
);
212 prefix_copy(&p
, CONNECTED_PREFIX(ifc
));
214 /* Apply mask to the network. */
217 afi
= family2afi(p
.family
);
222 * In case of connected address is 0.0.0.0/0 we treat it tunnel
225 if (prefix_ipv4_any((struct prefix_ipv4
*)&p
))
230 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
231 if (IN6_IS_ADDR_UNSPECIFIED(&p
.u
.prefix6
))
238 flog_warn(EC_ZEBRA_CONNECTED_AFI_UNKNOWN
,
239 "Received unknown AFI: %s", afi2str(afi
));
244 metric
= (ifc
->metric
< (uint32_t)METRIC_MAX
) ?
245 ifc
->metric
: ifp
->metric
;
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
254 if (zrouter
.asic_offloaded
)
255 flags
|= ZEBRA_FLAG_OFFLOADED
;
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
265 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, c
)) {
268 prefix_copy(&cp
, CONNECTED_PREFIX(c
));
271 if (prefix_same(&cp
, &p
) &&
272 !CHECK_FLAG(c
->conf
, ZEBRA_IFC_DOWN
))
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,
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,
287 /* Schedule LSP forwarding entries for processing, if appropriate. */
288 if (zvrf
->vrf
->vrf_id
== VRF_DEFAULT
) {
289 if (IS_ZEBRA_DEBUG_MPLS
)
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
);
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
,
303 struct prefix_ipv4
*p
;
304 struct connected
*ifc
;
306 if (ipv4_martian(addr
))
309 /* Make connected structure. */
310 ifc
= connected_new();
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
);
320 /* Allocate new connected address. */
321 p
= prefix_ipv4_new();
325 CHECK_FLAG(flags
, ZEBRA_IFA_PEER
) ? IPV4_MAX_BITLEN
: prefixlen
;
326 ifc
->address
= (struct prefix
*)p
;
328 /* If there is a peer address. */
329 if (CONNECTED_PEER(ifc
)) {
330 /* validate the destination address */
332 p
= prefix_ipv4_new();
335 p
->prefixlen
= prefixlen
;
336 ifc
->destination
= (struct prefix
*)p
;
338 if (IPV4_ADDR_SAME(addr
, dest
))
340 EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER
,
341 "interface %s has same local and peer address %pI4, routing protocols may malfunction",
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
);
351 /* no destination address was supplied */
352 if (!dest
&& (prefixlen
== IPV4_MAX_BITLEN
) && if_is_pointopoint(ifp
))
354 "PtP interface %s with addr %pI4/%d needs a peer address",
355 ifp
->name
, addr
, prefixlen
);
357 /* Label of this address. */
359 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
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
);
365 connected_update(ifp
, ifc
);
368 void connected_down(struct interface
*ifp
, struct connected
*ifc
)
372 struct nexthop nh
= {
373 .type
= NEXTHOP_TYPE_IFINDEX
,
374 .ifindex
= ifp
->ifindex
,
375 .vrf_id
= ifp
->vrf
->vrf_id
,
377 struct zebra_vrf
*zvrf
;
379 struct listnode
*cnode
;
382 zvrf
= ifp
->vrf
->info
;
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
);
391 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
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.
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
);
405 prefix_copy(&p
, CONNECTED_PREFIX(ifc
));
407 /* Apply mask to the network. */
410 afi
= family2afi(p
.family
);
415 * In case of connected address is 0.0.0.0/0 we treat it tunnel
418 if (prefix_ipv4_any((struct prefix_ipv4
*)&p
))
422 if (IN6_IS_ADDR_UNSPECIFIED(&p
.u
.prefix6
))
428 zlog_warn("Unknown AFI: %s", afi2str(afi
));
432 /* Mark the address as 'down' */
433 SET_FLAG(ifc
->conf
, ZEBRA_IFC_DOWN
);
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
442 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, c
)) {
445 prefix_copy(&cp
, CONNECTED_PREFIX(c
));
448 if (prefix_same(&p
, &cp
) &&
449 !CHECK_FLAG(c
->conf
, ZEBRA_IFC_DOWN
))
457 * Same logic as for connected_up(): push the changes into the
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);
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);
466 /* Schedule LSP forwarding entries for processing, if appropriate. */
467 if (zvrf
->vrf
->vrf_id
== VRF_DEFAULT
) {
468 if (IS_ZEBRA_DEBUG_MPLS
)
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
);
476 static void connected_delete_helper(struct connected
*ifc
, struct prefix
*p
)
478 struct interface
*ifp
;
484 connected_withdraw(ifc
);
486 /* Schedule LSP forwarding entries for processing, if appropriate. */
487 if (ifp
->vrf
->vrf_id
== VRF_DEFAULT
) {
488 if (IS_ZEBRA_DEBUG_MPLS
)
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
);
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
)
502 struct connected
*ifc
;
504 memset(&p
, 0, sizeof(p
));
508 CHECK_FLAG(flags
, ZEBRA_IFA_PEER
) ? IPV4_MAX_BITLEN
: prefixlen
;
511 memset(&d
, 0, sizeof(d
));
514 d
.prefixlen
= prefixlen
;
515 ifc
= connected_check_ptp(ifp
, &p
, &d
);
517 ifc
= connected_check_ptp(ifp
, &p
, NULL
);
519 connected_delete_helper(ifc
, &p
);
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
)
528 struct prefix_ipv6
*p
;
529 struct connected
*ifc
;
531 if (ipv6_martian(addr
))
534 /* Make connected structure. */
535 ifc
= connected_new();
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
);
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
;
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
);
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
;
563 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
)) {
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
);
571 /* Label of this address. */
573 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
575 /* On Linux, we only get here when DAD is complete, therefore we can set
578 * On BSD, there currently doesn't seem to be a way to check for
580 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
582 * might still be running.
584 SET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
585 connected_update(ifp
, ifc
);
588 void connected_delete_ipv6(struct interface
*ifp
,
589 const struct in6_addr
*address
,
590 const struct in6_addr
*dest
, uint16_t prefixlen
)
593 struct connected
*ifc
;
595 memset(&p
, 0, sizeof(p
));
597 memcpy(&p
.u
.prefix6
, address
, sizeof(struct in6_addr
));
598 p
.prefixlen
= prefixlen
;
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
);
605 memset(&d
, 0, sizeof(d
));
607 IPV6_ADDR_COPY(&d
.u
.prefix6
, dest
);
608 d
.prefixlen
= prefixlen
;
609 ifc
= connected_check_ptp(ifp
, &p
, &d
);
611 ifc
= connected_check_ptp(ifp
, &p
, NULL
);
613 connected_delete_helper(ifc
, &p
);
616 int connected_is_unnumbered(struct interface
*ifp
)
618 struct connected
*connected
;
619 struct listnode
*node
;
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
);