+ sayonara old_pid!
[jleu-quagga.git] / zebra / rt_netlink.c
blob5b592f948a23b2468bedfd44f1f409fb08ee5488
1 /* Kernel routing table updates using netlink over GNU/Linux system.
2 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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.
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.
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.
22 #include <zebra.h>
24 /* Hack for GNU libc version 2. */
25 #ifndef MSG_TRUNC
26 #define MSG_TRUNC 0x20
27 #endif /* MSG_TRUNC */
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"
39 #include "zebra/zserv.h"
40 #include "zebra/rt.h"
41 #include "zebra/redistribute.h"
42 #include "zebra/interface.h"
43 #include "zebra/debug.h"
45 /* Socket interface to kernel */
46 struct nlsock
48 int sock;
49 int seq;
50 struct sockaddr_nl snl;
51 const char *name;
52 } netlink = { -1, 0, {0}, "netlink-listen"}, /* kernel messages */
53 netlink_cmd = { -1, 0, {0}, "netlink-cmd"}; /* command channel */
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}
68 const char *nexthop_types_desc[] =
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",
83 extern struct zebra_t zebrad;
85 extern struct zebra_privs_t zserv_privs;
87 extern u_int32_t nl_rcvbufsize;
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)
94 struct interface *oifp;
96 if (((oifp = if_lookup_by_index(ifi_index)) != NULL) && (oifp != ifp))
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
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);
113 ifp->ifindex = ifi_index;
116 /* Make socket for Linux netlink interface. */
117 static int
118 netlink_socket (struct nlsock *nl, unsigned long groups)
120 int ret;
121 struct sockaddr_nl snl;
122 int sock;
123 int namelen;
124 int save_errno;
126 sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
127 if (sock < 0)
129 zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
130 safe_strerror (errno));
131 return -1;
134 ret = fcntl (sock, F_SETFL, O_NONBLOCK);
135 if (ret < 0)
137 zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
138 safe_strerror (errno));
139 close (sock);
140 return -1;
143 /* Set receive buffer size if it's set from command line */
144 if (nl_rcvbufsize)
146 u_int32_t oldsize, oldlen;
147 u_int32_t newsize, newlen;
149 oldlen = sizeof(oldsize);
150 newlen = sizeof(newsize);
152 ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &oldsize, &oldlen);
153 if (ret < 0)
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;
161 ret = setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &nl_rcvbufsize,
162 sizeof(nl_rcvbufsize));
163 if (ret < 0)
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;
171 ret = getsockopt(sock, SOL_SOCKET, SO_RCVBUF, &newsize, &newlen);
172 if (ret < 0)
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;
180 zlog (NULL, LOG_INFO,
181 "Setting netlink socket receive buffer size: %u -> %u",
182 oldsize, newsize);
185 memset (&snl, 0, sizeof snl);
186 snl.nl_family = AF_NETLINK;
187 snl.nl_groups = groups;
189 /* Bind the socket to the netlink structure for anything. */
190 if (zserv_privs.change (ZPRIVS_RAISE))
192 zlog (NULL, LOG_ERR, "Can't raise privileges");
193 return -1;
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");
201 if (ret < 0)
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;
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)
214 zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
215 safe_strerror (errno));
216 close (sock);
217 return -1;
220 nl->snl = snl;
221 nl->sock = sock;
222 return ret;
226 set_netlink_blocking (struct nlsock *nl, int *flags)
229 /* Change socket flags for blocking I/O. */
230 if ((*flags = fcntl (nl->sock, F_GETFL, 0)) < 0)
232 zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s",
233 __FUNCTION__, __LINE__, safe_strerror (errno));
234 return -1;
236 *flags &= ~O_NONBLOCK;
237 if (fcntl (nl->sock, F_SETFL, *flags) < 0)
239 zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
240 __FUNCTION__, __LINE__, safe_strerror (errno));
241 return -1;
243 return 0;
247 set_netlink_nonblocking (struct nlsock *nl, int *flags)
249 /* Restore socket flags for nonblocking I/O */
250 *flags |= O_NONBLOCK;
251 if (fcntl (nl->sock, F_SETFL, *flags) < 0)
253 zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s",
254 __FUNCTION__, __LINE__, safe_strerror (errno));
255 return -1;
257 return 0;
260 /* Get type specified information from netlink. */
261 static int
262 netlink_request (int family, int type, struct nlsock *nl)
264 int ret;
265 struct sockaddr_nl snl;
266 int save_errno;
268 struct
270 struct nlmsghdr nlh;
271 struct rtgenmsg g;
272 } req;
275 /* Check netlink socket. */
276 if (nl->sock < 0)
278 zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
279 return -1;
282 memset (&snl, 0, sizeof snl);
283 snl.nl_family = AF_NETLINK;
285 memset (&req, 0, sizeof req);
286 req.nlh.nlmsg_len = sizeof req;
287 req.nlh.nlmsg_type = type;
288 req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
289 req.nlh.nlmsg_pid = 0;
290 req.nlh.nlmsg_seq = ++nl->seq;
291 req.g.rtgen_family = family;
293 /* linux appears to check capabilities on every message
294 * have to raise caps for every message sent
296 if (zserv_privs.change (ZPRIVS_RAISE))
298 zlog (NULL, LOG_ERR, "Can't raise privileges");
299 return -1;
302 ret = sendto (nl->sock, (void *) &req, sizeof req, 0,
303 (struct sockaddr *) &snl, sizeof snl);
304 save_errno = errno;
306 if (zserv_privs.change (ZPRIVS_LOWER))
307 zlog (NULL, LOG_ERR, "Can't lower privileges");
309 if (ret < 0)
311 zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name,
312 safe_strerror (save_errno));
313 return -1;
316 return 0;
319 /* Receive message from netlink interface and pass those information
320 to the given function. */
321 static int
322 netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
323 struct nlsock *nl)
325 int status;
326 int ret = 0;
327 int error;
329 while (1)
331 char buf[4096];
332 struct iovec iov = { buf, sizeof buf };
333 struct sockaddr_nl snl;
334 struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
335 struct nlmsghdr *h;
336 int save_errno;
338 if (zserv_privs.change (ZPRIVS_RAISE))
339 zlog (NULL, LOG_ERR, "Can't raise privileges");
341 status = recvmsg (nl->sock, &msg, 0);
342 save_errno = errno;
344 if (zserv_privs.change (ZPRIVS_LOWER))
345 zlog (NULL, LOG_ERR, "Can't lower privileges");
347 if (status < 0)
349 if (save_errno == EINTR)
350 continue;
351 if (save_errno == EWOULDBLOCK || save_errno == EAGAIN)
352 break;
353 zlog (NULL, LOG_ERR, "%s recvmsg overrun: %s",
354 nl->name, safe_strerror(save_errno));
355 continue;
358 if (status == 0)
360 zlog (NULL, LOG_ERR, "%s EOF", nl->name);
361 return -1;
364 if (msg.msg_namelen != sizeof snl)
366 zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
367 nl->name, msg.msg_namelen);
368 return -1;
371 /* JF: Ignore messages that aren't from the kernel */
372 if ( snl.nl_pid != 0 )
374 zlog ( NULL, LOG_ERR, "Ignoring message from pid %u", snl.nl_pid );
375 continue;
378 for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, (unsigned int) status);
379 h = NLMSG_NEXT (h, status))
381 /* Finish of reading. */
382 if (h->nlmsg_type == NLMSG_DONE)
383 return ret;
385 /* Error handling. */
386 if (h->nlmsg_type == NLMSG_ERROR)
388 struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
390 /* If the error field is zero, then this is an ACK */
391 if (err->error == 0)
393 if (IS_ZEBRA_DEBUG_KERNEL)
395 zlog_debug ("%s: %s ACK: type=%s(%u), seq=%u, pid=%u",
396 __FUNCTION__, nl->name,
397 lookup (nlmsg_str, err->msg.nlmsg_type),
398 err->msg.nlmsg_type, err->msg.nlmsg_seq,
399 err->msg.nlmsg_pid);
402 /* return if not a multipart message, otherwise continue */
403 if (!(h->nlmsg_flags & NLM_F_MULTI))
405 return 0;
407 continue;
410 if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
412 zlog (NULL, LOG_ERR, "%s error: message truncated",
413 nl->name);
414 return -1;
417 /* Deal with Error Noise - MAG */
419 int loglvl = LOG_ERR;
420 int errnum = err->error;
421 int msg_type = err->msg.nlmsg_type;
423 if (nl == &netlink_cmd
424 && (-errnum == ENODEV || -errnum == ESRCH)
425 && (msg_type == RTM_NEWROUTE || msg_type == RTM_DELROUTE))
426 loglvl = LOG_DEBUG;
428 zlog (NULL, loglvl, "%s error: %s, type=%s(%u), "
429 "seq=%u, pid=%u",
430 nl->name, safe_strerror (-errnum),
431 lookup (nlmsg_str, msg_type),
432 msg_type, err->msg.nlmsg_seq, err->msg.nlmsg_pid);
435 ret = -1;
436 continue;
438 return -1;
441 /* OK we got netlink message. */
442 if (IS_ZEBRA_DEBUG_KERNEL)
443 zlog_debug ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%u",
444 nl->name,
445 lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
446 h->nlmsg_seq, h->nlmsg_pid);
448 /* skip unsolicited messages originating from command socket */
449 if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
451 if (IS_ZEBRA_DEBUG_KERNEL)
452 zlog_debug ("netlink_parse_info: %s packet comes from %s",
453 netlink_cmd.name, nl->name);
454 continue;
457 error = (*filter) (&snl, h);
458 if (error < 0)
460 zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
461 ret = error;
465 /* After error care. */
466 if (msg.msg_flags & MSG_TRUNC)
468 zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
469 continue;
471 if (status)
473 zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
474 status);
475 return -1;
478 return ret;
481 /* Utility function for parse rtattr. */
482 static void
483 netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta,
484 int len)
486 while (RTA_OK (rta, len))
488 if (rta->rta_type <= max)
489 tb[rta->rta_type] = rta;
490 rta = RTA_NEXT (rta, len);
494 /* Called from interface_lookup_netlink(). This function is only used
495 during bootstrap. */
497 netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
499 int len;
500 struct ifinfomsg *ifi;
501 struct rtattr *tb[IFLA_MAX + 1];
502 struct interface *ifp;
503 char *name;
504 int i;
506 ifi = NLMSG_DATA (h);
508 if (h->nlmsg_type != RTM_NEWLINK)
509 return 0;
511 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
512 if (len < 0)
513 return -1;
515 /* Looking up interface name. */
516 memset (tb, 0, sizeof tb);
517 netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
519 #ifdef IFLA_WIRELESS
520 /* check for wireless messages to ignore */
521 if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
523 if (IS_ZEBRA_DEBUG_KERNEL)
524 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
525 return 0;
527 #endif /* IFLA_WIRELESS */
529 if (tb[IFLA_IFNAME] == NULL)
530 return -1;
531 name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
533 /* Add interface. */
534 ifp = if_get_by_name (name);
535 set_ifindex(ifp, ifi->ifi_index);
536 ifp->flags = ifi->ifi_flags & 0x0000fffff;
537 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
538 ifp->metric = 1;
540 /* Hardware type and address. */
541 ifp->hw_type = ifi->ifi_type;
543 if (tb[IFLA_ADDRESS])
545 int hw_addr_len;
547 hw_addr_len = RTA_PAYLOAD (tb[IFLA_ADDRESS]);
549 if (hw_addr_len > INTERFACE_HWADDR_MAX)
550 zlog_warn ("Hardware address is too large: %d", hw_addr_len);
551 else
553 ifp->hw_addr_len = hw_addr_len;
554 memcpy (ifp->hw_addr, RTA_DATA (tb[IFLA_ADDRESS]), hw_addr_len);
556 for (i = 0; i < hw_addr_len; i++)
557 if (ifp->hw_addr[i] != 0)
558 break;
560 if (i == hw_addr_len)
561 ifp->hw_addr_len = 0;
562 else
563 ifp->hw_addr_len = hw_addr_len;
567 if_add_update (ifp);
569 return 0;
572 /* Lookup interface IPv4/IPv6 address. */
574 netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
576 int len;
577 struct ifaddrmsg *ifa;
578 struct rtattr *tb[IFA_MAX + 1];
579 struct interface *ifp;
580 void *addr;
581 void *broad;
582 u_char flags = 0;
583 char *label = NULL;
585 ifa = NLMSG_DATA (h);
587 if (ifa->ifa_family != AF_INET
588 #ifdef HAVE_IPV6
589 && ifa->ifa_family != AF_INET6
590 #endif /* HAVE_IPV6 */
592 return 0;
594 if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
595 return 0;
597 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifaddrmsg));
598 if (len < 0)
599 return -1;
601 memset (tb, 0, sizeof tb);
602 netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
604 ifp = if_lookup_by_index (ifa->ifa_index);
605 if (ifp == NULL)
607 zlog_err ("netlink_interface_addr can't find interface by index %d",
608 ifa->ifa_index);
609 return -1;
612 if (IS_ZEBRA_DEBUG_KERNEL) /* remove this line to see initial ifcfg */
614 char buf[BUFSIZ];
615 zlog_debug ("netlink_interface_addr %s %s:",
616 lookup (nlmsg_str, h->nlmsg_type), ifp->name);
617 if (tb[IFA_LOCAL])
618 zlog_debug (" IFA_LOCAL %s/%d",
619 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_LOCAL]),
620 buf, BUFSIZ), ifa->ifa_prefixlen);
621 if (tb[IFA_ADDRESS])
622 zlog_debug (" IFA_ADDRESS %s/%d",
623 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_ADDRESS]),
624 buf, BUFSIZ), ifa->ifa_prefixlen);
625 if (tb[IFA_BROADCAST])
626 zlog_debug (" IFA_BROADCAST %s/%d",
627 inet_ntop (ifa->ifa_family, RTA_DATA (tb[IFA_BROADCAST]),
628 buf, BUFSIZ), ifa->ifa_prefixlen);
629 if (tb[IFA_LABEL] && strcmp (ifp->name, RTA_DATA (tb[IFA_LABEL])))
630 zlog_debug (" IFA_LABEL %s", (char *)RTA_DATA (tb[IFA_LABEL]));
632 if (tb[IFA_CACHEINFO])
634 struct ifa_cacheinfo *ci = RTA_DATA (tb[IFA_CACHEINFO]);
635 zlog_debug (" IFA_CACHEINFO pref %d, valid %d",
636 ci->ifa_prefered, ci->ifa_valid);
640 /* logic copied from iproute2/ip/ipaddress.c:print_addrinfo() */
641 if (tb[IFA_LOCAL] == NULL)
642 tb[IFA_LOCAL] = tb[IFA_ADDRESS];
643 if (tb[IFA_ADDRESS] == NULL)
644 tb[IFA_ADDRESS] = tb[IFA_LOCAL];
646 /* local interface address */
647 addr = (tb[IFA_LOCAL] ? RTA_DATA(tb[IFA_LOCAL]) : NULL);
649 /* is there a peer address? */
650 if (tb[IFA_ADDRESS] &&
651 memcmp(RTA_DATA(tb[IFA_ADDRESS]), RTA_DATA(tb[IFA_LOCAL]), RTA_PAYLOAD(tb[IFA_ADDRESS])))
653 broad = RTA_DATA(tb[IFA_ADDRESS]);
654 SET_FLAG (flags, ZEBRA_IFA_PEER);
656 else
657 /* seeking a broadcast address */
658 broad = (tb[IFA_BROADCAST] ? RTA_DATA(tb[IFA_BROADCAST]) : NULL);
660 /* addr is primary key, SOL if we don't have one */
661 if (addr == NULL)
663 zlog_debug ("%s: NULL address", __func__);
664 return -1;
667 /* Flags. */
668 if (ifa->ifa_flags & IFA_F_SECONDARY)
669 SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
671 /* Label */
672 if (tb[IFA_LABEL])
673 label = (char *) RTA_DATA (tb[IFA_LABEL]);
675 if (ifp && label && strcmp (ifp->name, label) == 0)
676 label = NULL;
678 /* Register interface address to the interface. */
679 if (ifa->ifa_family == AF_INET)
681 if (h->nlmsg_type == RTM_NEWADDR)
682 connected_add_ipv4 (ifp, flags,
683 (struct in_addr *) addr, ifa->ifa_prefixlen,
684 (struct in_addr *) broad, label);
685 else
686 connected_delete_ipv4 (ifp, flags,
687 (struct in_addr *) addr, ifa->ifa_prefixlen,
688 (struct in_addr *) broad);
690 #ifdef HAVE_IPV6
691 if (ifa->ifa_family == AF_INET6)
693 if (h->nlmsg_type == RTM_NEWADDR)
694 connected_add_ipv6 (ifp, flags,
695 (struct in6_addr *) addr, ifa->ifa_prefixlen,
696 (struct in6_addr *) broad, label);
697 else
698 connected_delete_ipv6 (ifp,
699 (struct in6_addr *) addr, ifa->ifa_prefixlen,
700 (struct in6_addr *) broad);
702 #endif /* HAVE_IPV6 */
704 return 0;
707 /* Looking up routing table by netlink interface. */
709 netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
711 int len;
712 struct rtmsg *rtm;
713 struct rtattr *tb[RTA_MAX + 1];
714 u_char flags = 0;
716 char anyaddr[16] = { 0 };
718 int index;
719 int table;
720 int metric;
722 void *dest;
723 void *gate;
724 void *src;
726 rtm = NLMSG_DATA (h);
728 if (h->nlmsg_type != RTM_NEWROUTE)
729 return 0;
730 if (rtm->rtm_type != RTN_UNICAST)
731 return 0;
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
739 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
740 if (len < 0)
741 return -1;
743 memset (tb, 0, sizeof tb);
744 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
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;
753 if (rtm->rtm_src_len != 0)
754 return 0;
756 /* Route which inserted by Zebra. */
757 if (rtm->rtm_protocol == RTPROT_ZEBRA)
758 flags |= ZEBRA_FLAG_SELFROUTE;
760 index = 0;
761 metric = 0;
762 dest = NULL;
763 gate = NULL;
764 src = NULL;
766 if (tb[RTA_OIF])
767 index = *(int *) RTA_DATA (tb[RTA_OIF]);
769 if (tb[RTA_DST])
770 dest = RTA_DATA (tb[RTA_DST]);
771 else
772 dest = anyaddr;
774 if (tb[RTA_PREFSRC])
775 src = RTA_DATA (tb[RTA_PREFSRC]);
777 /* Multipath treatment is needed. */
778 if (tb[RTA_GATEWAY])
779 gate = RTA_DATA (tb[RTA_GATEWAY]);
781 if (tb[RTA_PRIORITY])
782 metric = *(int *) RTA_DATA(tb[RTA_PRIORITY]);
784 if (rtm->rtm_family == AF_INET)
786 struct prefix_ipv4 p;
787 p.family = AF_INET;
788 memcpy (&p.prefix, dest, 4);
789 p.prefixlen = rtm->rtm_dst_len;
791 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, src, index, table, metric, 0);
793 #ifdef HAVE_IPV6
794 if (rtm->rtm_family == AF_INET6)
796 struct prefix_ipv6 p;
797 p.family = AF_INET6;
798 memcpy (&p.prefix, dest, 16);
799 p.prefixlen = rtm->rtm_dst_len;
801 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table,
802 metric, 0);
804 #endif /* HAVE_IPV6 */
806 return 0;
809 struct message rtproto_str[] = {
810 {RTPROT_REDIRECT, "redirect"},
811 {RTPROT_KERNEL, "kernel"},
812 {RTPROT_BOOT, "boot"},
813 {RTPROT_STATIC, "static"},
814 {RTPROT_GATED, "GateD"},
815 {RTPROT_RA, "router advertisement"},
816 {RTPROT_MRT, "MRT"},
817 {RTPROT_ZEBRA, "Zebra"},
818 #ifdef RTPROT_BIRD
819 {RTPROT_BIRD, "BIRD"},
820 #endif /* RTPROT_BIRD */
821 {0, NULL}
824 /* Routing information change from the kernel. */
826 netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
828 int len;
829 struct rtmsg *rtm;
830 struct rtattr *tb[RTA_MAX + 1];
832 char anyaddr[16] = { 0 };
834 int index;
835 int table;
836 void *dest;
837 void *gate;
838 void *src;
840 rtm = NLMSG_DATA (h);
842 if (!(h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
844 /* If this is not route add/delete message print warning. */
845 zlog_warn ("Kernel message: %d\n", h->nlmsg_type);
846 return 0;
849 /* Connected route. */
850 if (IS_ZEBRA_DEBUG_KERNEL)
851 zlog_debug ("%s %s %s proto %s",
852 h->nlmsg_type ==
853 RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
854 rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
855 rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
856 lookup (rtproto_str, rtm->rtm_protocol));
858 if (rtm->rtm_type != RTN_UNICAST)
860 return 0;
863 table = rtm->rtm_table;
864 if (table != RT_TABLE_MAIN && table != zebrad.rtm_table_default)
866 return 0;
869 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct rtmsg));
870 if (len < 0)
871 return -1;
873 memset (tb, 0, sizeof tb);
874 netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
876 if (rtm->rtm_flags & RTM_F_CLONED)
877 return 0;
878 if (rtm->rtm_protocol == RTPROT_REDIRECT)
879 return 0;
880 if (rtm->rtm_protocol == RTPROT_KERNEL)
881 return 0;
883 if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
884 return 0;
886 if (rtm->rtm_src_len != 0)
888 zlog_warn ("netlink_route_change(): no src len");
889 return 0;
892 index = 0;
893 dest = NULL;
894 gate = NULL;
895 src = NULL;
897 if (tb[RTA_OIF])
898 index = *(int *) RTA_DATA (tb[RTA_OIF]);
900 if (tb[RTA_DST])
901 dest = RTA_DATA (tb[RTA_DST]);
902 else
903 dest = anyaddr;
905 if (tb[RTA_GATEWAY])
906 gate = RTA_DATA (tb[RTA_GATEWAY]);
908 if (tb[RTA_PREFSRC])
909 src = RTA_DATA (tb[RTA_PREFSRC]);
911 if (rtm->rtm_family == AF_INET)
913 struct prefix_ipv4 p;
914 p.family = AF_INET;
915 memcpy (&p.prefix, dest, 4);
916 p.prefixlen = rtm->rtm_dst_len;
918 if (IS_ZEBRA_DEBUG_KERNEL)
920 if (h->nlmsg_type == RTM_NEWROUTE)
921 zlog_debug ("RTM_NEWROUTE %s/%d",
922 inet_ntoa (p.prefix), p.prefixlen);
923 else
924 zlog_debug ("RTM_DELROUTE %s/%d",
925 inet_ntoa (p.prefix), p.prefixlen);
928 if (h->nlmsg_type == RTM_NEWROUTE)
929 rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, src, index, table, 0, 0);
930 else
931 rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
934 #ifdef HAVE_IPV6
935 if (rtm->rtm_family == AF_INET6)
937 struct prefix_ipv6 p;
938 char buf[BUFSIZ];
940 p.family = AF_INET6;
941 memcpy (&p.prefix, dest, 16);
942 p.prefixlen = rtm->rtm_dst_len;
944 if (IS_ZEBRA_DEBUG_KERNEL)
946 if (h->nlmsg_type == RTM_NEWROUTE)
947 zlog_debug ("RTM_NEWROUTE %s/%d",
948 inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
949 p.prefixlen);
950 else
951 zlog_debug ("RTM_DELROUTE %s/%d",
952 inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
953 p.prefixlen);
956 if (h->nlmsg_type == RTM_NEWROUTE)
957 rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0, 0, 0);
958 else
959 rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
961 #endif /* HAVE_IPV6 */
963 return 0;
967 netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
969 int len;
970 struct ifinfomsg *ifi;
971 struct rtattr *tb[IFLA_MAX + 1];
972 struct interface *ifp;
973 char *name;
975 ifi = NLMSG_DATA (h);
977 if (!(h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
979 /* If this is not link add/delete message so print warning. */
980 zlog_warn ("netlink_link_change: wrong kernel message %d\n",
981 h->nlmsg_type);
982 return 0;
985 len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
986 if (len < 0)
987 return -1;
989 /* Looking up interface name. */
990 memset (tb, 0, sizeof tb);
991 netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
993 #ifdef IFLA_WIRELESS
994 /* check for wireless messages to ignore */
995 if ((tb[IFLA_WIRELESS] != NULL) && (ifi->ifi_change == 0))
997 if (IS_ZEBRA_DEBUG_KERNEL)
998 zlog_debug ("%s: ignoring IFLA_WIRELESS message", __func__);
999 return 0;
1001 #endif /* IFLA_WIRELESS */
1003 if (tb[IFLA_IFNAME] == NULL)
1004 return -1;
1005 name = (char *) RTA_DATA (tb[IFLA_IFNAME]);
1007 /* Add interface. */
1008 if (h->nlmsg_type == RTM_NEWLINK)
1010 ifp = if_lookup_by_name (name);
1012 if (ifp == NULL || !CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
1014 if (ifp == NULL)
1015 ifp = if_get_by_name (name);
1017 set_ifindex(ifp, ifi->ifi_index);
1018 ifp->flags = ifi->ifi_flags & 0x0000fffff;
1019 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
1020 ifp->metric = 1;
1022 /* If new link is added. */
1023 if_add_update (ifp);
1025 else
1027 /* Interface status change. */
1028 set_ifindex(ifp, ifi->ifi_index);
1029 ifp->mtu6 = ifp->mtu = *(int *) RTA_DATA (tb[IFLA_MTU]);
1030 ifp->metric = 1;
1032 if (if_is_operative (ifp))
1034 ifp->flags = ifi->ifi_flags & 0x0000fffff;
1035 if (!if_is_operative (ifp))
1036 if_down (ifp);
1037 else
1038 /* Must notify client daemons of new interface status. */
1039 zebra_interface_up_update (ifp);
1041 else
1043 ifp->flags = ifi->ifi_flags & 0x0000fffff;
1044 if (if_is_operative (ifp))
1045 if_up (ifp);
1049 else
1051 /* RTM_DELLINK. */
1052 ifp = if_lookup_by_name (name);
1054 if (ifp == NULL)
1056 zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
1057 name);
1058 return 0;
1061 if_delete_update (ifp);
1064 return 0;
1068 netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
1070 switch (h->nlmsg_type)
1072 case RTM_NEWROUTE:
1073 return netlink_route_change (snl, h);
1074 break;
1075 case RTM_DELROUTE:
1076 return netlink_route_change (snl, h);
1077 break;
1078 case RTM_NEWLINK:
1079 return netlink_link_change (snl, h);
1080 break;
1081 case RTM_DELLINK:
1082 return netlink_link_change (snl, h);
1083 break;
1084 case RTM_NEWADDR:
1085 return netlink_interface_addr (snl, h);
1086 break;
1087 case RTM_DELADDR:
1088 return netlink_interface_addr (snl, h);
1089 break;
1090 default:
1091 zlog_warn ("Unknown netlink nlmsg_type %d\n", h->nlmsg_type);
1092 break;
1094 return 0;
1097 /* Interface lookup by netlink socket. */
1099 interface_lookup_netlink (void)
1101 int ret;
1102 int flags;
1103 int snb_ret;
1106 * Change netlink socket flags to blocking to ensure we get
1107 * a reply via nelink_parse_info
1109 snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
1110 if (snb_ret < 0)
1111 zlog (NULL, LOG_WARNING,
1112 "%s:%i Warning: Could not set netlink socket to blocking.",
1113 __FUNCTION__, __LINE__);
1115 /* Get interface information. */
1116 ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
1117 if (ret < 0)
1118 return ret;
1119 ret = netlink_parse_info (netlink_interface, &netlink_cmd);
1120 if (ret < 0)
1121 return ret;
1123 /* Get IPv4 address of the interfaces. */
1124 ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
1125 if (ret < 0)
1126 return ret;
1127 ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
1128 if (ret < 0)
1129 return ret;
1131 #ifdef HAVE_IPV6
1132 /* Get IPv6 address of the interfaces. */
1133 ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
1134 if (ret < 0)
1135 return ret;
1136 ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
1137 if (ret < 0)
1138 return ret;
1139 #endif /* HAVE_IPV6 */
1141 /* restore socket flags */
1142 if (snb_ret == 0)
1143 set_netlink_nonblocking (&netlink_cmd, &flags);
1144 return 0;
1147 /* Routing table read function using netlink interface. Only called
1148 bootstrap time. */
1150 netlink_route_read (void)
1152 int ret;
1153 int flags;
1154 int snb_ret;
1157 * Change netlink socket flags to blocking to ensure we get
1158 * a reply via nelink_parse_info
1160 snb_ret = set_netlink_blocking (&netlink_cmd, &flags);
1161 if (snb_ret < 0)
1162 zlog (NULL, LOG_WARNING,
1163 "%s:%i Warning: Could not set netlink socket to blocking.",
1164 __FUNCTION__, __LINE__);
1166 /* Get IPv4 routing table. */
1167 ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
1168 if (ret < 0)
1169 return ret;
1170 ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
1171 if (ret < 0)
1172 return ret;
1174 #ifdef HAVE_IPV6
1175 /* Get IPv6 routing table. */
1176 ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
1177 if (ret < 0)
1178 return ret;
1179 ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
1180 if (ret < 0)
1181 return ret;
1182 #endif /* HAVE_IPV6 */
1184 /* restore flags */
1185 if (snb_ret == 0)
1186 set_netlink_nonblocking (&netlink_cmd, &flags);
1187 return 0;
1190 /* Utility function comes from iproute2.
1191 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1193 addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
1195 int len;
1196 struct rtattr *rta;
1198 len = RTA_LENGTH (alen);
1200 if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
1201 return -1;
1203 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
1204 rta->rta_type = type;
1205 rta->rta_len = len;
1206 memcpy (RTA_DATA (rta), data, alen);
1207 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
1209 return 0;
1213 rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
1215 int len;
1216 struct rtattr *subrta;
1218 len = RTA_LENGTH (alen);
1220 if (RTA_ALIGN (rta->rta_len) + len > maxlen)
1221 return -1;
1223 subrta = (struct rtattr *) (((char *) rta) + RTA_ALIGN (rta->rta_len));
1224 subrta->rta_type = type;
1225 subrta->rta_len = len;
1226 memcpy (RTA_DATA (subrta), data, alen);
1227 rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
1229 return 0;
1232 /* Utility function comes from iproute2.
1233 Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
1235 addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
1237 int len;
1238 struct rtattr *rta;
1240 len = RTA_LENGTH (4);
1242 if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
1243 return -1;
1245 rta = (struct rtattr *) (((char *) n) + NLMSG_ALIGN (n->nlmsg_len));
1246 rta->rta_type = type;
1247 rta->rta_len = len;
1248 memcpy (RTA_DATA (rta), &data, 4);
1249 n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
1251 return 0;
1254 static int
1255 netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
1257 zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
1258 return 0;
1261 /* sendmsg() to netlink socket then recvmsg(). */
1263 netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
1265 int status;
1266 struct sockaddr_nl snl;
1267 struct iovec iov = { (void *) n, n->nlmsg_len };
1268 struct msghdr msg = { (void *) &snl, sizeof snl, &iov, 1, NULL, 0, 0 };
1269 int flags = 0;
1270 int snb_ret;
1271 int save_errno;
1273 memset (&snl, 0, sizeof snl);
1274 snl.nl_family = AF_NETLINK;
1276 n->nlmsg_seq = ++nl->seq;
1278 /* Request an acknowledgement by setting NLM_F_ACK */
1279 n->nlmsg_flags |= NLM_F_ACK;
1281 if (IS_ZEBRA_DEBUG_KERNEL)
1282 zlog_debug ("netlink_talk: %s type %s(%u), seq=%u", nl->name,
1283 lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
1284 n->nlmsg_seq);
1286 /* Send message to netlink interface. */
1287 if (zserv_privs.change (ZPRIVS_RAISE))
1288 zlog (NULL, LOG_ERR, "Can't raise privileges");
1289 status = sendmsg (nl->sock, &msg, 0);
1290 save_errno = errno;
1291 if (zserv_privs.change (ZPRIVS_LOWER))
1292 zlog (NULL, LOG_ERR, "Can't lower privileges");
1294 if (status < 0)
1296 zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
1297 safe_strerror (save_errno));
1298 return -1;
1302 * Change socket flags for blocking I/O.
1303 * This ensures we wait for a reply in netlink_parse_info().
1305 snb_ret = set_netlink_blocking (nl, &flags);
1306 if (snb_ret < 0)
1307 zlog (NULL, LOG_WARNING,
1308 "%s:%i Warning: Could not set netlink socket to blocking.",
1309 __FUNCTION__, __LINE__);
1312 * Get reply from netlink socket.
1313 * The reply should either be an acknowlegement or an error.
1315 status = netlink_parse_info (netlink_talk_filter, nl);
1317 /* Restore socket flags for nonblocking I/O */
1318 if (snb_ret == 0)
1319 set_netlink_nonblocking (nl, &flags);
1321 return status;
1324 /* Routing table change via netlink interface. */
1326 netlink_route (int cmd, int family, void *dest, int length, void *gate,
1327 int index, int zebra_flags, int table)
1329 int ret;
1330 int bytelen;
1331 struct sockaddr_nl snl;
1332 int discard;
1334 struct
1336 struct nlmsghdr n;
1337 struct rtmsg r;
1338 char buf[1024];
1339 } req;
1341 memset (&req, 0, sizeof req);
1343 bytelen = (family == AF_INET ? 4 : 16);
1345 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1346 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1347 req.n.nlmsg_type = cmd;
1348 req.r.rtm_family = family;
1349 req.r.rtm_table = table;
1350 req.r.rtm_dst_len = length;
1352 if ((zebra_flags & ZEBRA_FLAG_BLACKHOLE)
1353 || (zebra_flags & ZEBRA_FLAG_REJECT))
1354 discard = 1;
1355 else
1356 discard = 0;
1358 if (cmd == RTM_NEWROUTE)
1360 req.r.rtm_protocol = RTPROT_ZEBRA;
1361 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1363 if (discard)
1365 if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
1366 req.r.rtm_type = RTN_BLACKHOLE;
1367 else if (zebra_flags & ZEBRA_FLAG_REJECT)
1368 req.r.rtm_type = RTN_UNREACHABLE;
1369 else
1370 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1372 else
1373 req.r.rtm_type = RTN_UNICAST;
1376 if (dest)
1377 addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
1379 if (!discard)
1381 if (gate)
1382 addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
1383 if (index > 0)
1384 addattr32 (&req.n, sizeof req, RTA_OIF, index);
1387 /* Destination netlink address. */
1388 memset (&snl, 0, sizeof snl);
1389 snl.nl_family = AF_NETLINK;
1391 /* Talk to netlink socket. */
1392 ret = netlink_talk (&req.n, &netlink_cmd);
1393 if (ret < 0)
1394 return -1;
1396 return 0;
1399 /* Routing table change via netlink interface. */
1401 netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
1402 int family)
1404 int bytelen;
1405 struct sockaddr_nl snl;
1406 struct nexthop *nexthop = NULL;
1407 int nexthop_num = 0;
1408 int discard;
1410 struct
1412 struct nlmsghdr n;
1413 struct rtmsg r;
1414 char buf[1024];
1415 } req;
1417 memset (&req, 0, sizeof req);
1419 bytelen = (family == AF_INET ? 4 : 16);
1421 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
1422 req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
1423 req.n.nlmsg_type = cmd;
1424 req.r.rtm_family = family;
1425 req.r.rtm_table = rib->table;
1426 req.r.rtm_dst_len = p->prefixlen;
1428 if ((rib->flags & ZEBRA_FLAG_BLACKHOLE) || (rib->flags & ZEBRA_FLAG_REJECT))
1429 discard = 1;
1430 else
1431 discard = 0;
1433 if (cmd == RTM_NEWROUTE)
1435 req.r.rtm_protocol = RTPROT_ZEBRA;
1436 req.r.rtm_scope = RT_SCOPE_UNIVERSE;
1438 if (discard)
1440 if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
1441 req.r.rtm_type = RTN_BLACKHOLE;
1442 else if (rib->flags & ZEBRA_FLAG_REJECT)
1443 req.r.rtm_type = RTN_UNREACHABLE;
1444 else
1445 assert (RTN_BLACKHOLE != RTN_UNREACHABLE); /* false */
1447 else
1448 req.r.rtm_type = RTN_UNICAST;
1451 addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
1453 /* Metric. */
1454 addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
1456 if (discard)
1458 if (cmd == RTM_NEWROUTE)
1459 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1460 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1461 goto skip;
1464 /* Multipath case. */
1465 if (rib->nexthop_active_num == 1 || MULTIPATH_NUM == 1)
1467 for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
1470 if ((cmd == RTM_NEWROUTE
1471 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1472 || (cmd == RTM_DELROUTE
1473 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1476 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1478 if (IS_ZEBRA_DEBUG_KERNEL)
1480 zlog_debug
1481 ("netlink_route_multipath() (recursive, 1 hop): "
1482 "%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1483 #ifdef HAVE_IPV6
1484 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1485 inet6_ntoa (p->u.prefix6),
1486 #else
1487 inet_ntoa (p->u.prefix4),
1488 #endif /* HAVE_IPV6 */
1490 p->prefixlen, nexthop_types_desc[nexthop->rtype]);
1493 if (nexthop->rtype == NEXTHOP_TYPE_IPV4
1494 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
1496 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1497 &nexthop->rgate.ipv4, bytelen);
1498 if (nexthop->src.ipv4.s_addr)
1499 addattr_l(&req.n, sizeof req, RTA_PREFSRC,
1500 &nexthop->src.ipv4, bytelen);
1501 if (IS_ZEBRA_DEBUG_KERNEL)
1502 zlog_debug("netlink_route_multipath() (recursive, "
1503 "1 hop): nexthop via %s if %u",
1504 inet_ntoa (nexthop->rgate.ipv4),
1505 nexthop->rifindex);
1507 #ifdef HAVE_IPV6
1508 if (nexthop->rtype == NEXTHOP_TYPE_IPV6
1509 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1510 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1512 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1513 &nexthop->rgate.ipv6, bytelen);
1515 if (IS_ZEBRA_DEBUG_KERNEL)
1516 zlog_debug("netlink_route_multipath() (recursive, "
1517 "1 hop): nexthop via %s if %u",
1518 inet6_ntoa (nexthop->rgate.ipv6),
1519 nexthop->rifindex);
1521 #endif /* HAVE_IPV6 */
1522 if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
1523 || nexthop->rtype == NEXTHOP_TYPE_IFNAME
1524 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1525 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1526 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1528 addattr32 (&req.n, sizeof req, RTA_OIF,
1529 nexthop->rifindex);
1530 if ((nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1531 || nexthop->rtype == NEXTHOP_TYPE_IFINDEX)
1532 && nexthop->src.ipv4.s_addr)
1533 addattr_l (&req.n, sizeof req, RTA_PREFSRC,
1534 &nexthop->src.ipv4, bytelen);
1536 if (IS_ZEBRA_DEBUG_KERNEL)
1537 zlog_debug("netlink_route_multipath() (recursive, "
1538 "1 hop): nexthop via if %u",
1539 nexthop->rifindex);
1542 else
1544 if (IS_ZEBRA_DEBUG_KERNEL)
1546 zlog_debug
1547 ("netlink_route_multipath() (single hop): "
1548 "%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1549 #ifdef HAVE_IPV6
1550 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1551 inet6_ntoa (p->u.prefix6),
1552 #else
1553 inet_ntoa (p->u.prefix4),
1554 #endif /* HAVE_IPV6 */
1555 p->prefixlen, nexthop_types_desc[nexthop->type]);
1558 if (nexthop->type == NEXTHOP_TYPE_IPV4
1559 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1561 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1562 &nexthop->gate.ipv4, bytelen);
1563 if (nexthop->src.ipv4.s_addr)
1564 addattr_l (&req.n, sizeof req, RTA_PREFSRC,
1565 &nexthop->src.ipv4, bytelen);
1567 if (IS_ZEBRA_DEBUG_KERNEL)
1568 zlog_debug("netlink_route_multipath() (single hop): "
1569 "nexthop via %s if %u",
1570 inet_ntoa (nexthop->gate.ipv4),
1571 nexthop->ifindex);
1573 #ifdef HAVE_IPV6
1574 if (nexthop->type == NEXTHOP_TYPE_IPV6
1575 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1576 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1578 addattr_l (&req.n, sizeof req, RTA_GATEWAY,
1579 &nexthop->gate.ipv6, bytelen);
1581 if (IS_ZEBRA_DEBUG_KERNEL)
1582 zlog_debug("netlink_route_multipath() (single hop): "
1583 "nexthop via %s if %u",
1584 inet6_ntoa (nexthop->gate.ipv6),
1585 nexthop->ifindex);
1587 #endif /* HAVE_IPV6 */
1588 if (nexthop->type == NEXTHOP_TYPE_IFINDEX
1589 || nexthop->type == NEXTHOP_TYPE_IFNAME
1590 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1592 addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
1594 if (nexthop->src.ipv4.s_addr)
1595 addattr_l (&req.n, sizeof req, RTA_PREFSRC,
1596 &nexthop->src.ipv4, bytelen);
1598 if (IS_ZEBRA_DEBUG_KERNEL)
1599 zlog_debug("netlink_route_multipath() (single hop): "
1600 "nexthop via if %u", nexthop->ifindex);
1602 else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
1603 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
1605 addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
1607 if (IS_ZEBRA_DEBUG_KERNEL)
1608 zlog_debug("netlink_route_multipath() (single hop): "
1609 "nexthop via if %u", nexthop->ifindex);
1613 if (cmd == RTM_NEWROUTE)
1614 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1616 nexthop_num++;
1617 break;
1621 else
1623 char buf[1024];
1624 struct rtattr *rta = (void *) buf;
1625 struct rtnexthop *rtnh;
1626 union g_addr *src = NULL;
1628 rta->rta_type = RTA_MULTIPATH;
1629 rta->rta_len = RTA_LENGTH (0);
1630 rtnh = RTA_DATA (rta);
1632 nexthop_num = 0;
1633 for (nexthop = rib->nexthop;
1634 nexthop && (MULTIPATH_NUM == 0 || nexthop_num < MULTIPATH_NUM);
1635 nexthop = nexthop->next)
1637 if ((cmd == RTM_NEWROUTE
1638 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
1639 || (cmd == RTM_DELROUTE
1640 && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
1642 nexthop_num++;
1644 rtnh->rtnh_len = sizeof (*rtnh);
1645 rtnh->rtnh_flags = 0;
1646 rtnh->rtnh_hops = 0;
1647 rta->rta_len += rtnh->rtnh_len;
1649 if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
1651 if (IS_ZEBRA_DEBUG_KERNEL)
1653 zlog_debug ("netlink_route_multipath() "
1654 "(recursive, multihop): %s %s/%d type %s",
1655 lookup (nlmsg_str, cmd),
1656 #ifdef HAVE_IPV6
1657 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1658 inet6_ntoa (p->u.prefix6),
1659 #else
1660 inet_ntoa (p->u.prefix4),
1661 #endif /* HAVE_IPV6 */
1662 p->prefixlen, nexthop_types_desc[nexthop->rtype]);
1664 if (nexthop->rtype == NEXTHOP_TYPE_IPV4
1665 || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
1667 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1668 &nexthop->rgate.ipv4, bytelen);
1669 rtnh->rtnh_len += sizeof (struct rtattr) + 4;
1671 if (nexthop->src.ipv4.s_addr)
1672 src = &nexthop->src;
1674 if (IS_ZEBRA_DEBUG_KERNEL)
1675 zlog_debug("netlink_route_multipath() (recursive, "
1676 "multihop): nexthop via %s if %u",
1677 inet_ntoa (nexthop->rgate.ipv4),
1678 nexthop->rifindex);
1680 #ifdef HAVE_IPV6
1681 if (nexthop->rtype == NEXTHOP_TYPE_IPV6
1682 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
1683 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
1685 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1686 &nexthop->rgate.ipv6, bytelen);
1688 if (IS_ZEBRA_DEBUG_KERNEL)
1689 zlog_debug("netlink_route_multipath() (recursive, "
1690 "multihop): nexthop via %s if %u",
1691 inet6_ntoa (nexthop->rgate.ipv6),
1692 nexthop->rifindex);
1694 #endif /* HAVE_IPV6 */
1695 /* ifindex */
1696 if (nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
1697 || nexthop->rtype == NEXTHOP_TYPE_IFINDEX
1698 || nexthop->rtype == NEXTHOP_TYPE_IFNAME)
1700 rtnh->rtnh_ifindex = nexthop->rifindex;
1701 if (nexthop->src.ipv4.s_addr)
1702 src = &nexthop->src;
1704 if (IS_ZEBRA_DEBUG_KERNEL)
1705 zlog_debug("netlink_route_multipath() (recursive, "
1706 "multihop): nexthop via if %u",
1707 nexthop->rifindex);
1709 else if (nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
1710 || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
1712 rtnh->rtnh_ifindex = nexthop->rifindex;
1714 if (IS_ZEBRA_DEBUG_KERNEL)
1715 zlog_debug("netlink_route_multipath() (recursive, "
1716 "multihop): nexthop via if %u",
1717 nexthop->rifindex);
1719 else
1721 rtnh->rtnh_ifindex = 0;
1724 else
1726 if (IS_ZEBRA_DEBUG_KERNEL)
1728 zlog_debug ("netlink_route_multipath() (multihop): "
1729 "%s %s/%d, type %s", lookup (nlmsg_str, cmd),
1730 #ifdef HAVE_IPV6
1731 (family == AF_INET) ? inet_ntoa (p->u.prefix4) :
1732 inet6_ntoa (p->u.prefix6),
1733 #else
1734 inet_ntoa (p->u.prefix4),
1735 #endif /* HAVE_IPV6 */
1736 p->prefixlen, nexthop_types_desc[nexthop->type]);
1738 if (nexthop->type == NEXTHOP_TYPE_IPV4
1739 || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
1741 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1742 &nexthop->gate.ipv4, bytelen);
1743 rtnh->rtnh_len += sizeof (struct rtattr) + 4;
1745 if (nexthop->src.ipv4.s_addr)
1746 src = &nexthop->src;
1748 if (IS_ZEBRA_DEBUG_KERNEL)
1749 zlog_debug("netlink_route_multipath() (multihop): "
1750 "nexthop via %s if %u",
1751 inet_ntoa (nexthop->gate.ipv4),
1752 nexthop->ifindex);
1754 #ifdef HAVE_IPV6
1755 if (nexthop->type == NEXTHOP_TYPE_IPV6
1756 || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1757 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1759 rta_addattr_l (rta, 4096, RTA_GATEWAY,
1760 &nexthop->gate.ipv6, bytelen);
1762 if (IS_ZEBRA_DEBUG_KERNEL)
1763 zlog_debug("netlink_route_multipath() (multihop): "
1764 "nexthop via %s if %u",
1765 inet6_ntoa (nexthop->gate.ipv6),
1766 nexthop->ifindex);
1768 #endif /* HAVE_IPV6 */
1769 /* ifindex */
1770 if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
1771 || nexthop->type == NEXTHOP_TYPE_IFINDEX
1772 || nexthop->type == NEXTHOP_TYPE_IFNAME)
1774 rtnh->rtnh_ifindex = nexthop->ifindex;
1775 if (nexthop->src.ipv4.s_addr)
1776 src = &nexthop->src;
1777 if (IS_ZEBRA_DEBUG_KERNEL)
1778 zlog_debug("netlink_route_multipath() (multihop): "
1779 "nexthop via if %u", nexthop->ifindex);
1781 else if (nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
1782 || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
1784 rtnh->rtnh_ifindex = nexthop->ifindex;
1786 if (IS_ZEBRA_DEBUG_KERNEL)
1787 zlog_debug("netlink_route_multipath() (multihop): "
1788 "nexthop via if %u", nexthop->ifindex);
1790 else
1792 rtnh->rtnh_ifindex = 0;
1795 rtnh = RTNH_NEXT (rtnh);
1797 if (cmd == RTM_NEWROUTE)
1798 SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
1801 if (src)
1802 addattr_l (&req.n, sizeof req, RTA_PREFSRC, &src->ipv4, bytelen);
1804 if (rta->rta_len > RTA_LENGTH (0))
1805 addattr_l (&req.n, 1024, RTA_MULTIPATH, RTA_DATA (rta),
1806 RTA_PAYLOAD (rta));
1809 /* If there is no useful nexthop then return. */
1810 if (nexthop_num == 0)
1812 if (IS_ZEBRA_DEBUG_KERNEL)
1813 zlog_debug ("netlink_route_multipath(): No useful nexthop.");
1814 return 0;
1817 skip:
1819 /* Destination netlink address. */
1820 memset (&snl, 0, sizeof snl);
1821 snl.nl_family = AF_NETLINK;
1823 /* Talk to netlink socket. */
1824 return netlink_talk (&req.n, &netlink_cmd);
1828 kernel_add_ipv4 (struct prefix *p, struct rib *rib)
1830 return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET);
1834 kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
1836 return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET);
1839 #ifdef HAVE_IPV6
1841 kernel_add_ipv6 (struct prefix *p, struct rib *rib)
1843 return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6);
1847 kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
1849 return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6);
1852 /* Delete IPv6 route from the kernel. */
1854 kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
1855 unsigned int index, int flags, int table)
1857 return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix,
1858 dest->prefixlen, gate, index, flags, table);
1860 #endif /* HAVE_IPV6 */
1862 /* Interface address modification. */
1864 netlink_address (int cmd, int family, struct interface *ifp,
1865 struct connected *ifc)
1867 int bytelen;
1868 struct prefix *p;
1870 struct
1872 struct nlmsghdr n;
1873 struct ifaddrmsg ifa;
1874 char buf[1024];
1875 } req;
1877 p = ifc->address;
1878 memset (&req, 0, sizeof req);
1880 bytelen = (family == AF_INET ? 4 : 16);
1882 req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct ifaddrmsg));
1883 req.n.nlmsg_flags = NLM_F_REQUEST;
1884 req.n.nlmsg_type = cmd;
1885 req.ifa.ifa_family = family;
1887 req.ifa.ifa_index = ifp->ifindex;
1888 req.ifa.ifa_prefixlen = p->prefixlen;
1890 addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
1892 if (family == AF_INET && cmd == RTM_NEWADDR)
1894 if (!CONNECTED_PEER(ifc) && ifc->destination)
1896 p = ifc->destination;
1897 addattr_l (&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix,
1898 bytelen);
1902 if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
1903 SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
1905 if (ifc->label)
1906 addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
1907 strlen (ifc->label) + 1);
1909 return netlink_talk (&req.n, &netlink_cmd);
1913 kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
1915 return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
1919 kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
1921 return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
1925 extern struct thread_master *master;
1927 /* Kernel route reflection. */
1929 kernel_read (struct thread *thread)
1931 int ret;
1932 int sock;
1934 sock = THREAD_FD (thread);
1935 ret = netlink_parse_info (netlink_information_fetch, &netlink);
1936 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);
1938 return 0;
1941 /* Exported interface function. This function simply calls
1942 netlink_socket (). */
1943 void
1944 kernel_init (void)
1946 unsigned long groups;
1948 groups = RTMGRP_LINK | RTMGRP_IPV4_ROUTE | RTMGRP_IPV4_IFADDR;
1949 #ifdef HAVE_IPV6
1950 groups |= RTMGRP_IPV6_ROUTE | RTMGRP_IPV6_IFADDR;
1951 #endif /* HAVE_IPV6 */
1952 netlink_socket (&netlink, groups);
1953 netlink_socket (&netlink_cmd, 0);
1955 /* Register kernel socket. */
1956 if (netlink.sock > 0)
1957 thread_add_read (zebrad.master, kernel_read, NULL, netlink.sock);