]> git.proxmox.com Git - mirror_frr.git/blob - zebra/connected.c
*: reindent
[mirror_frr.git] / zebra / connected.c
1 /*
2 * Address linked list routine.
3 * Copyright (C) 1997, 98 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
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
10 * later version.
11 *
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.
16 *
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
20 */
21
22 #include <zebra.h>
23
24 #include "prefix.h"
25 #include "linklist.h"
26 #include "if.h"
27 #include "table.h"
28 #include "rib.h"
29 #include "table.h"
30 #include "log.h"
31 #include "memory.h"
32 #include "zebra_memory.h"
33
34 #include "vty.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"
43
44 /* communicate the withdrawal of a connected address */
45 static void connected_withdraw(struct connected *ifc)
46 {
47 if (!ifc)
48 return;
49
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);
53
54 if (ifc->address->family == AF_INET)
55 if_subnet_delete(ifc->ifp, ifc);
56
57 if (ifc->address->family == AF_INET)
58 connected_down_ipv4(ifc->ifp, ifc);
59 else
60 connected_down_ipv6(ifc->ifp, ifc);
61
62 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
63 }
64
65 /* The address is not in the kernel anymore, so clear the flag */
66 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
67
68 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
69 listnode_delete(ifc->ifp->connected, ifc);
70 connected_free(ifc);
71 }
72 }
73
74 static void connected_announce(struct interface *ifp, struct connected *ifc)
75 {
76 if (!ifc)
77 return;
78
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);
82 else
83 UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
84 }
85
86 listnode_add(ifp->connected, ifc);
87
88 /* Update interface address information to protocol daemon. */
89 if (ifc->address->family == AF_INET)
90 if_subnet_add(ifp, ifc);
91
92 zebra_interface_address_add_update(ifp, ifc);
93
94 if (if_is_operative(ifp)) {
95 if (ifc->address->family == AF_INET)
96 connected_up_ipv4(ifp, ifc);
97 else
98 connected_up_ipv6(ifp, ifc);
99 }
100 }
101
102 /* If same interface address is already exist... */
103 struct connected *connected_check(struct interface *ifp, struct prefix *p)
104 {
105 struct connected *ifc;
106 struct listnode *node;
107
108 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc))
109 if (prefix_same(ifc->address, p))
110 return ifc;
111
112 return NULL;
113 }
114
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)
117 {
118 if (ifc1->ifp != ifc2->ifp)
119 return 0;
120
121 if (ifc1->destination)
122 if (!ifc2->destination)
123 return 0;
124 if (ifc2->destination)
125 if (!ifc1->destination)
126 return 0;
127
128 if (ifc1->destination && ifc2->destination)
129 if (!prefix_same(ifc1->destination, ifc2->destination))
130 return 0;
131
132 if (ifc1->flags != ifc2->flags)
133 return 0;
134
135 if (ifc1->conf != ifc2->conf)
136 return 0;
137
138 return 1;
139 }
140
141 /* Handle changes to addresses and send the neccesary announcements
142 * to clients. */
143 static void connected_update(struct interface *ifp, struct connected *ifc)
144 {
145 struct connected *current;
146
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);
151
152 /* Avoid spurious withdraws, this might be just the kernel
153 * 'reflecting'
154 * back an address we have already added.
155 */
156 if (connected_same(current, ifc)) {
157 /* nothing to do */
158 connected_free(ifc);
159 return;
160 }
161
162 /* Clear the configured flag on the old ifc, so it will be freed
163 * by
164 * connected withdraw. */
165 UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
166 connected_withdraw(
167 current); /* implicit withdraw - freebsd does this */
168 }
169
170 /* If the connected is new or has changed, announce it, if it is usable
171 */
172 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
173 connected_announce(ifp, ifc);
174 }
175
176 /* Called from if_up(). */
177 void connected_up_ipv4(struct interface *ifp, struct connected *ifc)
178 {
179 struct prefix p;
180
181 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
182 return;
183
184 PREFIX_COPY_IPV4((struct prefix_ipv4 *)&p, CONNECTED_PREFIX(ifc));
185
186 /* Apply mask to the network. */
187 apply_mask(&p);
188
189 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
190 address. */
191 if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
192 return;
193
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,
196 0, 0);
197
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,
200 0, 0);
201
202 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
203 zlog_debug(
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);
207
208 /* Schedule LSP forwarding entries for processing, if appropriate. */
209 if (ifp->vrf_id == VRF_DEFAULT) {
210 if (IS_ZEBRA_DEBUG_MPLS)
211 zlog_debug(
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));
215 }
216 }
217
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,
221 const char *label)
222 {
223 struct prefix_ipv4 *p;
224 struct connected *ifc;
225
226 if (ipv4_martian(addr))
227 return;
228
229 /* Make connected structure. */
230 ifc = connected_new();
231 ifc->ifp = ifp;
232 ifc->flags = flags;
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);
236
237 /* Allocate new connected address. */
238 p = prefix_ipv4_new();
239 p->family = AF_INET;
240 p->prefix = *addr;
241 p->prefixlen = prefixlen;
242 ifc->address = (struct prefix *)p;
243
244 /* If there is broadcast or peer address. */
245 if (broad) {
246 p = prefix_ipv4_new();
247 p->family = AF_INET;
248 p->prefix = *broad;
249 p->prefixlen = prefixlen;
250 ifc->destination = (struct prefix *)p;
251
252 /* validate the destination address */
253 if (CONNECTED_PEER(ifc)) {
254 if (IPV4_ADDR_SAME(addr, broad))
255 zlog_warn(
256 "warning: interface %s has same local and peer "
257 "address %s, routing protocols may malfunction",
258 ifp->name, inet_ntoa(*addr));
259 } else {
260 if (broad->s_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,
265 prefixlen);
266 zlog_warn(
267 "warning: interface %s broadcast addr %s/%d != "
268 "calculated %s, routing protocols may malfunction",
269 ifp->name,
270 inet_ntop(AF_INET, broad, buf[0],
271 sizeof(buf[0])),
272 prefixlen,
273 inet_ntop(AF_INET, &bcalc, buf[1],
274 sizeof(buf[1])));
275 }
276 }
277
278 } else {
279 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
280 zlog_warn(
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);
285 }
286
287 /* no broadcast or destination address was supplied */
288 if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
289 zlog_warn(
290 "warning: PtP interface %s with addr %s/%d needs a "
291 "peer address",
292 ifp->name, inet_ntoa(*addr), prefixlen);
293 }
294
295 /* Label of this address. */
296 if (label)
297 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
298
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);
302
303 connected_update(ifp, ifc);
304 }
305
306 void connected_down_ipv4(struct interface *ifp, struct connected *ifc)
307 {
308 struct prefix p;
309
310 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
311 return;
312
313 PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
314
315 /* Apply mask to the network. */
316 apply_mask(&p);
317
318 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
319 address. */
320 if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
321 return;
322
323 /* Same logic as for connected_up_ipv4(): push the changes into the
324 * head. */
325 rib_delete(AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0, 0,
326 &p, NULL, NULL, ifp->ifindex, 0);
327
328 rib_delete(AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
329 0, &p, NULL, NULL, ifp->ifindex, 0);
330
331 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
332 zlog_debug(
333 "%u: IF %s IPv4 address down, scheduling RIB processing",
334 ifp->vrf_id, ifp->name);
335
336 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
337
338 /* Schedule LSP forwarding entries for processing, if appropriate. */
339 if (ifp->vrf_id == VRF_DEFAULT) {
340 if (IS_ZEBRA_DEBUG_MPLS)
341 zlog_debug(
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));
345 }
346 }
347
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)
352 {
353 struct prefix_ipv4 p;
354 struct connected *ifc;
355
356 memset(&p, 0, sizeof(struct prefix_ipv4));
357 p.family = AF_INET;
358 p.prefix = *addr;
359 p.prefixlen = prefixlen;
360
361 ifc = connected_check(ifp, (struct prefix *)&p);
362 if (!ifc)
363 return;
364
365 connected_withdraw(ifc);
366
367 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
368 zlog_debug(
369 "%u: IF %s IPv4 address del, scheduling RIB processing",
370 ifp->vrf_id, ifp->name);
371
372 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
373
374 /* Schedule LSP forwarding entries for processing, if appropriate. */
375 if (ifp->vrf_id == VRF_DEFAULT) {
376 if (IS_ZEBRA_DEBUG_MPLS)
377 zlog_debug(
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));
381 }
382 }
383
384 void connected_up_ipv6(struct interface *ifp, struct connected *ifc)
385 {
386 struct prefix p;
387
388 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
389 return;
390
391 PREFIX_COPY_IPV6((struct prefix_ipv6 *)&p, CONNECTED_PREFIX(ifc));
392
393 /* Apply mask to the network. */
394 apply_mask(&p);
395
396 #ifndef LINUX
397 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
398 if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
399 return;
400 #endif
401
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,
404 0, 0);
405
406 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
407 zlog_debug(
408 "%u: IF %s IPv6 address down, scheduling RIB processing",
409 ifp->vrf_id, ifp->name);
410
411 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
412
413 /* Schedule LSP forwarding entries for processing, if appropriate. */
414 if (ifp->vrf_id == VRF_DEFAULT) {
415 if (IS_ZEBRA_DEBUG_MPLS)
416 zlog_debug(
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));
420 }
421 }
422
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,
426 const char *label)
427 {
428 struct prefix_ipv6 *p;
429 struct connected *ifc;
430
431 if (ipv6_martian(addr))
432 return;
433
434 /* Make connected structure. */
435 ifc = connected_new();
436 ifc->ifp = ifp;
437 ifc->flags = flags;
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);
441
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;
448
449 /* If there is broadcast or peer address. */
450 if (broad) {
451 if (IN6_IS_ADDR_UNSPECIFIED(broad))
452 zlog_warn(
453 "warning: %s called for interface %s with unspecified "
454 "destination address; ignoring!",
455 __func__, ifp->name);
456 else {
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;
462 }
463 }
464 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER) && !ifc->destination) {
465 zlog_warn(
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);
470 }
471
472 /* Label of this address. */
473 if (label)
474 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
475
476 /* On Linux, we only get here when DAD is complete, therefore we can set
477 * ZEBRA_IFC_REAL.
478 *
479 * On BSD, there currently doesn't seem to be a way to check for
480 * completion of
481 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
482 * although DAD
483 * might still be running.
484 */
485 SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
486 connected_update(ifp, ifc);
487 }
488
489 void connected_down_ipv6(struct interface *ifp, struct connected *ifc)
490 {
491 struct prefix p;
492
493 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
494 return;
495
496 PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));
497
498 apply_mask(&p);
499
500 if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
501 return;
502
503 rib_delete(AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT, 0,
504 0, &p, NULL, NULL, ifp->ifindex, 0);
505
506 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
507 zlog_debug(
508 "%u: IF %s IPv6 address down, scheduling RIB processing",
509 ifp->vrf_id, ifp->name);
510
511 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
512
513 /* Schedule LSP forwarding entries for processing, if appropriate. */
514 if (ifp->vrf_id == VRF_DEFAULT) {
515 if (IS_ZEBRA_DEBUG_MPLS)
516 zlog_debug(
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));
520 }
521 }
522
523 void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address,
524 u_char prefixlen, struct in6_addr *broad)
525 {
526 struct prefix_ipv6 p;
527 struct connected *ifc;
528
529 memset(&p, 0, sizeof(struct prefix_ipv6));
530 p.family = AF_INET6;
531 memcpy(&p.prefix, address, sizeof(struct in6_addr));
532 p.prefixlen = prefixlen;
533
534 ifc = connected_check(ifp, (struct prefix *)&p);
535 if (!ifc)
536 return;
537
538 connected_withdraw(ifc);
539
540 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
541 zlog_debug(
542 "%u: IF %s IPv6 address del, scheduling RIB processing",
543 ifp->vrf_id, ifp->name);
544
545 rib_update(ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
546
547 /* Schedule LSP forwarding entries for processing, if appropriate. */
548 if (ifp->vrf_id == VRF_DEFAULT) {
549 if (IS_ZEBRA_DEBUG_MPLS)
550 zlog_debug(
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));
554 }
555 }
556
557 int connected_is_unnumbered(struct interface *ifp)
558 {
559 struct connected *connected;
560 struct listnode *node;
561
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);
567 }
568 return 0;
569 }