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