2 * Address linked list routine.
3 * Copyright (C) 1997, 98 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with this program; see the file COPYING; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
34 #include "zebra/debug.h"
35 #include "zebra/zserv.h"
36 #include "zebra/redistribute.h"
37 #include "zebra/interface.h"
38 #include "zebra/connected.h"
39 #include "zebra/rtadv.h"
40 #include "zebra/zebra_mpls.h"
41 #include "zebra/debug.h"
42 #include "zebra/zebra_errors.h"
43 #include "zebra/zebra_router.h"
45 /* communicate the withdrawal of a connected address */
46 static void connected_withdraw(struct connected
*ifc
)
51 /* Update interface address information to protocol daemon. */
52 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
)) {
53 zebra_interface_address_delete_update(ifc
->ifp
, ifc
);
55 if (ifc
->address
->family
== AF_INET
)
56 if_subnet_delete(ifc
->ifp
, ifc
);
58 connected_down(ifc
->ifp
, ifc
);
60 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
63 /* The address is not in the kernel anymore, so clear the flag */
64 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
66 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)) {
67 listnode_delete(ifc
->ifp
->connected
, ifc
);
72 static void connected_announce(struct interface
*ifp
, struct connected
*ifc
)
77 if (!if_is_loopback(ifp
) && ifc
->address
->family
== AF_INET
&&
78 !IS_ZEBRA_IF_VRF(ifp
)) {
79 if (ifc
->address
->prefixlen
== 32)
80 SET_FLAG(ifc
->flags
, ZEBRA_IFA_UNNUMBERED
);
82 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_UNNUMBERED
);
85 listnode_add(ifp
->connected
, ifc
);
87 /* Update interface address information to protocol daemon. */
88 if (ifc
->address
->family
== AF_INET
)
89 if_subnet_add(ifp
, ifc
);
91 zebra_interface_address_add_update(ifp
, ifc
);
93 if (if_is_operative(ifp
)) {
94 connected_up(ifp
, ifc
);
98 /* If same interface address is already exist... */
99 struct connected
*connected_check(struct interface
*ifp
,
100 union prefixconstptr pu
)
102 const struct prefix
*p
= pu
.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
))
113 /* same, but with peer address */
114 struct connected
*connected_check_ptp(struct interface
*ifp
,
115 union prefixconstptr pu
,
116 union prefixconstptr du
)
118 const struct prefix
*p
= pu
.p
;
119 const struct prefix
*d
= du
.p
;
120 struct connected
*ifc
;
121 struct listnode
*node
;
123 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
)) {
124 if (!prefix_same(ifc
->address
, p
))
126 if (!CONNECTED_PEER(ifc
) && !d
)
128 if (CONNECTED_PEER(ifc
) && d
129 && prefix_same(ifc
->destination
, d
))
136 /* Check if two ifc's describe the same address in the same state */
137 static int connected_same(struct connected
*ifc1
, struct connected
*ifc2
)
139 if (ifc1
->ifp
!= ifc2
->ifp
)
142 if (ifc1
->flags
!= ifc2
->flags
)
145 if (ifc1
->conf
!= ifc2
->conf
)
148 if (ifc1
->destination
)
149 if (!ifc2
->destination
)
151 if (ifc2
->destination
)
152 if (!ifc1
->destination
)
155 if (ifc1
->destination
&& ifc2
->destination
)
156 if (!prefix_same(ifc1
->destination
, ifc2
->destination
))
162 /* Handle changes to addresses and send the neccesary announcements
164 static void connected_update(struct interface
*ifp
, struct connected
*ifc
)
166 struct connected
*current
;
168 /* Check same connected route. */
169 current
= connected_check_ptp(ifp
, ifc
->address
, ifc
->destination
);
171 if (CHECK_FLAG(current
->conf
, ZEBRA_IFC_CONFIGURED
))
172 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
174 /* Avoid spurious withdraws, this might be just the kernel
176 * back an address we have already added.
178 if (connected_same(current
, ifc
)) {
180 connected_free(&ifc
);
184 /* Clear the configured flag on the old ifc, so it will be freed
186 * connected withdraw. */
187 UNSET_FLAG(current
->conf
, ZEBRA_IFC_CONFIGURED
);
189 current
); /* implicit withdraw - freebsd does this */
192 /* If the connected is new or has changed, announce it, if it is usable
194 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
195 connected_announce(ifp
, ifc
);
198 /* Called from if_up(). */
199 void connected_up(struct interface
*ifp
, struct connected
*ifc
)
202 struct prefix p
= {0};
203 struct nexthop nh
= {
204 .type
= NEXTHOP_TYPE_IFINDEX
,
205 .ifindex
= ifp
->ifindex
,
206 .vrf_id
= ifp
->vrf_id
,
208 struct zebra_vrf
*zvrf
;
212 struct listnode
*cnode
;
215 zvrf
= zebra_vrf_lookup_by_id(ifp
->vrf_id
);
218 EC_ZEBRA_VRF_NOT_FOUND
,
219 "%s: Received Up for interface but no associated zvrf: %d",
220 __func__
, ifp
->vrf_id
);
223 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
226 PREFIX_COPY(&p
, CONNECTED_PREFIX(ifc
));
228 /* Apply mask to the network. */
231 afi
= family2afi(p
.family
);
236 * In case of connected address is 0.0.0.0/0 we treat it tunnel
239 if (prefix_ipv4_any((struct prefix_ipv4
*)&p
))
244 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
245 if (IN6_IS_ADDR_UNSPECIFIED(&p
.u
.prefix6
))
250 flog_warn(EC_ZEBRA_CONNECTED_AFI_UNKNOWN
,
251 "Received unknown AFI: %s", afi2str(afi
));
256 metric
= (ifc
->metric
< (uint32_t)METRIC_MAX
) ?
257 ifc
->metric
: ifp
->metric
;
260 * Since we are hand creating the connected routes
261 * in our main routing table, *if* we are working
262 * in an offloaded environment then we need to
263 * pretend like the route is offloaded so everything
266 if (zrouter
.asic_offloaded
)
267 flags
|= ZEBRA_FLAG_OFFLOADED
;
270 * It's possible to add the same network and mask
271 * to an interface over and over. This would
272 * result in an equivalent number of connected
273 * routes. Just add one connected route in
274 * for all the addresses on an interface that
275 * resolve to the same network and mask
277 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, c
)) {
280 PREFIX_COPY(&cp
, CONNECTED_PREFIX(c
));
283 if (prefix_same(&cp
, &p
))
290 rib_add(afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0,
291 flags
, &p
, NULL
, &nh
, 0, zvrf
->table_id
, metric
, 0, 0, 0);
293 rib_add(afi
, SAFI_MULTICAST
, zvrf
->vrf
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0,
294 flags
, &p
, NULL
, &nh
, 0, zvrf
->table_id
, metric
, 0, 0, 0);
296 /* Schedule LSP forwarding entries for processing, if appropriate. */
297 if (zvrf
->vrf
->vrf_id
== VRF_DEFAULT
) {
298 if (IS_ZEBRA_DEBUG_MPLS
)
300 "%u: IF %s IP %pFX address add/up, scheduling MPLS processing",
301 zvrf
->vrf
->vrf_id
, ifp
->name
, &p
);
302 mpls_mark_lsps_for_processing(zvrf
, &p
);
306 /* Add connected IPv4 route to the interface. */
307 void connected_add_ipv4(struct interface
*ifp
, int flags
, struct in_addr
*addr
,
308 uint16_t prefixlen
, struct in_addr
*dest
,
309 const char *label
, uint32_t metric
)
311 struct prefix_ipv4
*p
;
312 struct connected
*ifc
;
314 if (ipv4_martian(addr
))
317 /* Make connected structure. */
318 ifc
= connected_new();
321 ifc
->metric
= metric
;
322 /* If we get a notification from the kernel,
323 * we can safely assume the address is known to the kernel */
324 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
326 /* Allocate new connected address. */
327 p
= prefix_ipv4_new();
330 p
->prefixlen
= CHECK_FLAG(flags
, ZEBRA_IFA_PEER
) ? IPV4_MAX_PREFIXLEN
332 ifc
->address
= (struct prefix
*)p
;
334 /* If there is a peer address. */
335 if (CONNECTED_PEER(ifc
)) {
336 /* validate the destination address */
338 p
= prefix_ipv4_new();
341 p
->prefixlen
= prefixlen
;
342 ifc
->destination
= (struct prefix
*)p
;
344 if (IPV4_ADDR_SAME(addr
, dest
))
346 EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER
,
347 "interface %s has same local and peer address %pI4, routing protocols may malfunction",
351 "%s called for interface %s with peer flag set, but no peer address supplied",
352 __func__
, ifp
->name
);
353 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
357 /* no destination address was supplied */
358 if (!dest
&& (prefixlen
== IPV4_MAX_PREFIXLEN
)
359 && if_is_pointopoint(ifp
))
361 "PtP interface %s with addr %pI4/%d needs a peer address",
362 ifp
->name
, addr
, prefixlen
);
364 /* Label of this address. */
366 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
368 /* For all that I know an IPv4 address is always ready when we receive
369 * the notification. So it should be safe to set the REAL flag here. */
370 SET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
372 connected_update(ifp
, ifc
);
375 void connected_down(struct interface
*ifp
, struct connected
*ifc
)
379 struct nexthop nh
= {
380 .type
= NEXTHOP_TYPE_IFINDEX
,
381 .ifindex
= ifp
->ifindex
,
382 .vrf_id
= ifp
->vrf_id
,
384 struct zebra_vrf
*zvrf
;
386 struct listnode
*cnode
;
389 zvrf
= zebra_vrf_lookup_by_id(ifp
->vrf_id
);
392 EC_ZEBRA_VRF_NOT_FOUND
,
393 "%s: Received Up for interface but no associated zvrf: %d",
394 __func__
, ifp
->vrf_id
);
398 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
401 PREFIX_COPY(&p
, CONNECTED_PREFIX(ifc
));
403 /* Apply mask to the network. */
406 afi
= family2afi(p
.family
);
411 * In case of connected address is 0.0.0.0/0 we treat it tunnel
414 if (prefix_ipv4_any((struct prefix_ipv4
*)&p
))
418 if (IN6_IS_ADDR_UNSPECIFIED(&p
.u
.prefix6
))
422 zlog_warn("Unknown AFI: %s", afi2str(afi
));
427 * It's possible to have X number of addresses
428 * on a interface that all resolve to the same
429 * network and mask. Find them and just
430 * allow the deletion when are removing the last
433 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, cnode
, c
)) {
436 PREFIX_COPY(&cp
, CONNECTED_PREFIX(c
));
439 if (prefix_same(&p
, &cp
))
447 * Same logic as for connected_up(): push the changes into the
450 rib_delete(afi
, SAFI_UNICAST
, zvrf
->vrf
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0,
451 0, &p
, NULL
, &nh
, 0, zvrf
->table_id
, 0, 0, false);
453 rib_delete(afi
, SAFI_MULTICAST
, zvrf
->vrf
->vrf_id
, ZEBRA_ROUTE_CONNECT
,
454 0, 0, &p
, NULL
, &nh
, 0, zvrf
->table_id
, 0, 0, false);
456 /* Schedule LSP forwarding entries for processing, if appropriate. */
457 if (zvrf
->vrf
->vrf_id
== VRF_DEFAULT
) {
458 if (IS_ZEBRA_DEBUG_MPLS
)
460 "%u: IF %s IP %pFX address down, scheduling MPLS processing",
461 zvrf
->vrf
->vrf_id
, ifp
->name
, &p
);
462 mpls_mark_lsps_for_processing(zvrf
, &p
);
466 static void connected_delete_helper(struct connected
*ifc
, struct prefix
*p
)
468 struct interface
*ifp
;
474 connected_withdraw(ifc
);
476 /* Schedule LSP forwarding entries for processing, if appropriate. */
477 if (ifp
->vrf_id
== VRF_DEFAULT
) {
478 if (IS_ZEBRA_DEBUG_MPLS
)
480 "%u: IF %s IP %pFX address delete, scheduling MPLS processing",
481 ifp
->vrf_id
, ifp
->name
, p
);
482 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
), p
);
486 /* Delete connected IPv4 route to the interface. */
487 void connected_delete_ipv4(struct interface
*ifp
, int flags
,
488 struct in_addr
*addr
, uint16_t prefixlen
,
489 struct in_addr
*dest
)
492 struct connected
*ifc
;
494 memset(&p
, 0, sizeof(struct prefix
));
497 p
.prefixlen
= CHECK_FLAG(flags
, ZEBRA_IFA_PEER
) ? IPV4_MAX_PREFIXLEN
501 memset(&d
, 0, sizeof(struct prefix
));
504 d
.prefixlen
= prefixlen
;
505 ifc
= connected_check_ptp(ifp
, &p
, &d
);
507 ifc
= connected_check_ptp(ifp
, &p
, NULL
);
509 connected_delete_helper(ifc
, &p
);
512 /* Add connected IPv6 route to the interface. */
513 void connected_add_ipv6(struct interface
*ifp
, int flags
, struct in6_addr
*addr
,
514 struct in6_addr
*dest
, uint16_t prefixlen
,
515 const char *label
, uint32_t metric
)
517 struct prefix_ipv6
*p
;
518 struct connected
*ifc
;
520 if (ipv6_martian(addr
))
523 /* Make connected structure. */
524 ifc
= connected_new();
527 ifc
->metric
= metric
;
528 /* If we get a notification from the kernel,
529 * we can safely assume the address is known to the kernel */
530 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
532 /* Allocate new connected address. */
533 p
= prefix_ipv6_new();
534 p
->family
= AF_INET6
;
535 IPV6_ADDR_COPY(&p
->prefix
, addr
);
536 p
->prefixlen
= prefixlen
;
537 ifc
->address
= (struct prefix
*)p
;
539 /* Add global ipv6 address to the RA prefix list */
540 if (!IN6_IS_ADDR_LINKLOCAL(&p
->prefix
))
541 rtadv_add_prefix(ifp
->info
, p
);
544 p
= prefix_ipv6_new();
545 p
->family
= AF_INET6
;
546 IPV6_ADDR_COPY(&p
->prefix
, dest
);
547 p
->prefixlen
= prefixlen
;
548 ifc
->destination
= (struct prefix
*)p
;
550 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
)) {
552 "%s called for interface %s with peer flag set, but no peer address supplied",
553 __func__
, ifp
->name
);
554 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
558 /* Label of this address. */
560 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
562 /* On Linux, we only get here when DAD is complete, therefore we can set
565 * On BSD, there currently doesn't seem to be a way to check for
567 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
569 * might still be running.
571 SET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
572 connected_update(ifp
, ifc
);
575 void connected_delete_ipv6(struct interface
*ifp
, struct in6_addr
*address
,
576 struct in6_addr
*dest
, uint16_t prefixlen
)
579 struct connected
*ifc
;
581 memset(&p
, 0, sizeof(struct prefix
));
583 memcpy(&p
.u
.prefix6
, address
, sizeof(struct in6_addr
));
584 p
.prefixlen
= prefixlen
;
586 /* Delete global ipv6 address from RA prefix list */
587 if (!IN6_IS_ADDR_LINKLOCAL(&p
.u
.prefix6
))
588 rtadv_delete_prefix(ifp
->info
, &p
);
591 memset(&d
, 0, sizeof(struct prefix
));
593 IPV6_ADDR_COPY(&d
.u
.prefix6
, dest
);
594 d
.prefixlen
= prefixlen
;
595 ifc
= connected_check_ptp(ifp
, &p
, &d
);
597 ifc
= connected_check_ptp(ifp
, &p
, NULL
);
599 connected_delete_helper(ifc
, &p
);
602 int connected_is_unnumbered(struct interface
*ifp
)
604 struct connected
*connected
;
605 struct listnode
*node
;
607 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
608 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
609 && connected
->address
->family
== AF_INET
)
610 return CHECK_FLAG(connected
->flags
,
611 ZEBRA_IFA_UNNUMBERED
);