]> git.proxmox.com Git - mirror_frr.git/blob - zebra/rt_netlink.c
22908730c54c0dca13cf60b707e90bc04d32a80a
[mirror_frr.git] / zebra / rt_netlink.c
1 /* Kernel routing table updates using netlink over GNU/Linux system.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
3 *
4 * This file is part of GNU Zebra.
5 *
6 * GNU Zebra is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * GNU Zebra is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GNU Zebra; see the file COPYING. If not, write to the Free
18 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 */
21
22 #include <zebra.h>
23
24 /* Hack for GNU libc version 2. */
25 #ifndef MSG_TRUNC
26 #define MSG_TRUNC 0x20
27 #endif /* MSG_TRUNC */
28
29 #include "linklist.h"
30 #include "if.h"
31 #include "log.h"
32 #include "prefix.h"
33 #include "connected.h"
34 #include "table.h"
35 #include "rib.h"
36 #include "thread.h"
37 #include "privs.h"
38
39 #include "zebra/zserv.h"
40 #include "zebra/redistribute.h"
41 #include "zebra/interface.h"
42 #include "zebra/debug.h"
43
44 /* Socket interface to kernel */
45 struct nlsock
46 {
47 int sock;
48 int seq;
49 struct sockaddr_nl snl;
50 const char *name;
51 } netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
52 netlink_cmd = { -1, 0, {0}, "netlink-cmd"}, /* command channel */
53 netlink_addr = { -1, 0, {0}, "netlink-addr"}; /* address channel */
54
55 struct message nlmsg_str[] = {
56 {RTM_NEWROUTE, "RTM_NEWROUTE"},
57 {RTM_DELROUTE, "RTM_DELROUTE"},
58 {RTM_GETROUTE, "RTM_GETROUTE"},
59 {RTM_NEWLINK, "RTM_NEWLINK"},
60 {RTM_DELLINK, "RTM_DELLINK"},
61 {RTM_GETLINK, "RTM_GETLINK"},
62 {RTM_NEWADDR, "RTM_NEWADDR"},
63 {RTM_DELADDR, "RTM_DELADDR"},
64 {RTM_GETADDR, "RTM_GETADDR"},
65 {0, NULL}
66 };
67
68 const char *nexthop_types_desc[] =
69 {
70 "none",
71 "Directly connected",
72 "Interface route",
73 "IPv4 nexthop",
74 "IPv4 nexthop with ifindex",
75 "IPv4 nexthop with ifname",
76 "IPv6 nexthop",
77 "IPv6 nexthop with ifindex",
78 "IPv6 nexthop with ifname",
79 "Null0 nexthop",
80 };
81
82
83 extern struct zebra_t zebrad;
84
85 extern struct zebra_privs_t zserv_privs;
86
87 extern u_int32_t nl_rcvbufsize;
88
89 /* Note: on netlink systems, there should be a 1-to-1 mapping between interface
90 names and ifindex values. */
91 static void
92 set_ifindex(struct interface *ifp, unsigned int ifi_index)
93 {
94 struct interface *oifp;
95
96 if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
97 {
98 if (ifi_index == IFINDEX_INTERNAL)
99 zlog_err("Netlink is setting interface %s ifindex to reserved "
100 "internal value %u", ifp->name, ifi_index);
101 else
102 {
103 if (IS_ZEBRA_DEBUG_KERNEL)
104 zlog_debug("interface index %d was renamed from %s to %s",
105 ifi_index, oifp->name, ifp->name);
106 if (if_is_up(oifp))
107 zlog_err("interface rename detected on up interface: index %d "
108 "was renamed from %s to %s, results are uncertain!",
109 ifi_index, oifp->name, ifp->name);
110 if_delete_update(oifp);
111 }
112 }
113 ifp->ifindex = ifi_index;
114 }
115
116 /* Make socket for Linux netlink interface. */
117 static int
118 netlink_socket (struct nlsock *nl, unsigned long groups)
119 {
120 int ret;
121 struct sockaddr_nl snl;
122 int sock;
123 int namelen;
124 int save_errno;
125
126 sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
127 if (sock < 0)
128 {
129 zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
130 safe_strerror (errno));
131 return -1;
132 }
133
134 ret = fcntl (sock, F_SETFL, O_NONBLOCK);
135 if (ret < 0)
136 {
137 zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
138 safe_strerror (errno));
139 close (sock);
140 return -1;
141 }
142
143 /* Set receive buffer size if it's set from command line */
144 if (nl_rcvbufsize)
145 {
146 u_int32_t oldsize, oldlen;
147 u_int32_t newsize, newlen;
148
149 oldlen = sizeof(oldsize);
150 newlen = sizeof(newsize);
151
152 ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
153 if (ret < 0)
154 {
155 zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
156 safe_strerror (errno));
157 close (sock);
158 return -1;
159 }
160
161 ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
162 sizeof(nl_rcvbufsize));
163 if (ret < 0)
164 {
165 zlog (NULL, LOG_ERR, "Can't set %s receive buffer size: %s", nl->name,
166 safe_strerror (errno));
167 close (sock);
168 return -1;
169 }
170
171 ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
172 if (ret < 0)
173 {
174 zlog (NULL, LOG_ERR, "Can't get %s receive buffer size: %s", nl->name,
175 safe_strerror (errno));
176 close (sock);
177 return -1;
178 }
179
180 zlog (NULL, LOG_INFO,
181 "Setting netlink socket receive buffer size: %u -> %u",
182 oldsize, newsize);
183 }
184
185 memset (&snl, 0, sizeof snl);
186 snl.nl_family = AF_NETLINK;
187 snl.nl_groups = groups;
188
189 /* Bind the socket to the netlink structure for anything. */
190 if (zserv_privs.change (ZPRIVS_RAISE))
191 {
192 zlog (NULL, LOG_ERR, "Can't raise privileges");
193 return -1;
194 }
195
196 ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
197 save_errno = errno;
198 if (zserv_privs.change (ZPRIVS_LOWER))
199 zlog (NULL, LOG_ERR, "Can't lower privileges");
200
201 if (ret < 0)
202 {
203 zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
204 nl->name, snl.nl_groups, safe_strerror (save_errno));
205 close (sock);
206 return -1;
207 }
208
209 /* multiple netlink sockets will have different nl_pid */
210 namelen = sizeof snl;
211 ret = getsockname (sock, (struct sockaddr *) &snl, (socklen_t *) &namelen);
212 if (ret < 0 || namelen != sizeof snl)
213 {
214 zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
215 safe_strerror (errno));
216 close (sock);
217 return -1;
218 }
219
220 nl->snl = snl;
221 nl->sock = sock;
222 return ret;
223 }
224
225 int
226 set_netlink_blocking (struct nlsock *nl, int *flags)
227 {
228
229 /* Change socket flags for blocking I/O. */
230 if ((*flags = fcntl (nl->sock, F_GETFL, 0)) < 0)
231 {
232 zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s",
233 __FUNCTION__, __LINE__, safe_strerror (errno));
234 return -1;
235 }
236 *flags &= ~O_NONBLOCK;
237 if (fcntl (nl->sock, F_SETFL, *flags) < 0)
238 {
239 zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
240 __FUNCTION__, __LINE__, safe_strerror (errno));
241 return -1;
242 }
243 return 0;
244 }
245
246 int
247 set_netlink_nonblocking (struct nlsock *nl, int *flags)
248 {
249 /* Restore socket flags for nonblocking I/O */
250 *flags |= O_NONBLOCK;
251 if (fcntl (nl->sock, F_SETFL, *flags) < 0)
252 {
253 zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
254 __FUNCTION__, __LINE__, safe_strerror (errno));
255 return -1;
256 }
257 return 0;
258 }
259
260 /* Get type specified information from netlink. */
261 static int
262 netlink_request (int family, int type, struct nlsock *nl)
263 {
264 int ret;
265 struct sockaddr_nl snl;
266 int save_errno;
267
268 struct
269 {
270 struct nlmsghdr nlh;
271 struct rtgenmsg g;
272 } req;
273
274
275 /* Check netlink socket. */
276 if (nl->sock < 0)
277 {
278 zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
279 return -1;
280 }
281
282 memset (&snl, 0, sizeof snl);
283 snl.nl_family = AF_NETLINK;
284
285 req.nlh.nlmsg_len = sizeof req;
286 req.nlh.nlmsg_type = type;
287 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
288 req.nlh.nlmsg_pid = 0;
289 req.nlh.nlmsg_seq = ++nl->seq;
290 req.g.rtgen_family = family;
291
292 /* linux appears to check capabilities on every message
293 * have to raise caps for every message sent
294 */
295 if (zserv_privs.change (ZPRIVS_RAISE))
296 {
297 zlog (NULL, LOG_ERR, "Can't raise privileges");
298 return -1;
299 }
300
301 ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
302 (struct sockaddr *) &snl, sizeof snl);
303 save_errno = errno;
304
305 if (zserv_privs.change (ZPRIVS_LOWER))
306 zlog (NULL, LOG_ERR, "Can't lower privileges");
307
308 if (ret < 0)
309 {
310 zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
311 safe_strerror (save_errno));
312 return -1;
313 }
314
315 return 0;
316 }
317
318 /* Receive message from netlink interface and pass those information
319 to the given function. */
320 static int
321 netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
322 struct nlsock *nl)
323 {
324 int status;
325 int ret = 0;
326 int error;
327
328 while (1)
329 {
330 char buf[4096];
331 struct iovec iov = { buf, sizeof buf };
332 struct sockaddr_nl snl;
333 struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
334 struct nlmsghdr *h;
335 int save_errno;
336
337 if (zserv_privs.change (ZPRIVS_RAISE))
338 zlog (NULL, LOG_ERR, "Can't raise privileges");
339
340 status = recvmsg (nl->sock, &msg, 0);
341 save_errno = errno;
342
343 if (zserv_privs.change (ZPRIVS_LOWER))
344 zlog (NULL, LOG_ERR, "Can't lower privileges");
345
346 if (status < 0)
347 {
348 if (save_errno == EINTR)
349 continue;
350 if (save_errno == EWOULDBLOCK || save_errno == EAGAIN)
351 break;
352 zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
353 nl->name, safe_strerror(save_errno));
354 continue;
355 }
356
357 if (status == 0)
358 {
359 zlog (NULL, LOG_ERR, "%s EOF", nl->name);
360 return -1;
361 }
362
363 if (msg.msg_namelen != sizeof snl)
364 {
365 zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
366 nl->name, msg.msg_namelen);
367 return -1;
368 }
369
370 /* JF: Ignore messages that aren't from the kernel */
371 if ( snl.nl_pid != 0 )
372 {
373 zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
374 continue;
375 }
376
377 for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
378 h = NLMSG_NEXT (h, status))
379 {
380 /* Finish of reading. */
381 if (h->nlmsg_type == NLMSG_DONE)
382 return ret;
383
384 /* Error handling. */
385 if (h->nlmsg_type == NLMSG_ERROR)
386 {
387 struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
388
389 /* If the error field is zero, then this is an ACK */
390 if (err->error == 0)
391 {
392 if (IS_ZEBRA_DEBUG_KERNEL)
393 {
394 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%d",
395 __FUNCTION__, nl->name,
396 lookup (nlmsg_str, err->msg.nlmsg_type),
397 err->msg.nlmsg_type, err->msg.nlmsg_seq,
398 err->msg.nlmsg_pid);
399 }
400
401 /* return if not a multipart message, otherwise continue */
402 if (!(h->nlmsg_flags & NLM_F_MULTI))
403 {
404 return 0;
405 }
406 continue;
407 }
408
409 if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
410 {
411 zlog (NULL, LOG_ERR, "%s error: message truncated",
412 nl->name);
413 return -1;
414 }
415
416 /* Deal with Error Noise - MAG */
417 {
418 int loglvl = LOG_ERR;
419 int errnum = err->error;
420 int msg_type = err->msg.nlmsg_type;
421
422 if (nl == &netlink_cmd
423 && (-errnum == ENODEV || -errnum == ESRCH)
424 && (msg_type == RTM_NEWROUTE || msg_type == RTM_DELROUTE))
425 loglvl = LOG_DEBUG;
426
427 zlog (NULL, loglvl, "%s error: %s, type=%s(%u), "
428 "seq=%u, pid=%d",
429 nl->name, safe_strerror (-errnum),
430 lookup (nlmsg_str, msg_type),
431 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
432 }
433 /*
434 ret = -1;
435 continue;
436 */
437 return -1;
438 }
439
440 /* OK we got netlink message. */
441 if (IS_ZEBRA_DEBUG_KERNEL)
442 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%d",
443 nl->name,
444 lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
445 h->nlmsg_seq, h->nlmsg_pid);
446
447 /* skip unsolicited messages originating from command socket */
448 if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
449 {
450 if (IS_ZEBRA_DEBUG_KERNEL)
451 zlog_debug ("netlink_parse_info: %s packet comes from %s",
452 nl->name, netlink_cmd.name);
453 continue;
454 }
455
456 error = (*filter) (&snl, h);
457 if (error < 0)
458 {
459 zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
460 ret = error;
461 }
462 }
463
464 /* After error care. */
465 if (msg.msg_flags & MSG_TRUNC)
466 {
467 zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
468 continue;
469 }
470 if (status)
471 {
472 zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
473 status);
474 return -1;
475 }
476 }
477 return ret;
478 }
479
480 /* Utility function for parse rtattr. */
481 static void
482 netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
483 int len)
484 {
485 while (RTA_OK (rta, len))
486 {
487 if (rta->rta_type <= max)
488 tb[rta->rta_type] = rta;
489 rta = RTA_NEXT (rta, len);
490 }
491 }
492
493 /* Called from interface_lookup_netlink(). This function is only used
494 during bootstrap. */
495 int
496 netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
497 {
498 int len;
499 struct ifinfomsg *ifi;
500 struct rtattr *tb[IFLA_MAX + 1];
501 struct interface *ifp;
502 char *name;
503 int i;
504
505 ifi = NLMSG_DATA (h);
506
507 if (h->nlmsg_type != RTM_NEWLINK)
508 return 0;
509
510 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
511 if (len < 0)
512 return -1;
513
514 /* Looking up interface name. */
515 memset (tb, 0, sizeof tb);
516 netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
517
518 #ifdef IFLA_WIRELESS
519 /* check for wireless messages to ignore */
520 if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
521 {
522 if (IS_ZEBRA_DEBUG_KERNEL)
523 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
524 return 0;
525 }
526 #endif /* IFLA_WIRELESS */
527
528 if (tb[IFLA_IFNAME] == NULL)
529 return -1;
530 name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
531
532 /* Add interface. */
533 ifp = if_get_by_name (name);
534 set_ifindex(ifp, ifi->ifi_index);
535 ifp->flags = ifi->ifi_flags & 0x0000fffff;
536 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
537 ifp->metric = 1;
538
539 /* Hardware type and address. */
540 ifp->hw_type = ifi->ifi_type;
541
542 if (tb[IFLA_ADDRESS])
543 {
544 int hw_addr_len;
545
546 hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
547
548 if (hw_addr_len > INTERFACE_HWADDR_MAX)
549 zlog_warn ("Hardware address is too large: %d", hw_addr_len);
550 else
551 {
552 ifp->hw_addr_len = hw_addr_len;
553 memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
554
555 for (i = 0; i < hw_addr_len; i++)
556 if (ifp->hw_addr[i] != 0)
557 break;
558
559 if (i == hw_addr_len)
560 ifp->hw_addr_len = 0;
561 else
562 ifp->hw_addr_len = hw_addr_len;
563 }
564 }
565
566 if_add_update (ifp);
567
568 return 0;
569 }
570
571 /* Lookup interface IPv4/IPv6 address. */
572 int
573 netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
574 {
575 int len;
576 struct ifaddrmsg *ifa;
577 struct rtattr *tb[IFA_MAX + 1];
578 struct interface *ifp;
579 void *addr = NULL;
580 void *broad = NULL;
581 u_char flags = 0;
582 char *label = NULL;
583
584 ifa = NLMSG_DATA (h);
585
586 if (ifa->ifa_family != AF_INET
587 #ifdef HAVE_IPV6
588 && ifa->ifa_family != AF_INET6
589 #endif /* HAVE_IPV6 */
590 )
591 return 0;
592
593 if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
594 return 0;
595
596 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
597 if (len < 0)
598 return -1;
599
600 memset (tb, 0, sizeof tb);
601 netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
602
603 ifp = if_lookup_by_index (ifa->ifa_index);
604 if (ifp == NULL)
605 {
606 zlog_err ("netlink_interface_addr can't find interface by index %d",
607 ifa->ifa_index);
608 return -1;
609 }
610
611 if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
612 {
613 char buf[BUFSIZ];
614 zlog_debug ("netlink_interface_addr %s %s:",
615 lookup (nlmsg_str, h->nlmsg_type), ifp->name);
616 if (tb[IFA_LOCAL])
617 zlog_debug (" IFA_LOCAL %s/%d",
618 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
619 buf, BUFSIZ), ifa->ifa_prefixlen);
620 if (tb[IFA_ADDRESS])
621 zlog_debug (" IFA_ADDRESS %s/%d",
622 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
623 buf, BUFSIZ), ifa->ifa_prefixlen);
624 if (tb[IFA_BROADCAST])
625 zlog_debug (" IFA_BROADCAST %s/%d",
626 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
627 buf, BUFSIZ), ifa->ifa_prefixlen);
628 if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
629 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL]));
630 }
631
632 if (tb[IFA_ADDRESS] == NULL)
633 tb[IFA_ADDRESS] = tb[IFA_LOCAL];
634
635 if (ifp->flags & IFF_POINTOPOINT)
636 {
637 if (tb[IFA_LOCAL])
638 {
639 addr = RTA_DATA (tb[IFA_LOCAL]);
640 if (tb[IFA_ADDRESS] &&
641 memcmp(RTA_DATA(tb[IFA_ADDRESS]),RTA_DATA(tb[IFA_LOCAL]),4))
642 /* if IFA_ADDRESS != IFA_LOCAL, then it's the peer address */
643 broad = RTA_DATA (tb[IFA_ADDRESS]);
644 else
645 broad = NULL;
646 }
647 else
648 {
649 if (tb[IFA_ADDRESS])
650 addr = RTA_DATA (tb[IFA_ADDRESS]);
651 else
652 addr = NULL;
653 }
654 }
655 else
656 {
657 if (tb[IFA_ADDRESS])
658 addr = RTA_DATA (tb[IFA_ADDRESS]);
659 else
660 addr = NULL;
661
662 if (tb[IFA_BROADCAST])
663 broad = RTA_DATA(tb[IFA_BROADCAST]);
664 else
665 broad = NULL;
666 }
667
668 /* Flags. */
669 if (ifa->ifa_flags & IFA_F_SECONDARY)
670 SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
671
672 /* Label */
673 if (tb[IFA_LABEL])
674 label = (char *) RTA_DATA (tb[IFA_LABEL]);
675
676 if (ifp && label && strcmp (ifp->name, label) == 0)
677 label = NULL;
678
679 /* Register interface address to the interface. */
680 if (ifa->ifa_family == AF_INET)
681 {
682 if (h->nlmsg_type == RTM_NEWADDR)
683 connected_add_ipv4 (ifp, flags,
684 (struct in_addr *) addr, ifa->ifa_prefixlen,
685 (struct in_addr *) broad, label);
686 else
687 connected_delete_ipv4 (ifp, flags,
688 (struct in_addr *) addr, ifa->ifa_prefixlen,
689 (struct in_addr *) broad, label);
690 }
691 #ifdef HAVE_IPV6
692 if (ifa->ifa_family == AF_INET6)
693 {
694 if (h->nlmsg_type == RTM_NEWADDR)
695 connected_add_ipv6 (ifp,
696 (struct in6_addr *) addr, ifa->ifa_prefixlen,
697 (struct in6_addr *) broad);
698 else
699 connected_delete_ipv6 (ifp,
700 (struct in6_addr *) addr, ifa->ifa_prefixlen,
701 (struct in6_addr *) broad);
702 }
703 #endif /* HAVE_IPV6 */
704
705 return 0;
706 }
707
708 /* Looking up routing table by netlink interface. */
709 int
710 netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
711 {
712 int len;
713 struct rtmsg *rtm;
714 struct rtattr *tb[RTA_MAX + 1];
715 u_char flags = 0;
716
717 char anyaddr[16] = { 0 };
718
719 int index;
720 int table;
721 int metric;
722
723 void *dest;
724 void *gate;
725
726 rtm = NLMSG_DATA (h);
727
728 if (h->nlmsg_type != RTM_NEWROUTE)
729 return 0;
730 if (rtm->rtm_type != RTN_UNICAST)
731 return 0;
732
733 table = rtm->rtm_table;
734 #if 0 /* we weed them out later in rib_weed_tables () */
735 if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
736 return 0;
737 #endif
738
739 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
740 if (len < 0)
741 return -1;
742
743 memset (tb, 0, sizeof tb);
744 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
745
746 if (rtm->rtm_flags & RTM_F_CLONED)
747 return 0;
748 if (rtm->rtm_protocol == RTPROT_REDIRECT)
749 return 0;
750 if (rtm->rtm_protocol == RTPROT_KERNEL)
751 return 0;
752
753 if (rtm->rtm_src_len != 0)
754 return 0;
755
756 /* Route which inserted by Zebra. */
757 if (rtm->rtm_protocol == RTPROT_ZEBRA)
758 flags |= ZEBRA_FLAG_SELFROUTE;
759
760 index = 0;
761 metric = 0;
762 dest = NULL;
763 gate = NULL;
764
765 if (tb[RTA_OIF])
766 index = *(int *) RTA_DATA (tb[RTA_OIF]);
767
768 if (tb[RTA_DST])
769 dest = RTA_DATA (tb[RTA_DST]);
770 else
771 dest = anyaddr;
772
773 /* Multipath treatment is needed. */
774 if (tb[RTA_GATEWAY])
775 gate = RTA_DATA (tb[RTA_GATEWAY]);
776
777 if (tb[RTA_PRIORITY])
778 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
779
780 if (rtm->rtm_family == AF_INET)
781 {
782 struct prefix_ipv4 p;
783 p.family = AF_INET;
784 memcpy (&p.prefix, dest, 4);
785 p.prefixlen = rtm->rtm_dst_len;
786
787 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, metric, 0);
788 }
789 #ifdef HAVE_IPV6
790 if (rtm->rtm_family == AF_INET6)
791 {
792 struct prefix_ipv6 p;
793 p.family = AF_INET6;
794 memcpy (&p.prefix, dest, 16);
795 p.prefixlen = rtm->rtm_dst_len;
796
797 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table);
798 }
799 #endif /* HAVE_IPV6 */
800
801 return 0;
802 }
803
804 struct message rtproto_str[] = {
805 {RTPROT_REDIRECT, "redirect"},
806 {RTPROT_KERNEL, "kernel"},
807 {RTPROT_BOOT, "boot"},
808 {RTPROT_STATIC, "static"},
809 {RTPROT_GATED, "GateD"},
810 {RTPROT_RA, "router advertisement"},
811 {RTPROT_MRT, "MRT"},
812 {RTPROT_ZEBRA, "Zebra"},
813 #ifdef RTPROT_BIRD
814 {RTPROT_BIRD, "BIRD"},
815 #endif /* RTPROT_BIRD */
816 {0, NULL}
817 };
818
819 /* Routing information change from the kernel. */
820 int
821 netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
822 {
823 int len;
824 struct rtmsg *rtm;
825 struct rtattr *tb[RTA_MAX + 1];
826
827 char anyaddr[16] = { 0 };
828
829 int index;
830 int table;
831 void *dest;
832 void *gate;
833
834 rtm = NLMSG_DATA (h);
835
836 if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
837 {
838 /* If this is not route add/delete message print warning. */
839 zlog_warn ("Kernel message: %d\n", h->nlmsg_type);
840 return 0;
841 }
842
843 /* Connected route. */
844 if (IS_ZEBRA_DEBUG_KERNEL)
845 zlog_debug ("%s %s %s proto %s",
846 h->nlmsg_type ==
847 RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
848 rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
849 rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
850 lookup (rtproto_str, rtm->rtm_protocol));
851
852 if (rtm->rtm_type != RTN_UNICAST)
853 {
854 return 0;
855 }
856
857 table = rtm->rtm_table;
858 if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
859 {
860 return 0;
861 }
862
863 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
864 if (len < 0)
865 return -1;
866
867 memset (tb, 0, sizeof tb);
868 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
869
870 if (rtm->rtm_flags & RTM_F_CLONED)
871 return 0;
872 if (rtm->rtm_protocol == RTPROT_REDIRECT)
873 return 0;
874 if (rtm->rtm_protocol == RTPROT_KERNEL)
875 return 0;
876
877 if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
878 return 0;
879
880 if (rtm->rtm_src_len != 0)
881 {
882 zlog_warn ("netlink_route_change(): no src len");
883 return 0;
884 }
885
886 index = 0;
887 dest = NULL;
888 gate = NULL;
889
890 if (tb[RTA_OIF])
891 index = *(int *) RTA_DATA (tb[RTA_OIF]);
892
893 if (tb[RTA_DST])
894 dest = RTA_DATA (tb[RTA_DST]);
895 else
896 dest = anyaddr;
897
898 if (tb[RTA_GATEWAY])
899 gate = RTA_DATA (tb[RTA_GATEWAY]);
900
901 if (rtm->rtm_family == AF_INET)
902 {
903 struct prefix_ipv4 p;
904 p.family = AF_INET;
905 memcpy (&p.prefix, dest, 4);
906 p.prefixlen = rtm->rtm_dst_len;
907
908 if (IS_ZEBRA_DEBUG_KERNEL)
909 {
910 if (h->nlmsg_type == RTM_NEWROUTE)
911 zlog_debug ("RTM_NEWROUTE %s/%d",
912 inet_ntoa (p.prefix), p.prefixlen);
913 else
914 zlog_debug ("RTM_DELROUTE %s/%d",
915 inet_ntoa (p.prefix), p.prefixlen);
916 }
917
918 if (h->nlmsg_type == RTM_NEWROUTE)
919 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0);
920 else
921 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
922 }
923
924 #ifdef HAVE_IPV6
925 if (rtm->rtm_family == AF_INET6)
926 {
927 struct prefix_ipv6 p;
928 char buf[BUFSIZ];
929
930 p.family = AF_INET6;
931 memcpy (&p.prefix, dest, 16);
932 p.prefixlen = rtm->rtm_dst_len;
933
934 if (IS_ZEBRA_DEBUG_KERNEL)
935 {
936 if (h->nlmsg_type == RTM_NEWROUTE)
937 zlog_debug ("RTM_NEWROUTE %s/%d",
938 inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
939 p.prefixlen);
940 else
941 zlog_debug ("RTM_DELROUTE %s/%d",
942 inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
943 p.prefixlen);
944 }
945
946 if (h->nlmsg_type == RTM_NEWROUTE)
947 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
948 else
949 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
950 }
951 #endif /* HAVE_IPV6 */
952
953 return 0;
954 }
955
956 int
957 netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
958 {
959 int len;
960 struct ifinfomsg *ifi;
961 struct rtattr *tb[IFLA_MAX + 1];
962 struct interface *ifp;
963 char *name;
964
965 ifi = NLMSG_DATA (h);
966
967 if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
968 {
969 /* If this is not link add/delete message so print warning. */
970 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
971 h->nlmsg_type);
972 return 0;
973 }
974
975 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
976 if (len < 0)
977 return -1;
978
979 /* Looking up interface name. */
980 memset (tb, 0, sizeof tb);
981 netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
982
983 #ifdef IFLA_WIRELESS
984 /* check for wireless messages to ignore */
985 if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
986 {
987 if (IS_ZEBRA_DEBUG_KERNEL)
988 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
989 return 0;
990 }
991 #endif /* IFLA_WIRELESS */
992
993 if (tb[IFLA_IFNAME] == NULL)
994 return -1;
995 name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
996
997 /* Add interface. */
998 if (h->nlmsg_type == RTM_NEWLINK)
999 {
1000 ifp = if_lookup_by_name (name);
1001
1002 if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1003 {
1004 if (ifp == NULL)
1005 ifp = if_get_by_name (name);
1006
1007 set_ifindex(ifp, ifi->ifi_index);
1008 ifp->flags = ifi->ifi_flags & 0x0000fffff;
1009 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
1010 ifp->metric = 1;
1011
1012 /* If new link is added. */
1013 if_add_update (ifp);
1014 }
1015 else
1016 {
1017 /* Interface status change. */
1018 set_ifindex(ifp, ifi->ifi_index);
1019 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
1020 ifp->metric = 1;
1021
1022 if (if_is_operative (ifp))
1023 {
1024 ifp->flags = ifi->ifi_flags & 0x0000fffff;
1025 if (!if_is_operative (ifp))
1026 if_down (ifp);
1027 else
1028 /* Must notify client daemons of new interface status. */
1029 zebra_interface_up_update (ifp);
1030 }
1031 else
1032 {
1033 ifp->flags = ifi->ifi_flags & 0x0000fffff;
1034 if (if_is_operative (ifp))
1035 if_up (ifp);
1036 }
1037 }
1038 }
1039 else
1040 {
1041 /* RTM_DELLINK. */
1042 ifp = if_lookup_by_name (name);
1043
1044 if (ifp == NULL)
1045 {
1046 zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
1047 name);
1048 return 0;
1049 }
1050
1051 if_delete_update (ifp);
1052 }
1053
1054 return 0;
1055 }
1056
1057 int
1058 netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
1059 {
1060 switch (h->nlmsg_type)
1061 {
1062 case RTM_NEWROUTE:
1063 return netlink_route_change (snl, h);
1064 break;
1065 case RTM_DELROUTE:
1066 return netlink_route_change (snl, h);
1067 break;
1068 case RTM_NEWLINK:
1069 return netlink_link_change (snl, h);
1070 break;
1071 case RTM_DELLINK:
1072 return netlink_link_change (snl, h);
1073 break;
1074 case RTM_NEWADDR:
1075 return netlink_interface_addr (snl, h);
1076 break;
1077 case RTM_DELADDR:
1078 return netlink_interface_addr (snl, h);
1079 break;
1080 default:
1081 zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
1082 break;
1083 }
1084 return 0;
1085 }
1086
1087 /* Interface lookup by netlink socket. */
1088 int
1089 interface_lookup_netlink ()
1090 {
1091 int ret;
1092 int flags;
1093 int snb_ret;
1094
1095 /*
1096 * Change netlink socket flags to blocking to ensure we get
1097 * a reply via nelink_parse_info
1098 */
1099 snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
1100 if (snb_ret < 0)
1101 zlog (NULL, LOG_WARNING,
1102 "%s:%i Warning: Could not set netlink socket to blocking.",
1103 __FUNCTION__, __LINE__);
1104
1105 /* Get interface information. */
1106 ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
1107 if (ret < 0)
1108 return ret;
1109 ret = netlink_parse_info (netlink_interface, &netlink_cmd);
1110 if (ret < 0)
1111 return ret;
1112
1113 /* Get IPv4 address of the interfaces. */
1114 ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
1115 if (ret < 0)
1116 return ret;
1117 ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
1118 if (ret < 0)
1119 return ret;
1120
1121 #ifdef HAVE_IPV6
1122 /* Get IPv6 address of the interfaces. */
1123 ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
1124 if (ret < 0)
1125 return ret;
1126 ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
1127 if (ret < 0)
1128 return ret;
1129 #endif /* HAVE_IPV6 */
1130
1131 /* restore socket flags */
1132 if (snb_ret == 0)
1133 set_netlink_nonblocking (&netlink_cmd, &flags);
1134 return 0;
1135 }
1136
1137 /* Routing table read function using netlink interface. Only called
1138 bootstrap time. */
1139 int
1140 netlink_route_read ()
1141 {
1142 int ret;
1143 int flags;
1144 int snb_ret;
1145
1146 /*
1147 * Change netlink socket flags to blocking to ensure we get
1148 * a reply via nelink_parse_info
1149 */
1150 snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
1151 if (snb_ret < 0)
1152 zlog (NULL, LOG_WARNING,
1153 "%s:%i Warning: Could not set netlink socket to blocking.",
1154 __FUNCTION__, __LINE__);
1155
1156 /* Get IPv4 routing table. */
1157 ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
1158 if (ret < 0)
1159 return ret;
1160 ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
1161 if (ret < 0)
1162 return ret;
1163
1164 #ifdef HAVE_IPV6
1165 /* Get IPv6 routing table. */
1166 ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
1167 if (ret < 0)
1168 return ret;
1169 ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
1170 if (ret < 0)
1171 return ret;
1172 #endif /* HAVE_IPV6 */
1173
1174 /* restore flags */
1175 if (snb_ret == 0)
1176 set_netlink_nonblocking (&netlink_cmd, &flags);
1177 return 0;
1178 }
1179
1180 /* Utility function comes from iproute2.
1181 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1182 int
1183 addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
1184 {
1185 int len;
1186 struct rtattr *rta;
1187
1188 len = RTA_LENGTH (alen);
1189
1190 if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
1191 return -1;
1192
1193 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
1194 rta->rta_type = type;
1195 rta->rta_len = len;
1196 memcpy (RTA_DATA (rta), data, alen);
1197 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
1198
1199 return 0;
1200 }
1201
1202 int
1203 rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
1204 {
1205 int len;
1206 struct rtattr *subrta;
1207
1208 len = RTA_LENGTH (alen);
1209
1210 if (RTA_ALIGN (rta->rta_len) + len > maxlen)
1211 return -1;
1212
1213 subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
1214 subrta->rta_type = type;
1215 subrta->rta_len = len;
1216 memcpy (RTA_DATA (subrta), data, alen);
1217 rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
1218
1219 return 0;
1220 }
1221
1222 /* Utility function comes from iproute2.
1223 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1224 int
1225 addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
1226 {
1227 int len;
1228 struct rtattr *rta;
1229
1230 len = RTA_LENGTH (4);
1231
1232 if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
1233 return -1;
1234
1235 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
1236 rta->rta_type = type;
1237 rta->rta_len = len;
1238 memcpy (RTA_DATA (rta), &data, 4);
1239 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
1240
1241 return 0;
1242 }
1243
1244 static int
1245 netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
1246 {
1247 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
1248 return 0;
1249 }
1250
1251 /* sendmsg() to netlink socket then recvmsg(). */
1252 int
1253 netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
1254 {
1255 int status;
1256 struct sockaddr_nl snl;
1257 struct iovec iov = { (void *) n, n->nlmsg_len };
1258 struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
1259 int flags = 0;
1260 int snb_ret;
1261 int save_errno;
1262
1263 memset (&snl, 0, sizeof snl);
1264 snl.nl_family = AF_NETLINK;
1265
1266 n->nlmsg_seq = ++nl->seq;
1267
1268 /* Request an acknowledgement by setting NLM_F_ACK */
1269 n->nlmsg_flags |= NLM_F_ACK;
1270
1271 if (IS_ZEBRA_DEBUG_KERNEL)
1272 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
1273 lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
1274 n->nlmsg_seq);
1275
1276 /* Send message to netlink interface. */
1277 if (zserv_privs.change (ZPRIVS_RAISE))
1278 zlog (NULL, LOG_ERR, "Can't raise privileges");
1279 status = sendmsg (nl->sock, &msg, 0);
1280 save_errno = errno;
1281 if (zserv_privs.change (ZPRIVS_LOWER))
1282 zlog (NULL, LOG_ERR, "Can't lower privileges");
1283
1284 if (status < 0)
1285 {
1286 zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
1287 safe_strerror (save_errno));
1288 return -1;
1289 }
1290
1291 /*
1292 * Change socket flags for blocking I/O.
1293 * This ensures we wait for a reply in netlink_parse_info().
1294 */
1295 snb_ret = set_netlink_blocking (nl, &flags);
1296 if (snb_ret < 0)
1297 zlog (NULL, LOG_WARNING,
1298 "%s:%i Warning: Could not set netlink socket to blocking.",
1299 __FUNCTION__, __LINE__);
1300
1301 /*
1302 * Get reply from netlink socket.
1303 * The reply should either be an acknowlegement or an error.
1304 */
1305 status = netlink_parse_info (netlink_talk_filter, nl);
1306
1307 /* Restore socket flags for nonblocking I/O */
1308 if (snb_ret == 0)
1309 set_netlink_nonblocking (nl, &flags);
1310
1311 return status;
1312 }
1313
1314 /* Routing table change via netlink interface. */
1315 int
1316 netlink_route (int cmd, int family, void *dest, int length, void *gate,
1317 int index, int zebra_flags, int table)
1318 {
1319 int ret;
1320 int bytelen;
1321 struct sockaddr_nl snl;
1322 int discard;
1323
1324 struct
1325 {
1326 struct nlmsghdr n;
1327 struct rtmsg r;
1328 char buf[1024];
1329 } req;
1330
1331 memset (&req, 0, sizeof req);
1332
1333 bytelen = (family == AF_INET ? 4 : 16);
1334
1335 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1336 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1337 req.n.nlmsg_type = cmd;
1338 req.r.rtm_family = family;
1339 req.r.rtm_table = table;
1340 req.r.rtm_dst_len = length;
1341
1342 if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE)
1343 || (zebra_flags & ZEBRA_FLAG_REJECT))
1344 discard = 1;
1345 else
1346 discard = 0;
1347
1348 if (cmd == RTM_NEWROUTE)
1349 {
1350 req.r.rtm_protocol = RTPROT_ZEBRA;
1351 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1352
1353 if (discard)
1354 {
1355 if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
1356 req.r.rtm_type = RTN_BLACKHOLE;
1357 else if (zebra_flags & ZEBRA_FLAG_REJECT)
1358 req.r.rtm_type = RTN_UNREACHABLE;
1359 else
1360 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1361 }
1362 else
1363 req.r.rtm_type = RTN_UNICAST;
1364 }
1365
1366 if (dest)
1367 addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
1368
1369 if (!discard)
1370 {
1371 if (gate)
1372 addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
1373 if (index > 0)
1374 addattr32 (&req.n, sizeof req, RTA_OIF, index);
1375 }
1376
1377 /* Destination netlink address. */
1378 memset (&snl, 0, sizeof snl);
1379 snl.nl_family = AF_NETLINK;
1380
1381 /* Talk to netlink socket. */
1382 ret = netlink_talk (&req.n, &netlink_cmd);
1383 if (ret < 0)
1384 return -1;
1385
1386 return 0;
1387 }
1388
1389 /* Routing table change via netlink interface. */
1390 int
1391 netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
1392 int family)
1393 {
1394 int bytelen;
1395 struct sockaddr_nl snl;
1396 struct nexthop *nexthop = NULL;
1397 int nexthop_num = 0;
1398 int discard;
1399
1400 struct
1401 {
1402 struct nlmsghdr n;
1403 struct rtmsg r;
1404 char buf[1024];
1405 } req;
1406
1407 memset (&req, 0, sizeof req);
1408
1409 bytelen = (family == AF_INET ? 4 : 16);
1410
1411 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1412 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1413 req.n.nlmsg_type = cmd;
1414 req.r.rtm_family = family;
1415 req.r.rtm_table = rib->table;
1416 req.r.rtm_dst_len = p->prefixlen;
1417
1418 if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
1419 discard = 1;
1420 else
1421 discard = 0;
1422
1423 if (cmd == RTM_NEWROUTE)
1424 {
1425 req.r.rtm_protocol = RTPROT_ZEBRA;
1426 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1427
1428 if (discard)
1429 {
1430 if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
1431 req.r.rtm_type = RTN_BLACKHOLE;
1432 else if (rib->flags & ZEBRA_FLAG_REJECT)
1433 req.r.rtm_type = RTN_UNREACHABLE;
1434 else
1435 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1436 }
1437 else
1438 req.r.rtm_type = RTN_UNICAST;
1439 }
1440
1441 addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
1442
1443 /* Metric. */
1444 addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
1445
1446 if (discard)
1447 {
1448 if (cmd == RTM_NEWROUTE)
1449 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1450 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1451 goto skip;
1452 }
1453
1454 /* Multipath case. */
1455 if (rib->nexthop_active_num == 1 || MULTIPATH_NUM == 1)
1456 {
1457 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1458 {
1459
1460 if ((cmd == RTM_NEWROUTE
1461 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1462 || (cmd == RTM_DELROUTE
1463 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1464 {
1465
1466 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1467 {
1468 if (IS_ZEBRA_DEBUG_KERNEL)
1469 {
1470 zlog_debug
1471 ("netlink_route_multipath() (recursive, 1 hop): "
1472 "%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1473 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1474 inet6_ntoa (p->u.prefix6), p->prefixlen,
1475 nexthop_types_desc[nexthop->rtype]);
1476 }
1477
1478 if (nexthop->rtype == NEXTHOP_TYPE_IPV4
1479 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
1480 {
1481 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1482 &nexthop->rgate.ipv4, bytelen);
1483
1484 if (IS_ZEBRA_DEBUG_KERNEL)
1485 zlog_debug("netlink_route_multipath() (recursive, "
1486 "1 hop): nexthop via %s if %u",
1487 inet_ntoa (nexthop->rgate.ipv4),
1488 nexthop->rifindex);
1489 }
1490 #ifdef HAVE_IPV6
1491 if (nexthop->rtype == NEXTHOP_TYPE_IPV6
1492 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1493 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1494 {
1495 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1496 &nexthop->rgate.ipv6, bytelen);
1497
1498 if (IS_ZEBRA_DEBUG_KERNEL)
1499 zlog_debug("netlink_route_multipath() (recursive, "
1500 "1 hop): nexthop via %s if %u",
1501 inet6_ntoa (nexthop->rgate.ipv6),
1502 nexthop->rifindex);
1503 }
1504 #endif /* HAVE_IPV6 */
1505 if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
1506 || nexthop->rtype == NEXTHOP_TYPE_IFNAME
1507 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1508 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1509 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1510 {
1511 addattr32 (&req.n, sizeof req, RTA_OIF,
1512 nexthop->rifindex);
1513
1514 if (IS_ZEBRA_DEBUG_KERNEL)
1515 zlog_debug("netlink_route_multipath() (recursive, "
1516 "1 hop): nexthop via if %u",
1517 nexthop->rifindex);
1518 }
1519 }
1520 else
1521 {
1522 if (IS_ZEBRA_DEBUG_KERNEL)
1523 {
1524 zlog_debug
1525 ("netlink_route_multipath() (single hop): "
1526 "%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1527 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1528 inet6_ntoa (p->u.prefix6), p->prefixlen,
1529 nexthop_types_desc[nexthop->type]);
1530 }
1531
1532 if (nexthop->type == NEXTHOP_TYPE_IPV4
1533 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1534 {
1535 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1536 &nexthop->gate.ipv4, bytelen);
1537
1538 if (IS_ZEBRA_DEBUG_KERNEL)
1539 zlog_debug("netlink_route_multipath() (single hop): "
1540 "nexthop via %s if %u",
1541 inet_ntoa (nexthop->gate.ipv4),
1542 nexthop->ifindex);
1543 }
1544 #ifdef HAVE_IPV6
1545 if (nexthop->type == NEXTHOP_TYPE_IPV6
1546 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1547 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1548 {
1549 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1550 &nexthop->gate.ipv6, bytelen);
1551
1552 if (IS_ZEBRA_DEBUG_KERNEL)
1553 zlog_debug("netlink_route_multipath() (single hop): "
1554 "nexthop via %s if %u",
1555 inet6_ntoa (nexthop->gate.ipv6),
1556 nexthop->ifindex);
1557 }
1558 #endif /* HAVE_IPV6 */
1559 if (nexthop->type == NEXTHOP_TYPE_IFINDEX
1560 || nexthop->type == NEXTHOP_TYPE_IFNAME
1561 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
1562 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
1563 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1564 {
1565 addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
1566
1567 if (IS_ZEBRA_DEBUG_KERNEL)
1568 zlog_debug("netlink_route_multipath() (single hop): "
1569 "nexthop via if %u", nexthop->ifindex);
1570 }
1571 }
1572
1573 if (cmd == RTM_NEWROUTE)
1574 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1575
1576 nexthop_num++;
1577 break;
1578 }
1579 }
1580 }
1581 else
1582 {
1583 char buf[1024];
1584 struct rtattr *rta = (void *) buf;
1585 struct rtnexthop *rtnh;
1586
1587 rta->rta_type = RTA_MULTIPATH;
1588 rta->rta_len = RTA_LENGTH (0);
1589 rtnh = RTA_DATA (rta);
1590
1591 nexthop_num = 0;
1592 for (nexthop = rib->nexthop;
1593 nexthop && (MULTIPATH_NUM == 0 || nexthop_num < MULTIPATH_NUM);
1594 nexthop = nexthop->next)
1595 {
1596 if ((cmd == RTM_NEWROUTE
1597 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1598 || (cmd == RTM_DELROUTE
1599 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1600 {
1601 nexthop_num++;
1602
1603 rtnh->rtnh_len = sizeof (*rtnh);
1604 rtnh->rtnh_flags = 0;
1605 rtnh->rtnh_hops = 0;
1606 rta->rta_len += rtnh->rtnh_len;
1607
1608 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1609 {
1610 if (IS_ZEBRA_DEBUG_KERNEL)
1611 {
1612 zlog_debug ("netlink_route_multipath() "
1613 "(recursive, multihop): %s %s/%d type %s",
1614 lookup (nlmsg_str, cmd), (family == AF_INET) ?
1615 inet_ntoa (p->u.prefix4) : inet6_ntoa (p->u.prefix6),
1616 p->prefixlen, nexthop_types_desc[nexthop->rtype]);
1617 }
1618 if (nexthop->rtype == NEXTHOP_TYPE_IPV4
1619 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
1620 {
1621 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1622 &nexthop->rgate.ipv4, bytelen);
1623 rtnh->rtnh_len += sizeof (struct rtattr) + 4;
1624
1625 if (IS_ZEBRA_DEBUG_KERNEL)
1626 zlog_debug("netlink_route_multipath() (recursive, "
1627 "multihop): nexthop via %s if %u",
1628 inet_ntoa (nexthop->rgate.ipv4),
1629 nexthop->rifindex);
1630 }
1631 #ifdef HAVE_IPV6
1632 if (nexthop->rtype == NEXTHOP_TYPE_IPV6
1633 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
1634 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
1635 {
1636 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1637 &nexthop->rgate.ipv6, bytelen);
1638
1639 if (IS_ZEBRA_DEBUG_KERNEL)
1640 zlog_debug("netlink_route_multipath() (recursive, "
1641 "multihop): nexthop via %s if %u",
1642 inet6_ntoa (nexthop->rgate.ipv6),
1643 nexthop->rifindex);
1644 }
1645 #endif /* HAVE_IPV6 */
1646 /* ifindex */
1647 if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
1648 || nexthop->rtype == NEXTHOP_TYPE_IFNAME
1649 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1650 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1651 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1652 {
1653 rtnh->rtnh_ifindex = nexthop->rifindex;
1654
1655 if (IS_ZEBRA_DEBUG_KERNEL)
1656 zlog_debug("netlink_route_multipath() (recursive, "
1657 "multihop): nexthop via if %u",
1658 nexthop->rifindex);
1659 }
1660 else
1661 {
1662 rtnh->rtnh_ifindex = 0;
1663 }
1664 }
1665 else
1666 {
1667 if (IS_ZEBRA_DEBUG_KERNEL)
1668 {
1669 zlog_debug ("netlink_route_multipath() (multihop): "
1670 "%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1671 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1672 inet6_ntoa (p->u.prefix6), p->prefixlen,
1673 nexthop_types_desc[nexthop->type]);
1674 }
1675 if (nexthop->type == NEXTHOP_TYPE_IPV4
1676 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1677 {
1678 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1679 &nexthop->gate.ipv4, bytelen);
1680 rtnh->rtnh_len += sizeof (struct rtattr) + 4;
1681
1682 if (IS_ZEBRA_DEBUG_KERNEL)
1683 zlog_debug("netlink_route_multipath() (multihop): "
1684 "nexthop via %s if %u",
1685 inet_ntoa (nexthop->gate.ipv4),
1686 nexthop->ifindex);
1687 }
1688 #ifdef HAVE_IPV6
1689 if (nexthop->type == NEXTHOP_TYPE_IPV6
1690 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1691 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1692 {
1693 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1694 &nexthop->gate.ipv6, bytelen);
1695
1696 if (IS_ZEBRA_DEBUG_KERNEL)
1697 zlog_debug("netlink_route_multipath() (multihop): "
1698 "nexthop via %s if %u",
1699 inet6_ntoa (nexthop->gate.ipv6),
1700 nexthop->ifindex);
1701 }
1702 #endif /* HAVE_IPV6 */
1703 /* ifindex */
1704 if (nexthop->type == NEXTHOP_TYPE_IFINDEX
1705 || nexthop->type == NEXTHOP_TYPE_IFNAME
1706 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
1707 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1708 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1709 {
1710 rtnh->rtnh_ifindex = nexthop->ifindex;
1711
1712 if (IS_ZEBRA_DEBUG_KERNEL)
1713 zlog_debug("netlink_route_multipath() (multihop): "
1714 "nexthop via if %u", nexthop->ifindex);
1715 }
1716 else
1717 {
1718 rtnh->rtnh_ifindex = 0;
1719 }
1720 }
1721 rtnh = RTNH_NEXT (rtnh);
1722
1723 if (cmd == RTM_NEWROUTE)
1724 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1725 }
1726 }
1727
1728 if (rta->rta_len > RTA_LENGTH (0))
1729 addattr_l (&req.n, 1024, RTA_MULTIPATH, RTA_DATA (rta),
1730 RTA_PAYLOAD (rta));
1731 }
1732
1733 /* If there is no useful nexthop then return. */
1734 if (nexthop_num == 0)
1735 {
1736 if (IS_ZEBRA_DEBUG_KERNEL)
1737 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1738 return 0;
1739 }
1740
1741 skip:
1742
1743 /* Destination netlink address. */
1744 memset (&snl, 0, sizeof snl);
1745 snl.nl_family = AF_NETLINK;
1746
1747 /* Talk to netlink socket. */
1748 return netlink_talk (&req.n, &netlink_cmd);
1749 }
1750
1751 int
1752 kernel_add_ipv4 (struct prefix *p, struct rib *rib)
1753 {
1754 return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET);
1755 }
1756
1757 int
1758 kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
1759 {
1760 return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET);
1761 }
1762
1763 #ifdef HAVE_IPV6
1764 int
1765 kernel_add_ipv6 (struct prefix *p, struct rib *rib)
1766 {
1767 return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6);
1768 }
1769
1770 int
1771 kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
1772 {
1773 return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6);
1774 }
1775
1776 /* Delete IPv6 route from the kernel. */
1777 int
1778 kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
1779 int index, int flags, int table)
1780 {
1781 return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix,
1782 dest->prefixlen, gate, index, flags, table);
1783 }
1784 #endif /* HAVE_IPV6 */
1785 \f
1786 /* Interface address modification. */
1787 int
1788 netlink_address (int cmd, int family, struct interface *ifp,
1789 struct connected *ifc)
1790 {
1791 int bytelen;
1792 struct prefix *p;
1793
1794 struct
1795 {
1796 struct nlmsghdr n;
1797 struct ifaddrmsg ifa;
1798 char buf[1024];
1799 } req;
1800
1801 p = ifc->address;
1802 memset (&req, 0, sizeof req);
1803
1804 bytelen = (family == AF_INET ? 4 : 16);
1805
1806 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
1807 req.n.nlmsg_flags = NLM_F_REQUEST;
1808 req.n.nlmsg_type = cmd;
1809 req.ifa.ifa_family = family;
1810
1811 req.ifa.ifa_index = ifp->ifindex;
1812 req.ifa.ifa_prefixlen = p->prefixlen;
1813
1814 addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
1815
1816 if (family == AF_INET && cmd == RTM_NEWADDR)
1817 {
1818 if (if_is_broadcast (ifp) && ifc->destination)
1819 {
1820 p = ifc->destination;
1821 addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
1822 bytelen);
1823 }
1824 }
1825
1826 if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
1827 SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
1828
1829 if (ifc->label)
1830 addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
1831 strlen (ifc->label) + 1);
1832
1833 return netlink_talk (&req.n, &netlink_cmd);
1834 }
1835
1836 int
1837 kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
1838 {
1839 return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
1840 }
1841
1842 int
1843 kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
1844 {
1845 return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
1846 }
1847
1848
1849 extern struct thread_master *master;
1850
1851 /* Kernel route reflection. */
1852 int
1853 kernel_read (struct thread *thread)
1854 {
1855 int ret;
1856 int sock;
1857
1858 sock = THREAD_FD (thread);
1859 ret = netlink_parse_info (netlink_information_fetch, &netlink);
1860 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
1861
1862 return 0;
1863 }
1864
1865 /* Exported interface function. This function simply calls
1866 netlink_socket (). */
1867 void
1868 kernel_init ()
1869 {
1870 unsigned long groups;
1871
1872 groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
1873 #ifdef HAVE_IPV6
1874 groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
1875 #endif /* HAVE_IPV6 */
1876 netlink_socket (&netlink, groups);
1877 netlink_socket (&netlink_cmd, 0);
1878
1879 /* Register kernel socket. */
1880 if (netlink.sock > 0)
1881 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
1882 }