]> git.proxmox.com Git - mirror_frr.git/blob - zebra/connected.c
Merge pull request #4650 from pguibert6WIND/show_ip_route_table_all
[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 #include "zebra/zebra_errors.h"
44
45 /* communicate the withdrawal of a connected address */
46 static void connected_withdraw(struct connected *ifc)
47 {
48 if (!ifc)
49 return;
50
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);
54
55 if (ifc->address->family == AF_INET)
56 if_subnet_delete(ifc->ifp, ifc);
57
58 connected_down(ifc->ifp, ifc);
59
60 UNSET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
61 }
62
63 /* The address is not in the kernel anymore, so clear the flag */
64 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
65
66 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED)) {
67 listnode_delete(ifc->ifp->connected, ifc);
68 connected_free(ifc);
69 }
70 }
71
72 static void connected_announce(struct interface *ifp, struct connected *ifc)
73 {
74 if (!ifc)
75 return;
76
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);
81 else
82 UNSET_FLAG(ifc->flags, ZEBRA_IFA_UNNUMBERED);
83 }
84
85 listnode_add(ifp->connected, ifc);
86
87 /* Update interface address information to protocol daemon. */
88 if (ifc->address->family == AF_INET)
89 if_subnet_add(ifp, ifc);
90
91 zebra_interface_address_add_update(ifp, ifc);
92
93 if (if_is_operative(ifp)) {
94 connected_up(ifp, ifc);
95 }
96 }
97
98 /* If same interface address is already exist... */
99 struct connected *connected_check(struct interface *ifp,
100 union prefixconstptr pu)
101 {
102 const struct prefix *p = pu.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 return ifc;
109
110 return NULL;
111 }
112
113 /* same, but with peer address */
114 struct connected *connected_check_ptp(struct interface *ifp,
115 union prefixconstptr pu,
116 union prefixconstptr du)
117 {
118 const struct prefix *p = pu.p;
119 const struct prefix *d = du.p;
120 struct connected *ifc;
121 struct listnode *node;
122
123 /* ignore broadcast addresses */
124 if (p->prefixlen != IPV4_MAX_PREFIXLEN)
125 d = NULL;
126
127 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
128 if (!prefix_same(ifc->address, p))
129 continue;
130 if (!CONNECTED_PEER(ifc) && !d)
131 return ifc;
132 if (CONNECTED_PEER(ifc) && d
133 && prefix_same(ifc->destination, d))
134 return ifc;
135 }
136
137 return NULL;
138 }
139
140 /* Check if two ifc's describe the same address in the same state */
141 static int connected_same(struct connected *ifc1, struct connected *ifc2)
142 {
143 if (ifc1->ifp != ifc2->ifp)
144 return 0;
145
146 if (ifc1->destination)
147 if (!ifc2->destination)
148 return 0;
149 if (ifc2->destination)
150 if (!ifc1->destination)
151 return 0;
152
153 if (ifc1->destination && ifc2->destination)
154 if (!prefix_same(ifc1->destination, ifc2->destination))
155 return 0;
156
157 if (ifc1->flags != ifc2->flags)
158 return 0;
159
160 if (ifc1->conf != ifc2->conf)
161 return 0;
162
163 return 1;
164 }
165
166 /* Handle changes to addresses and send the neccesary announcements
167 * to clients. */
168 static void connected_update(struct interface *ifp, struct connected *ifc)
169 {
170 struct connected *current;
171
172 /* Check same connected route. */
173 current = connected_check_ptp(ifp, ifc->address, ifc->destination);
174 if (current) {
175 if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
176 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
177
178 /* Avoid spurious withdraws, this might be just the kernel
179 * 'reflecting'
180 * back an address we have already added.
181 */
182 if (connected_same(current, ifc)) {
183 /* nothing to do */
184 connected_free(ifc);
185 return;
186 }
187
188 /* Clear the configured flag on the old ifc, so it will be freed
189 * by
190 * connected withdraw. */
191 UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
192 connected_withdraw(
193 current); /* implicit withdraw - freebsd does this */
194 }
195
196 /* If the connected is new or has changed, announce it, if it is usable
197 */
198 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
199 connected_announce(ifp, ifc);
200 }
201
202 /* Called from if_up(). */
203 void connected_up(struct interface *ifp, struct connected *ifc)
204 {
205 afi_t afi;
206 struct prefix p;
207 struct nexthop nh = {
208 .type = NEXTHOP_TYPE_IFINDEX,
209 .ifindex = ifp->ifindex,
210 .vrf_id = ifp->vrf_id,
211 };
212 struct zebra_vrf *zvrf;
213 uint32_t metric;
214
215 zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
216 if (!zvrf) {
217 flog_err(EC_ZEBRA_VRF_NOT_FOUND,
218 "%s: Received Up for interface but no associated zvrf: %d",
219 __PRETTY_FUNCTION__, ifp->vrf_id);
220 return;
221 }
222 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
223 return;
224
225 PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
226
227 /* Apply mask to the network. */
228 apply_mask(&p);
229
230 afi = family2afi(p.family);
231
232 switch (afi) {
233 case AFI_IP:
234 /*
235 * In case of connected address is 0.0.0.0/0 we treat it tunnel
236 * address.
237 */
238 if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
239 return;
240 break;
241 case AFI_IP6:
242 #ifndef LINUX
243 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
244 if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
245 return;
246 #endif
247 break;
248 default:
249 flog_warn(EC_ZEBRA_CONNECTED_AFI_UNKNOWN,
250 "Received unknown AFI: %s", afi2str(afi));
251 return;
252 break;
253 }
254
255 metric = (ifc->metric < (uint32_t)METRIC_MAX) ?
256 ifc->metric : ifp->metric;
257 rib_add(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
258 0, 0, &p, NULL, &nh, zvrf->table_id, metric, 0, 0, 0);
259
260 rib_add(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
261 0, 0, &p, NULL, &nh, zvrf->table_id, metric, 0, 0, 0);
262
263 /* Schedule LSP forwarding entries for processing, if appropriate. */
264 if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
265 if (IS_ZEBRA_DEBUG_MPLS) {
266 char buf[PREFIX_STRLEN];
267
268 zlog_debug(
269 "%u: IF %s IP %s address add/up, scheduling MPLS processing",
270 zvrf->vrf->vrf_id, ifp->name,
271 prefix2str(&p, buf, sizeof(buf)));
272 }
273 mpls_mark_lsps_for_processing(zvrf, &p);
274 }
275 }
276
277 /* Add connected IPv4 route to the interface. */
278 void connected_add_ipv4(struct interface *ifp, int flags, struct in_addr *addr,
279 uint16_t prefixlen, struct in_addr *broad,
280 const char *label, uint32_t metric)
281 {
282 struct prefix_ipv4 *p;
283 struct connected *ifc;
284
285 if (ipv4_martian(addr))
286 return;
287
288 /* Make connected structure. */
289 ifc = connected_new();
290 ifc->ifp = ifp;
291 ifc->flags = flags;
292 ifc->metric = metric;
293 /* If we get a notification from the kernel,
294 * we can safely assume the address is known to the kernel */
295 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
296
297 /* Allocate new connected address. */
298 p = prefix_ipv4_new();
299 p->family = AF_INET;
300 p->prefix = *addr;
301 p->prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
302 : prefixlen;
303 ifc->address = (struct prefix *)p;
304
305 /* If there is broadcast or peer address. */
306 if (broad) {
307 p = prefix_ipv4_new();
308 p->family = AF_INET;
309 p->prefix = *broad;
310 p->prefixlen = prefixlen;
311 ifc->destination = (struct prefix *)p;
312
313 /* validate the destination address */
314 if (CONNECTED_PEER(ifc)) {
315 if (IPV4_ADDR_SAME(addr, broad))
316 flog_warn(
317 EC_ZEBRA_IFACE_SAME_LOCAL_AS_PEER,
318 "warning: interface %s has same local and peer "
319 "address %s, routing protocols may malfunction",
320 ifp->name, inet_ntoa(*addr));
321 } else {
322 if (broad->s_addr
323 != ipv4_broadcast_addr(addr->s_addr, prefixlen)) {
324 char buf[2][INET_ADDRSTRLEN];
325 struct in_addr bcalc;
326 bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,
327 prefixlen);
328 flog_warn(
329 EC_ZEBRA_BCAST_ADDR_MISMATCH,
330 "warning: interface %s broadcast addr %s/%d != "
331 "calculated %s, routing protocols may malfunction",
332 ifp->name,
333 inet_ntop(AF_INET, broad, buf[0],
334 sizeof(buf[0])),
335 prefixlen,
336 inet_ntop(AF_INET, &bcalc, buf[1],
337 sizeof(buf[1])));
338 }
339 }
340
341 } else {
342 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
343 zlog_debug(
344 "warning: %s called for interface %s "
345 "with peer flag set, but no peer address supplied",
346 __func__, ifp->name);
347 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
348 }
349
350 /* no broadcast or destination address was supplied */
351 if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
352 zlog_debug(
353 "warning: PtP interface %s with addr %s/%d needs a "
354 "peer address",
355 ifp->name, inet_ntoa(*addr), prefixlen);
356 }
357
358 /* Label of this address. */
359 if (label)
360 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
361
362 /* For all that I know an IPv4 address is always ready when we receive
363 * the notification. So it should be safe to set the REAL flag here. */
364 SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
365
366 connected_update(ifp, ifc);
367 }
368
369 void connected_down(struct interface *ifp, struct connected *ifc)
370 {
371 afi_t afi;
372 struct prefix p;
373 struct nexthop nh = {
374 .type = NEXTHOP_TYPE_IFINDEX,
375 .ifindex = ifp->ifindex,
376 .vrf_id = ifp->vrf_id,
377 };
378 struct zebra_vrf *zvrf;
379
380 zvrf = zebra_vrf_lookup_by_id(ifp->vrf_id);
381 if (!zvrf) {
382 flog_err(EC_ZEBRA_VRF_NOT_FOUND,
383 "%s: Received Up for interface but no associated zvrf: %d",
384 __PRETTY_FUNCTION__, ifp->vrf_id);
385 return;
386 }
387
388 if (!CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
389 return;
390
391 PREFIX_COPY(&p, CONNECTED_PREFIX(ifc));
392
393 /* Apply mask to the network. */
394 apply_mask(&p);
395
396 afi = family2afi(p.family);
397
398 switch (afi) {
399 case AFI_IP:
400 /*
401 * In case of connected address is 0.0.0.0/0 we treat it tunnel
402 * address.
403 */
404 if (prefix_ipv4_any((struct prefix_ipv4 *)&p))
405 return;
406 break;
407 case AFI_IP6:
408 if (IN6_IS_ADDR_UNSPECIFIED(&p.u.prefix6))
409 return;
410 break;
411 default:
412 zlog_info("Unknown AFI: %s", afi2str(afi));
413 break;
414 }
415
416 /*
417 * Same logic as for connected_up(): push the changes into the
418 * head.
419 */
420 rib_delete(afi, SAFI_UNICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
421 0, 0, &p, NULL, &nh, zvrf->table_id, 0, 0, false);
422
423 rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,
424 0, 0, &p, NULL, &nh, zvrf->table_id, 0, 0, false);
425
426 /* Schedule LSP forwarding entries for processing, if appropriate. */
427 if (zvrf->vrf->vrf_id == VRF_DEFAULT) {
428 if (IS_ZEBRA_DEBUG_MPLS) {
429 char buf[PREFIX_STRLEN];
430
431 zlog_debug(
432 "%u: IF %s IP %s address down, scheduling MPLS processing",
433 zvrf->vrf->vrf_id, ifp->name,
434 prefix2str(&p, buf, sizeof(buf)));
435 }
436 mpls_mark_lsps_for_processing(zvrf, &p);
437 }
438 }
439
440 static void connected_delete_helper(struct connected *ifc, struct prefix *p)
441 {
442 struct interface *ifp;
443
444 if (!ifc)
445 return;
446 ifp = ifc->ifp;
447
448 connected_withdraw(ifc);
449
450 /* Schedule LSP forwarding entries for processing, if appropriate. */
451 if (ifp->vrf_id == VRF_DEFAULT) {
452 if (IS_ZEBRA_DEBUG_MPLS) {
453 char buf[PREFIX_STRLEN];
454
455 zlog_debug(
456 "%u: IF %s IP %s address delete, scheduling MPLS processing",
457 ifp->vrf_id, ifp->name,
458 prefix2str(p, buf, sizeof(buf)));
459 }
460 mpls_mark_lsps_for_processing(vrf_info_lookup(ifp->vrf_id), p);
461 }
462 }
463
464 /* Delete connected IPv4 route to the interface. */
465 void connected_delete_ipv4(struct interface *ifp, int flags,
466 struct in_addr *addr, uint16_t prefixlen,
467 struct in_addr *broad)
468 {
469 struct prefix p, d;
470 struct connected *ifc;
471
472 memset(&p, 0, sizeof(struct prefix));
473 p.family = AF_INET;
474 p.u.prefix4 = *addr;
475 p.prefixlen = CHECK_FLAG(flags, ZEBRA_IFA_PEER) ? IPV4_MAX_PREFIXLEN
476 : prefixlen;
477
478 if (broad) {
479 memset(&d, 0, sizeof(struct prefix));
480 d.family = AF_INET;
481 d.u.prefix4 = *broad;
482 d.prefixlen = prefixlen;
483 ifc = connected_check_ptp(ifp, &p, &d);
484 } else
485 ifc = connected_check_ptp(ifp, &p, NULL);
486
487 connected_delete_helper(ifc, &p);
488 }
489
490 /* Add connected IPv6 route to the interface. */
491 void connected_add_ipv6(struct interface *ifp, int flags, struct in6_addr *addr,
492 struct in6_addr *broad, uint16_t prefixlen,
493 const char *label, uint32_t metric)
494 {
495 struct prefix_ipv6 *p;
496 struct connected *ifc;
497
498 if (ipv6_martian(addr))
499 return;
500
501 /* Make connected structure. */
502 ifc = connected_new();
503 ifc->ifp = ifp;
504 ifc->flags = flags;
505 ifc->metric = metric;
506 /* If we get a notification from the kernel,
507 * we can safely assume the address is known to the kernel */
508 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
509
510 /* Allocate new connected address. */
511 p = prefix_ipv6_new();
512 p->family = AF_INET6;
513 IPV6_ADDR_COPY(&p->prefix, addr);
514 p->prefixlen = prefixlen;
515 ifc->address = (struct prefix *)p;
516
517 if (broad) {
518 p = prefix_ipv6_new();
519 p->family = AF_INET6;
520 IPV6_ADDR_COPY(&p->prefix, broad);
521 p->prefixlen = prefixlen;
522 ifc->destination = (struct prefix *)p;
523 } else {
524 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER)) {
525 zlog_debug(
526 "warning: %s called for interface %s with peer flag set, but no peer address supplied",
527 __func__, ifp->name);
528 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
529 }
530 }
531
532 /* Label of this address. */
533 if (label)
534 ifc->label = XSTRDUP(MTYPE_CONNECTED_LABEL, label);
535
536 /* On Linux, we only get here when DAD is complete, therefore we can set
537 * ZEBRA_IFC_REAL.
538 *
539 * On BSD, there currently doesn't seem to be a way to check for
540 * completion of
541 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL,
542 * although DAD
543 * might still be running.
544 */
545 SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
546 connected_update(ifp, ifc);
547 }
548
549 void connected_delete_ipv6(struct interface *ifp, struct in6_addr *address,
550 struct in6_addr *broad, uint16_t prefixlen)
551 {
552 struct prefix p, d;
553 struct connected *ifc;
554
555 memset(&p, 0, sizeof(struct prefix));
556 p.family = AF_INET6;
557 memcpy(&p.u.prefix6, address, sizeof(struct in6_addr));
558 p.prefixlen = prefixlen;
559
560 if (broad) {
561 memset(&d, 0, sizeof(struct prefix));
562 d.family = AF_INET6;
563 IPV6_ADDR_COPY(&d.u.prefix6, broad);
564 d.prefixlen = prefixlen;
565 ifc = connected_check_ptp(ifp, &p, &d);
566 } else
567 ifc = connected_check_ptp(ifp, &p, NULL);
568
569 connected_delete_helper(ifc, &p);
570 }
571
572 int connected_is_unnumbered(struct interface *ifp)
573 {
574 struct connected *connected;
575 struct listnode *node;
576
577 for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, connected)) {
578 if (CHECK_FLAG(connected->conf, ZEBRA_IFC_REAL)
579 && connected->address->family == AF_INET)
580 return CHECK_FLAG(connected->flags,
581 ZEBRA_IFA_UNNUMBERED);
582 }
583 return 1;
584 }