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