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
32 #include "zebra_memory.h"
35 #include "zebra/debug.h"
36 #include "zebra/zserv.h"
37 #include "zebra/redistribute.h"
38 #include "zebra/interface.h"
39 #include "zebra/connected.h"
40 #include "zebra/rtadv.h"
41 #include "zebra/zebra_mpls.h"
42 #include "zebra/debug.h"
44 /* communicate the withdrawal of a connected address */
45 static void connected_withdraw(struct connected
*ifc
)
50 /* Update interface address information to protocol daemon. */
51 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
)) {
52 zebra_interface_address_delete_update(ifc
->ifp
, ifc
);
54 if (ifc
->address
->family
== AF_INET
)
55 if_subnet_delete(ifc
->ifp
, ifc
);
57 if (ifc
->address
->family
== AF_INET
)
58 connected_down_ipv4(ifc
->ifp
, ifc
);
60 connected_down_ipv6(ifc
->ifp
, ifc
);
62 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
65 /* The address is not in the kernel anymore, so clear the flag */
66 UNSET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
68 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
)) {
69 listnode_delete(ifc
->ifp
->connected
, ifc
);
74 static void connected_announce(struct interface
*ifp
, struct connected
*ifc
)
79 if (!if_is_loopback(ifp
) && ifc
->address
->family
== AF_INET
) {
80 if (ifc
->address
->prefixlen
== 32)
81 SET_FLAG(ifc
->flags
, ZEBRA_IFA_UNNUMBERED
);
83 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_UNNUMBERED
);
86 listnode_add(ifp
->connected
, ifc
);
88 /* Update interface address information to protocol daemon. */
89 if (ifc
->address
->family
== AF_INET
)
90 if_subnet_add(ifp
, ifc
);
92 zebra_interface_address_add_update(ifp
, ifc
);
94 if (if_is_operative(ifp
)) {
95 if (ifc
->address
->family
== AF_INET
)
96 connected_up_ipv4(ifp
, ifc
);
98 connected_up_ipv6(ifp
, ifc
);
102 /* If same interface address is already exist... */
103 struct connected
*connected_check(struct interface
*ifp
, struct prefix
*p
)
105 struct connected
*ifc
;
106 struct listnode
*node
;
108 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, ifc
))
109 if (prefix_same(ifc
->address
, p
))
115 /* Check if two ifc's describe the same address in the same state */
116 static int connected_same(struct connected
*ifc1
, struct connected
*ifc2
)
118 if (ifc1
->ifp
!= ifc2
->ifp
)
121 if (ifc1
->destination
)
122 if (!ifc2
->destination
)
124 if (ifc2
->destination
)
125 if (!ifc1
->destination
)
128 if (ifc1
->destination
&& ifc2
->destination
)
129 if (!prefix_same(ifc1
->destination
, ifc2
->destination
))
132 if (ifc1
->flags
!= ifc2
->flags
)
135 if (ifc1
->conf
!= ifc2
->conf
)
141 /* Handle changes to addresses and send the neccesary announcements
143 static void connected_update(struct interface
*ifp
, struct connected
*ifc
)
145 struct connected
*current
;
147 /* Check same connected route. */
148 if ((current
= connected_check(ifp
, (struct prefix
*)ifc
->address
))) {
149 if (CHECK_FLAG(current
->conf
, ZEBRA_IFC_CONFIGURED
))
150 SET_FLAG(ifc
->conf
, ZEBRA_IFC_CONFIGURED
);
152 /* Avoid spurious withdraws, this might be just the kernel
154 * back an address we have already added.
156 if (connected_same(current
, ifc
)) {
162 /* Clear the configured flag on the old ifc, so it will be freed
164 * connected withdraw. */
165 UNSET_FLAG(current
->conf
, ZEBRA_IFC_CONFIGURED
);
167 current
); /* implicit withdraw - freebsd does this */
170 /* If the connected is new or has changed, announce it, if it is usable
172 if (CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
173 connected_announce(ifp
, ifc
);
176 /* Called from if_up(). */
177 void connected_up_ipv4(struct interface
*ifp
, struct connected
*ifc
)
181 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
184 PREFIX_COPY_IPV4((struct prefix_ipv4
*)&p
, CONNECTED_PREFIX(ifc
));
186 /* Apply mask to the network. */
189 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
191 if (prefix_ipv4_any((struct prefix_ipv4
*)&p
))
194 rib_add(AFI_IP
, SAFI_UNICAST
, ifp
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0, 0,
195 &p
, NULL
, NULL
, NULL
, ifp
->ifindex
, RT_TABLE_MAIN
, ifp
->metric
,
198 rib_add(AFI_IP
, SAFI_MULTICAST
, ifp
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0, 0,
199 &p
, NULL
, NULL
, NULL
, ifp
->ifindex
, RT_TABLE_MAIN
, ifp
->metric
,
202 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
204 "%u: IF %s IPv4 address add/up, scheduling RIB processing",
205 ifp
->vrf_id
, ifp
->name
);
206 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
208 /* Schedule LSP forwarding entries for processing, if appropriate. */
209 if (ifp
->vrf_id
== VRF_DEFAULT
) {
210 if (IS_ZEBRA_DEBUG_MPLS
)
212 "%u: IF %s IPv4 address add/up, scheduling MPLS processing",
213 ifp
->vrf_id
, ifp
->name
);
214 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
));
218 /* Add connected IPv4 route to the interface. */
219 void connected_add_ipv4(struct interface
*ifp
, int flags
, struct in_addr
*addr
,
220 u_char prefixlen
, struct in_addr
*broad
,
223 struct prefix_ipv4
*p
;
224 struct connected
*ifc
;
226 if (ipv4_martian(addr
))
229 /* Make connected structure. */
230 ifc
= connected_new();
233 /* If we get a notification from the kernel,
234 * we can safely assume the address is known to the kernel */
235 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
237 /* Allocate new connected address. */
238 p
= prefix_ipv4_new();
241 p
->prefixlen
= prefixlen
;
242 ifc
->address
= (struct prefix
*)p
;
244 /* If there is broadcast or peer address. */
246 p
= prefix_ipv4_new();
249 p
->prefixlen
= prefixlen
;
250 ifc
->destination
= (struct prefix
*)p
;
252 /* validate the destination address */
253 if (CONNECTED_PEER(ifc
)) {
254 if (IPV4_ADDR_SAME(addr
, broad
))
256 "warning: interface %s has same local and peer "
257 "address %s, routing protocols may malfunction",
258 ifp
->name
, inet_ntoa(*addr
));
261 != ipv4_broadcast_addr(addr
->s_addr
, prefixlen
)) {
262 char buf
[2][INET_ADDRSTRLEN
];
263 struct in_addr bcalc
;
264 bcalc
.s_addr
= ipv4_broadcast_addr(addr
->s_addr
,
267 "warning: interface %s broadcast addr %s/%d != "
268 "calculated %s, routing protocols may malfunction",
270 inet_ntop(AF_INET
, broad
, buf
[0],
273 inet_ntop(AF_INET
, &bcalc
, buf
[1],
279 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
)) {
281 "warning: %s called for interface %s "
282 "with peer flag set, but no peer address supplied",
283 __func__
, ifp
->name
);
284 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
287 /* no broadcast or destination address was supplied */
288 if ((prefixlen
== IPV4_MAX_PREFIXLEN
) && if_is_pointopoint(ifp
))
290 "warning: PtP interface %s with addr %s/%d needs a "
292 ifp
->name
, inet_ntoa(*addr
), prefixlen
);
295 /* Label of this address. */
297 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
299 /* For all that I know an IPv4 address is always ready when we receive
300 * the notification. So it should be safe to set the REAL flag here. */
301 SET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
303 connected_update(ifp
, ifc
);
306 void connected_down_ipv4(struct interface
*ifp
, struct connected
*ifc
)
310 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
313 PREFIX_COPY_IPV4(&p
, CONNECTED_PREFIX(ifc
));
315 /* Apply mask to the network. */
318 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
320 if (prefix_ipv4_any((struct prefix_ipv4
*)&p
))
323 /* Same logic as for connected_up_ipv4(): push the changes into the
325 rib_delete(AFI_IP
, SAFI_UNICAST
, ifp
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0, 0,
326 &p
, NULL
, NULL
, ifp
->ifindex
, 0);
328 rib_delete(AFI_IP
, SAFI_MULTICAST
, ifp
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0,
329 0, &p
, NULL
, NULL
, ifp
->ifindex
, 0);
331 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
333 "%u: IF %s IPv4 address down, scheduling RIB processing",
334 ifp
->vrf_id
, ifp
->name
);
336 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
338 /* Schedule LSP forwarding entries for processing, if appropriate. */
339 if (ifp
->vrf_id
== VRF_DEFAULT
) {
340 if (IS_ZEBRA_DEBUG_MPLS
)
342 "%u: IF %s IPv4 address add/up, scheduling MPLS processing",
343 ifp
->vrf_id
, ifp
->name
);
344 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
));
348 /* Delete connected IPv4 route to the interface. */
349 void connected_delete_ipv4(struct interface
*ifp
, int flags
,
350 struct in_addr
*addr
, u_char prefixlen
,
351 struct in_addr
*broad
)
353 struct prefix_ipv4 p
;
354 struct connected
*ifc
;
356 memset(&p
, 0, sizeof(struct prefix_ipv4
));
359 p
.prefixlen
= prefixlen
;
361 ifc
= connected_check(ifp
, (struct prefix
*)&p
);
365 connected_withdraw(ifc
);
367 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
369 "%u: IF %s IPv4 address del, scheduling RIB processing",
370 ifp
->vrf_id
, ifp
->name
);
372 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
374 /* Schedule LSP forwarding entries for processing, if appropriate. */
375 if (ifp
->vrf_id
== VRF_DEFAULT
) {
376 if (IS_ZEBRA_DEBUG_MPLS
)
378 "%u: IF %s IPv4 address add/up, scheduling MPLS processing",
379 ifp
->vrf_id
, ifp
->name
);
380 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
));
384 void connected_up_ipv6(struct interface
*ifp
, struct connected
*ifc
)
388 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
391 PREFIX_COPY_IPV6((struct prefix_ipv6
*)&p
, CONNECTED_PREFIX(ifc
));
393 /* Apply mask to the network. */
397 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
398 if (IN6_IS_ADDR_UNSPECIFIED(&p
.u
.prefix6
))
402 rib_add(AFI_IP6
, SAFI_UNICAST
, ifp
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0, 0,
403 &p
, NULL
, NULL
, NULL
, ifp
->ifindex
, RT_TABLE_MAIN
, ifp
->metric
,
406 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
408 "%u: IF %s IPv6 address down, scheduling RIB processing",
409 ifp
->vrf_id
, ifp
->name
);
411 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
413 /* Schedule LSP forwarding entries for processing, if appropriate. */
414 if (ifp
->vrf_id
== VRF_DEFAULT
) {
415 if (IS_ZEBRA_DEBUG_MPLS
)
417 "%u: IF %s IPv4 address add/up, scheduling MPLS processing",
418 ifp
->vrf_id
, ifp
->name
);
419 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
));
423 /* Add connected IPv6 route to the interface. */
424 void connected_add_ipv6(struct interface
*ifp
, int flags
, struct in6_addr
*addr
,
425 u_char prefixlen
, struct in6_addr
*broad
,
428 struct prefix_ipv6
*p
;
429 struct connected
*ifc
;
431 if (ipv6_martian(addr
))
434 /* Make connected structure. */
435 ifc
= connected_new();
438 /* If we get a notification from the kernel,
439 * we can safely assume the address is known to the kernel */
440 SET_FLAG(ifc
->conf
, ZEBRA_IFC_QUEUED
);
442 /* Allocate new connected address. */
443 p
= prefix_ipv6_new();
444 p
->family
= AF_INET6
;
445 IPV6_ADDR_COPY(&p
->prefix
, addr
);
446 p
->prefixlen
= prefixlen
;
447 ifc
->address
= (struct prefix
*)p
;
449 /* If there is broadcast or peer address. */
451 if (IN6_IS_ADDR_UNSPECIFIED(broad
))
453 "warning: %s called for interface %s with unspecified "
454 "destination address; ignoring!",
455 __func__
, ifp
->name
);
457 p
= prefix_ipv6_new();
458 p
->family
= AF_INET6
;
459 IPV6_ADDR_COPY(&p
->prefix
, broad
);
460 p
->prefixlen
= prefixlen
;
461 ifc
->destination
= (struct prefix
*)p
;
464 if (CHECK_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
) && !ifc
->destination
) {
466 "warning: %s called for interface %s "
467 "with peer flag set, but no peer address supplied",
468 __func__
, ifp
->name
);
469 UNSET_FLAG(ifc
->flags
, ZEBRA_IFA_PEER
);
472 /* Label of this address. */
474 ifc
->label
= XSTRDUP(MTYPE_CONNECTED_LABEL
, label
);
476 /* On Linux, we only get here when DAD is complete, therefore we can set
479 * On BSD, there currently doesn't seem to be a way to check for
481 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
483 * might still be running.
485 SET_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
);
486 connected_update(ifp
, ifc
);
489 void connected_down_ipv6(struct interface
*ifp
, struct connected
*ifc
)
493 if (!CHECK_FLAG(ifc
->conf
, ZEBRA_IFC_REAL
))
496 PREFIX_COPY_IPV6(&p
, CONNECTED_PREFIX(ifc
));
500 if (IN6_IS_ADDR_UNSPECIFIED(&p
.u
.prefix6
))
503 rib_delete(AFI_IP6
, SAFI_UNICAST
, ifp
->vrf_id
, ZEBRA_ROUTE_CONNECT
, 0,
504 0, &p
, NULL
, NULL
, ifp
->ifindex
, 0);
506 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
508 "%u: IF %s IPv6 address down, scheduling RIB processing",
509 ifp
->vrf_id
, ifp
->name
);
511 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
513 /* Schedule LSP forwarding entries for processing, if appropriate. */
514 if (ifp
->vrf_id
== VRF_DEFAULT
) {
515 if (IS_ZEBRA_DEBUG_MPLS
)
517 "%u: IF %s IPv4 address add/up, scheduling MPLS processing",
518 ifp
->vrf_id
, ifp
->name
);
519 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
));
523 void connected_delete_ipv6(struct interface
*ifp
, struct in6_addr
*address
,
524 u_char prefixlen
, struct in6_addr
*broad
)
526 struct prefix_ipv6 p
;
527 struct connected
*ifc
;
529 memset(&p
, 0, sizeof(struct prefix_ipv6
));
531 memcpy(&p
.prefix
, address
, sizeof(struct in6_addr
));
532 p
.prefixlen
= prefixlen
;
534 ifc
= connected_check(ifp
, (struct prefix
*)&p
);
538 connected_withdraw(ifc
);
540 if (IS_ZEBRA_DEBUG_RIB_DETAILED
)
542 "%u: IF %s IPv6 address del, scheduling RIB processing",
543 ifp
->vrf_id
, ifp
->name
);
545 rib_update(ifp
->vrf_id
, RIB_UPDATE_IF_CHANGE
);
547 /* Schedule LSP forwarding entries for processing, if appropriate. */
548 if (ifp
->vrf_id
== VRF_DEFAULT
) {
549 if (IS_ZEBRA_DEBUG_MPLS
)
551 "%u: IF %s IPv4 address add/up, scheduling MPLS processing",
552 ifp
->vrf_id
, ifp
->name
);
553 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp
->vrf_id
));
557 int connected_is_unnumbered(struct interface
*ifp
)
559 struct connected
*connected
;
560 struct listnode
*node
;
562 for (ALL_LIST_ELEMENTS_RO(ifp
->connected
, node
, connected
)) {
563 if (CHECK_FLAG(connected
->conf
, ZEBRA_IFC_REAL
)
564 && connected
->address
->family
== AF_INET
)
565 return CHECK_FLAG(connected
->flags
,
566 ZEBRA_IFA_UNNUMBERED
);