]> git.proxmox.com Git - mirror_frr.git/blob - zebra/connected.c
290973a5cbf15b8b875a577751355dc7df84cad1
[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
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "prefix.h"
26 #include "linklist.h"
27 #include "if.h"
28 #include "table.h"
29 #include "rib.h"
30 #include "table.h"
31 #include "log.h"
32 #include "memory.h"
33 #include "zebra_memory.h"
34
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
42 /* communicate the withdrawal of a connected address */
43 static void
44 connected_withdraw (struct connected *ifc)
45 {
46 if (! ifc)
47 return;
48
49 /* Update interface address information to protocol daemon. */
50 if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
51 {
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 #ifdef HAVE_IPV6
60 else
61 connected_down_ipv6 (ifc->ifp, ifc);
62 #endif
63
64 UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);
65 }
66
67 /* The address is not in the kernel anymore, so clear the flag */
68 UNSET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
69
70 if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
71 {
72 listnode_delete (ifc->ifp->connected, ifc);
73 connected_free (ifc);
74 }
75 }
76
77 static void
78 connected_announce (struct interface *ifp, struct connected *ifc)
79 {
80 if (!ifc)
81 return;
82
83 if (!if_is_loopback(ifp) && ifc->address->family == AF_INET)
84 {
85 if (ifc->address->prefixlen == 32)
86 SET_FLAG (ifc->flags, ZEBRA_IFA_UNNUMBERED);
87 else
88 UNSET_FLAG (ifc->flags, ZEBRA_IFA_UNNUMBERED);
89 }
90
91 listnode_add (ifp->connected, ifc);
92
93 /* Update interface address information to protocol daemon. */
94 if (ifc->address->family == AF_INET)
95 if_subnet_add (ifp, ifc);
96
97 zebra_interface_address_add_update (ifp, ifc);
98
99 if (if_is_operative(ifp))
100 {
101 if (ifc->address->family == AF_INET)
102 connected_up_ipv4 (ifp, ifc);
103 #ifdef HAVE_IPV6
104 else
105 connected_up_ipv6 (ifp, ifc);
106 #endif
107 }
108 }
109
110 /* If same interface address is already exist... */
111 struct connected *
112 connected_check (struct interface *ifp, struct prefix *p)
113 {
114 struct connected *ifc;
115 struct listnode *node;
116
117 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, ifc))
118 if (prefix_same (ifc->address, p))
119 return ifc;
120
121 return NULL;
122 }
123
124 /* Check if two ifc's describe the same address in the same state */
125 static int
126 connected_same (struct connected *ifc1, struct connected *ifc2)
127 {
128 if (ifc1->ifp != ifc2->ifp)
129 return 0;
130
131 if (ifc1->destination)
132 if (!ifc2->destination)
133 return 0;
134 if (ifc2->destination)
135 if (!ifc1->destination)
136 return 0;
137
138 if (ifc1->destination && ifc2->destination)
139 if (!prefix_same (ifc1->destination, ifc2->destination))
140 return 0;
141
142 if (ifc1->flags != ifc2->flags)
143 return 0;
144
145 if (ifc1->conf != ifc2->conf)
146 return 0;
147
148 return 1;
149 }
150
151 /* Handle changes to addresses and send the neccesary announcements
152 * to clients. */
153 static void
154 connected_update(struct interface *ifp, struct connected *ifc)
155 {
156 struct connected *current;
157
158 /* Check same connected route. */
159 if ((current = connected_check (ifp, (struct prefix *) ifc->address)))
160 {
161 if (CHECK_FLAG(current->conf, ZEBRA_IFC_CONFIGURED))
162 SET_FLAG(ifc->conf, ZEBRA_IFC_CONFIGURED);
163
164 /* Avoid spurious withdraws, this might be just the kernel 'reflecting'
165 * back an address we have already added.
166 */
167 if (connected_same (current, ifc))
168 {
169 /* nothing to do */
170 connected_free (ifc);
171 return;
172 }
173
174 /* Clear the configured flag on the old ifc, so it will be freed by
175 * connected withdraw. */
176 UNSET_FLAG(current->conf, ZEBRA_IFC_CONFIGURED);
177 connected_withdraw (current); /* implicit withdraw - freebsd does this */
178 }
179
180 /* If the connected is new or has changed, announce it, if it is usable */
181 if (CHECK_FLAG(ifc->conf, ZEBRA_IFC_REAL))
182 connected_announce(ifp, ifc);
183 }
184
185 /* Called from if_up(). */
186 void
187 connected_up_ipv4 (struct interface *ifp, struct connected *ifc)
188 {
189 struct prefix p;
190
191 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
192 return;
193
194 PREFIX_COPY_IPV4((struct prefix_ipv4 *)&p, CONNECTED_PREFIX(ifc));
195
196 /* Apply mask to the network. */
197 apply_mask (&p);
198
199 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
200 address. */
201 if (prefix_ipv4_any ((struct prefix_ipv4 *)&p))
202 return;
203
204 rib_add (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
205 0, 0, &p, NULL, NULL, ifp->ifindex,
206 RT_TABLE_MAIN, ifp->metric, 0, 0);
207
208 rib_add (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
209 0, 0, &p, NULL, NULL, ifp->ifindex,
210 RT_TABLE_MAIN, ifp->metric, 0, 0);
211
212 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
213 zlog_debug ("%u: IF %s IPv4 address add/up, scheduling RIB processing",
214 ifp->vrf_id, ifp->name);
215 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
216 }
217
218 /* Add connected IPv4 route to the interface. */
219 void
220 connected_add_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
221 u_char prefixlen, struct in_addr *broad,
222 const char *label)
223 {
224 struct prefix_ipv4 *p;
225 struct connected *ifc;
226
227 if (ipv4_martian(addr))
228 return;
229
230 /* Make connected structure. */
231 ifc = connected_new ();
232 ifc->ifp = ifp;
233 ifc->flags = flags;
234 /* If we get a notification from the kernel,
235 * we can safely assume the address is known to the kernel */
236 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
237
238 /* Allocate new connected address. */
239 p = prefix_ipv4_new ();
240 p->family = AF_INET;
241 p->prefix = *addr;
242 p->prefixlen = prefixlen;
243 ifc->address = (struct prefix *) p;
244
245 /* If there is broadcast or peer address. */
246 if (broad)
247 {
248 p = prefix_ipv4_new ();
249 p->family = AF_INET;
250 p->prefix = *broad;
251 p->prefixlen = prefixlen;
252 ifc->destination = (struct prefix *) p;
253
254 /* validate the destination address */
255 if (CONNECTED_PEER(ifc))
256 {
257 if (IPV4_ADDR_SAME(addr,broad))
258 zlog_warn("warning: interface %s has same local and peer "
259 "address %s, routing protocols may malfunction",
260 ifp->name,inet_ntoa(*addr));
261 }
262 else
263 {
264 if (broad->s_addr != ipv4_broadcast_addr(addr->s_addr,prefixlen))
265 {
266 char buf[2][INET_ADDRSTRLEN];
267 struct in_addr bcalc;
268 bcalc.s_addr = ipv4_broadcast_addr(addr->s_addr,prefixlen);
269 zlog_warn("warning: interface %s broadcast addr %s/%d != "
270 "calculated %s, routing protocols may malfunction",
271 ifp->name,
272 inet_ntop (AF_INET, broad, buf[0], sizeof(buf[0])),
273 prefixlen,
274 inet_ntop (AF_INET, &bcalc, buf[1], sizeof(buf[1])));
275 }
276 }
277
278 }
279 else
280 {
281 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER))
282 {
283 zlog_warn("warning: %s called for interface %s "
284 "with peer flag set, but no peer address supplied",
285 __func__, ifp->name);
286 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
287 }
288
289 /* no broadcast or destination address was supplied */
290 if ((prefixlen == IPV4_MAX_PREFIXLEN) && if_is_pointopoint(ifp))
291 zlog_warn("warning: PtP interface %s with addr %s/%d needs a "
292 "peer address",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
307 connected_down_ipv4 (struct interface *ifp, struct connected *ifc)
308 {
309 struct prefix p;
310
311 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
312 return;
313
314 PREFIX_COPY_IPV4(&p, CONNECTED_PREFIX(ifc));
315
316 /* Apply mask to the network. */
317 apply_mask (&p);
318
319 /* In case of connected address is 0.0.0.0/0 we treat it tunnel
320 address. */
321 if (prefix_ipv4_any ((struct prefix_ipv4 *)&p))
322 return;
323
324 /* Same logic as for connected_up_ipv4(): push the changes into the head. */
325 rib_delete (AFI_IP, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
326 0, 0, &p, NULL, ifp->ifindex, 0);
327
328 rib_delete (AFI_IP, SAFI_MULTICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
329 0, 0, &p, NULL, ifp->ifindex, 0);
330
331 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
332 zlog_debug ("%u: IF %s IPv4 address down, scheduling RIB processing",
333 ifp->vrf_id, ifp->name);
334
335 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
336 }
337
338 /* Delete connected IPv4 route to the interface. */
339 void
340 connected_delete_ipv4 (struct interface *ifp, int flags, struct in_addr *addr,
341 u_char prefixlen, struct in_addr *broad)
342 {
343 struct prefix_ipv4 p;
344 struct connected *ifc;
345
346 memset (&p, 0, sizeof (struct prefix_ipv4));
347 p.family = AF_INET;
348 p.prefix = *addr;
349 p.prefixlen = prefixlen;
350
351 ifc = connected_check (ifp, (struct prefix *) &p);
352 if (! ifc)
353 return;
354
355 connected_withdraw (ifc);
356
357 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
358 zlog_debug ("%u: IF %s IPv4 address del, scheduling RIB processing",
359 ifp->vrf_id, ifp->name);
360
361 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
362 }
363
364 void
365 connected_up_ipv6 (struct interface *ifp, struct connected *ifc)
366 {
367 struct prefix p;
368
369 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
370 return;
371
372 PREFIX_COPY_IPV6((struct prefix_ipv6 *)&p, CONNECTED_PREFIX(ifc));
373
374 /* Apply mask to the network. */
375 apply_mask (&p);
376
377 #ifndef LINUX
378 /* XXX: It is already done by rib_bogus_ipv6 within rib_add */
379 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
380 return;
381 #endif
382
383 rib_add (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
384 0, 0, &p, NULL, NULL, ifp->ifindex,
385 RT_TABLE_MAIN, ifp->metric, 0, 0);
386
387 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
388 zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
389 ifp->vrf_id, ifp->name);
390
391 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
392 }
393
394 /* Add connected IPv6 route to the interface. */
395 void
396 connected_add_ipv6 (struct interface *ifp, int flags, struct in6_addr *addr,
397 u_char prefixlen, struct in6_addr *broad,
398 const char *label)
399 {
400 struct prefix_ipv6 *p;
401 struct connected *ifc;
402
403 if (ipv6_martian(addr))
404 return;
405
406 /* Make connected structure. */
407 ifc = connected_new ();
408 ifc->ifp = ifp;
409 ifc->flags = flags;
410 /* If we get a notification from the kernel,
411 * we can safely assume the address is known to the kernel */
412 SET_FLAG(ifc->conf, ZEBRA_IFC_QUEUED);
413
414 /* Allocate new connected address. */
415 p = prefix_ipv6_new ();
416 p->family = AF_INET6;
417 IPV6_ADDR_COPY (&p->prefix, addr);
418 p->prefixlen = prefixlen;
419 ifc->address = (struct prefix *) p;
420
421 /* If there is broadcast or peer address. */
422 if (broad)
423 {
424 if (IN6_IS_ADDR_UNSPECIFIED(broad))
425 zlog_warn("warning: %s called for interface %s with unspecified "
426 "destination address; ignoring!", __func__, ifp->name);
427 else
428 {
429 p = prefix_ipv6_new ();
430 p->family = AF_INET6;
431 IPV6_ADDR_COPY (&p->prefix, broad);
432 p->prefixlen = prefixlen;
433 ifc->destination = (struct prefix *) p;
434 }
435 }
436 if (CHECK_FLAG(ifc->flags, ZEBRA_IFA_PEER) && !ifc->destination)
437 {
438 zlog_warn("warning: %s called for interface %s "
439 "with peer flag set, but no peer address supplied",
440 __func__, ifp->name);
441 UNSET_FLAG(ifc->flags, ZEBRA_IFA_PEER);
442 }
443
444 /* Label of this address. */
445 if (label)
446 ifc->label = XSTRDUP (MTYPE_CONNECTED_LABEL, label);
447
448 /* On Linux, we only get here when DAD is complete, therefore we can set
449 * ZEBRA_IFC_REAL.
450 *
451 * On BSD, there currently doesn't seem to be a way to check for completion of
452 * DAD, so we replicate the old behaviour and set ZEBRA_IFC_REAL, although DAD
453 * might still be running.
454 */
455 SET_FLAG(ifc->conf, ZEBRA_IFC_REAL);
456 connected_update(ifp, ifc);
457 }
458
459 void
460 connected_down_ipv6 (struct interface *ifp, struct connected *ifc)
461 {
462 struct prefix p;
463
464 if (! CHECK_FLAG (ifc->conf, ZEBRA_IFC_REAL))
465 return;
466
467 PREFIX_COPY_IPV6(&p, CONNECTED_PREFIX(ifc));
468
469 apply_mask (&p);
470
471 if (IN6_IS_ADDR_UNSPECIFIED (&p.u.prefix6))
472 return;
473
474 rib_delete (AFI_IP6, SAFI_UNICAST, ifp->vrf_id, ZEBRA_ROUTE_CONNECT,
475 0, 0, &p, NULL, ifp->ifindex, 0);
476
477 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
478 zlog_debug ("%u: IF %s IPv6 address down, scheduling RIB processing",
479 ifp->vrf_id, ifp->name);
480
481 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
482 }
483
484 void
485 connected_delete_ipv6 (struct interface *ifp, struct in6_addr *address,
486 u_char prefixlen, struct in6_addr *broad)
487 {
488 struct prefix_ipv6 p;
489 struct connected *ifc;
490
491 memset (&p, 0, sizeof (struct prefix_ipv6));
492 p.family = AF_INET6;
493 memcpy (&p.prefix, address, sizeof (struct in6_addr));
494 p.prefixlen = prefixlen;
495
496 ifc = connected_check (ifp, (struct prefix *) &p);
497 if (! ifc)
498 return;
499
500 connected_withdraw (ifc);
501
502 if (IS_ZEBRA_DEBUG_RIB_DETAILED)
503 zlog_debug ("%u: IF %s IPv6 address del, scheduling RIB processing",
504 ifp->vrf_id, ifp->name);
505
506 rib_update (ifp->vrf_id, RIB_UPDATE_IF_CHANGE);
507 }
508
509 int
510 connected_is_unnumbered (struct interface *ifp)
511 {
512 struct connected *connected;
513 struct listnode *node;
514
515 for (ALL_LIST_ELEMENTS_RO (ifp->connected, node, connected))
516 {
517 if (CHECK_FLAG (connected->conf, ZEBRA_IFC_REAL) &&
518 connected->address->family == AF_INET)
519 return CHECK_FLAG(connected->flags, ZEBRA_IFA_UNNUMBERED);
520 }
521 return 0;
522 }