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