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