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