rt_netlink.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:36k
源码类别:

网络

开发平台:

Unix_Linux

  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. #include <zebra.h>
  22. /* Hack for GNU libc version 2. */
  23. #ifndef MSG_TRUNC
  24. #define MSG_TRUNC      0x20
  25. #endif /* MSG_TRUNC */
  26. #include "linklist.h"
  27. #include "if.h"
  28. #include "log.h"
  29. #include "prefix.h"
  30. #include "connected.h"
  31. #include "table.h"
  32. #include "rib.h"
  33. #include "zebra/zserv.h"
  34. #include "zebra/redistribute.h"
  35. #include "zebra/interface.h"
  36. #include "zebra/debug.h"
  37. /* Socket interface to kernel */
  38. struct nlsock
  39. {
  40.   int sock;
  41.   int seq;
  42.   struct sockaddr_nl snl;
  43.   char *name;
  44. } netlink = { -1, 0, {0}, "netlink-listen" }, /* kernel messages */
  45.   netlink_cmd = { -1, 0, {0}, "netlink-cmd" },          /* command channel */
  46.   netlink_addr = {-1, 0, {0}, "netlink-addr" }; /* address channel */
  47. struct message nlmsg_str[] =
  48. {
  49.   {RTM_NEWROUTE, "RTM_NEWROUTE"},
  50.   {RTM_DELROUTE, "RTM_DELROUTE"},
  51.   {RTM_GETROUTE, "RTM_GETROUTE"},
  52.   {RTM_NEWLINK,  "RTM_NEWLINK"},
  53.   {RTM_DELLINK,  "RTM_DELLINK"},
  54.   {RTM_GETLINK,  "RTM_GETLINK"},
  55.   {RTM_NEWADDR,  "RTM_NEWADDR"},
  56.   {RTM_DELADDR,  "RTM_DELADDR"},
  57.   {RTM_GETADDR,  "RTM_GETADDR"},
  58.   {0,            NULL}
  59. };
  60. extern int rtm_table_default;
  61. /* Make socket for Linux netlink interface. */
  62. static int
  63. netlink_socket (struct nlsock *nl, unsigned long groups)
  64. {
  65.   int ret;
  66.   struct sockaddr_nl snl;
  67.   int sock;
  68.   int namelen;
  69.   sock = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
  70.   if (sock < 0)
  71.     {
  72.       zlog (NULL, LOG_ERR, "Can't open %s socket: %s", nl->name,
  73.     strerror (errno));
  74.       return -1;
  75.     }
  76.   ret = fcntl (sock, F_SETFL, O_NONBLOCK);
  77.   if (ret < 0)
  78.     {
  79.       zlog (NULL, LOG_ERR, "Can't set %s socket flags: %s", nl->name,
  80.     strerror (errno));
  81.       close (sock);
  82.       return -1;
  83.     }
  84.   
  85.   memset (&snl, 0, sizeof snl);
  86.   snl.nl_family = AF_NETLINK;
  87.   snl.nl_groups = groups;
  88.   /* Bind the socket to the netlink structure for anything. */
  89.   ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
  90.   if (ret < 0)
  91.     {
  92.       zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s", 
  93.     nl->name, snl.nl_groups, strerror (errno));
  94.       close (sock);
  95.       return -1;
  96.     }
  97.   /* multiple netlink sockets will have different nl_pid */
  98.   namelen = sizeof snl;
  99.   ret = getsockname (sock, (struct sockaddr *) &snl, &namelen);
  100.   if (ret < 0 || namelen != sizeof snl)
  101.     {
  102.       zlog (NULL, LOG_ERR, "Can't get %s socket name: %s", nl->name,
  103.     strerror (errno));
  104.       close (sock);
  105.       return -1;
  106.     }
  107.   nl->snl = snl;
  108.   nl->sock = sock;
  109.   return ret;
  110. }
  111. /* Get type specified information from netlink. */
  112. static int
  113. netlink_request (int family, int type, struct nlsock *nl)
  114. {
  115.   int ret;
  116.   struct sockaddr_nl snl;
  117.   struct
  118.   {
  119.     struct nlmsghdr nlh;
  120.     struct rtgenmsg g;
  121.   } req;
  122.   /* Check netlink socket. */
  123.   if (nl->sock < 0)
  124.     {
  125.       zlog (NULL, LOG_ERR, "%s socket isn't active.", nl->name);
  126.       return -1;
  127.     }
  128.   memset (&snl, 0, sizeof snl);
  129.   snl.nl_family = AF_NETLINK;
  130.   req.nlh.nlmsg_len = sizeof req;
  131.   req.nlh.nlmsg_type = type;
  132.   req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
  133.   req.nlh.nlmsg_pid = 0;
  134.   req.nlh.nlmsg_seq = ++nl->seq;
  135.   req.g.rtgen_family = family;
  136.  
  137.   ret = sendto (nl->sock, (void*) &req, sizeof req, 0, 
  138. (struct sockaddr*) &snl, sizeof snl);
  139.   if (ret < 0)
  140.     {
  141.       zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name, strerror (errno));
  142.       return -1;
  143.     }
  144.   return 0;
  145. }
  146. /* Receive message from netlink interface and pass those information
  147.    to the given function. */
  148. static int
  149. netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
  150.     struct nlsock *nl)
  151. {
  152.   int status;
  153.   int ret = 0;
  154.   int error;
  155.   while (1)
  156.     {
  157.       char buf[4096];
  158.       struct iovec iov = { buf, sizeof buf };
  159.       struct sockaddr_nl snl;
  160.       struct msghdr msg = { (void*)&snl, sizeof snl, &iov, 1, NULL, 0, 0};
  161.       struct nlmsghdr *h;
  162.       status = recvmsg (nl->sock, &msg, 0);
  163.       if (status < 0)
  164. {
  165.   if (errno == EINTR)
  166.     continue;
  167.   if (errno == EWOULDBLOCK || errno == EAGAIN)
  168.     break;
  169.   zlog (NULL, LOG_ERR, "%s recvmsg overrun", nl->name);
  170.   continue;
  171. }
  172.       if (snl.nl_pid != 0)
  173. {
  174.   zlog (NULL, LOG_ERR, "Ignoring non kernel message from pid %u",
  175. snl.nl_pid);
  176.   continue;
  177. }
  178.       if (status == 0)
  179. {
  180.   zlog (NULL, LOG_ERR, "%s EOF", nl->name);
  181.   return -1;
  182. }
  183.       if (msg.msg_namelen != sizeof snl)
  184. {
  185.   zlog (NULL, LOG_ERR, "%s sender address length error: length %d",
  186.        nl->name, msg.msg_namelen);
  187.   return -1;
  188. }
  189.       for (h = (struct nlmsghdr *) buf; NLMSG_OK (h, status); 
  190.    h = NLMSG_NEXT (h, status))
  191. {
  192.   /* Finish of reading. */
  193.   if (h->nlmsg_type == NLMSG_DONE)
  194.     return ret;
  195.   /* Error handling. */
  196.   if (h->nlmsg_type == NLMSG_ERROR)
  197.     {
  198.       struct nlmsgerr *err = (struct nlmsgerr *) NLMSG_DATA (h);
  199.       
  200.               /* If the error field is zero, then this is an ACK */
  201.               if (err->error == 0) 
  202.                 {
  203.                   if (IS_ZEBRA_DEBUG_KERNEL) 
  204.                     {  
  205.                       zlog_info("%s: %s ACK: type=%s(%u), seq=%u, pid=%d", 
  206.                         __FUNCTION__, nl->name,
  207.                         lookup (nlmsg_str, err->msg.nlmsg_type),
  208.                         err->msg.nlmsg_type, err->msg.nlmsg_seq,
  209.         err->msg.nlmsg_pid);
  210.                     }
  211.                 
  212.                   /* return if not a multipart message, otherwise continue */  
  213.                   if(!(h->nlmsg_flags & NLM_F_MULTI)) 
  214.                     { 
  215.                       return 0;    
  216.                     }
  217.                   continue; 
  218.                 }
  219.               
  220.               if (h->nlmsg_len < NLMSG_LENGTH (sizeof (struct nlmsgerr)))
  221. {
  222.   zlog (NULL, LOG_ERR, "%s error: message truncated",
  223. nl->name);
  224.   return -1;
  225. }
  226.       zlog (NULL, LOG_ERR, "%s error: %s, type=%s(%u), seq=%u, pid=%d",
  227.     nl->name, strerror (-err->error),
  228.     lookup (nlmsg_str, err->msg.nlmsg_type),
  229.     err->msg.nlmsg_type, err->msg.nlmsg_seq,
  230.     err->msg.nlmsg_pid);
  231.       /*
  232.       ret = -1;
  233.       continue;
  234.       */
  235.       return -1;
  236.     }
  237.   /* OK we got netlink message. */
  238.   if (IS_ZEBRA_DEBUG_KERNEL)
  239.     zlog_info ("netlink_parse_info: %s type %s(%u), seq=%u, pid=%d",
  240.       nl->name,
  241.       lookup (nlmsg_str, h->nlmsg_type), h->nlmsg_type,
  242.       h->nlmsg_seq, h->nlmsg_pid);
  243.   /* skip unsolicited messages originating from command socket */
  244.   if (nl != &netlink_cmd && h->nlmsg_pid == netlink_cmd.snl.nl_pid)
  245.     {
  246.       if (IS_ZEBRA_DEBUG_KERNEL)
  247. zlog_info ("netlink_parse_info: %s packet comes from %s",
  248.   nl->name, netlink_cmd.name);
  249.       continue;
  250.     }
  251.   error = (*filter) (&snl, h);
  252.   if (error < 0)
  253.     {
  254.       zlog (NULL, LOG_ERR, "%s filter function error", nl->name);
  255.       ret = error;
  256.     }
  257. }
  258.       /* After error care. */
  259.       if (msg.msg_flags & MSG_TRUNC)
  260. {
  261.   zlog (NULL, LOG_ERR, "%s error: message truncated", nl->name);
  262.   continue;
  263. }
  264.       if (status)
  265. {
  266.   zlog (NULL, LOG_ERR, "%s error: data remnant size %d", nl->name,
  267. status);
  268.   return -1;
  269. }
  270.     }
  271.   return ret;
  272. }
  273. /* Utility function for parse rtattr. */
  274. static void
  275. netlink_parse_rtattr (struct rtattr **tb, int max, struct rtattr *rta, int len)
  276. {
  277.   while (RTA_OK(rta, len)) 
  278.     {
  279.       if (rta->rta_type <= max)
  280. tb[rta->rta_type] = rta;
  281.       rta = RTA_NEXT(rta,len);
  282.     }
  283. }
  284. /* Called from interface_lookup_netlink().  This function is only used
  285.    during bootstrap. */
  286. int
  287. netlink_interface (struct sockaddr_nl *snl, struct nlmsghdr *h)
  288. {
  289.   int len;
  290.   struct ifinfomsg *ifi;
  291.   struct rtattr *tb[IFLA_MAX + 1];
  292.   struct interface *ifp;
  293.   char *name;
  294.   int i;
  295.   ifi = NLMSG_DATA (h);
  296.   if (h->nlmsg_type != RTM_NEWLINK)
  297.     return 0;
  298.   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
  299.   if (len < 0)
  300.     return -1;
  301.   /* Looking up interface name. */
  302.   memset (tb, 0, sizeof tb);
  303.   netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
  304.   if (tb[IFLA_IFNAME] == NULL)
  305.     return -1;
  306.   name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
  307.   /* Add interface. */
  308.   ifp = if_get_by_name (name);
  309.   
  310.   ifp->ifindex = ifi->ifi_index;
  311.   ifp->flags = ifi->ifi_flags & 0x0000fffff;
  312.   ifp->mtu = *(int *)RTA_DATA (tb[IFLA_MTU]);
  313.   ifp->metric = 1;
  314.   /* Hardware type and address. */
  315.   ifp->hw_type = ifi->ifi_type;
  316.   if (tb[IFLA_ADDRESS])
  317.     {
  318.       int hw_addr_len;
  319.       hw_addr_len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
  320.       if (hw_addr_len > INTERFACE_HWADDR_MAX)
  321. zlog_warn ("Hardware address is too large: %d", hw_addr_len);
  322.       else
  323. {      
  324.   ifp->hw_addr_len = hw_addr_len;
  325.   memcpy (ifp->hw_addr, RTA_DATA(tb[IFLA_ADDRESS]), hw_addr_len);
  326.   for (i = 0; i < hw_addr_len; i++)
  327.     if (ifp->hw_addr[i] != 0)
  328.       break;
  329.   if (i == hw_addr_len)
  330.     ifp->hw_addr_len = 0;
  331.   else
  332.     ifp->hw_addr_len = hw_addr_len;
  333. }
  334.     }
  335.   if_add_update (ifp);
  336.   return 0;
  337. }
  338. /* Lookup interface IPv4/IPv6 address. */
  339. int
  340. netlink_interface_addr (struct sockaddr_nl *snl, struct nlmsghdr *h)
  341. {
  342.   int len;
  343.   struct ifaddrmsg *ifa;
  344.   struct rtattr *tb [IFA_MAX + 1];
  345.   struct interface *ifp;
  346.   void *addr = NULL;
  347.   void *broad = NULL;
  348.   u_char flags = 0;
  349.   char *label = NULL;
  350.   ifa = NLMSG_DATA (h);
  351.   if (ifa->ifa_family != AF_INET 
  352. #ifdef HAVE_IPV6
  353.       && ifa->ifa_family != AF_INET6
  354. #endif /* HAVE_IPV6 */
  355.       )
  356.     return 0;
  357.   if (h->nlmsg_type != RTM_NEWADDR && h->nlmsg_type != RTM_DELADDR)
  358.     return 0;
  359.   len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct ifaddrmsg));
  360.   if (len < 0)
  361.     return -1;
  362.   memset (tb, 0, sizeof tb);
  363.   netlink_parse_rtattr (tb, IFA_MAX, IFA_RTA (ifa), len);
  364.   ifp = if_lookup_by_index (ifa->ifa_index);
  365.   if (ifp == NULL)
  366.     {
  367.       zlog_err ("netlink_interface_addr can't find interface by index %d",
  368. ifa->ifa_index);
  369.       return -1;
  370.     }
  371.   if (tb[IFA_ADDRESS] == NULL)
  372.     tb[IFA_ADDRESS] = tb[IFA_LOCAL];
  373.   if (ifp->flags & IFF_POINTOPOINT)
  374.     {
  375.       if (tb[IFA_LOCAL])
  376. {
  377.   addr = RTA_DATA (tb[IFA_LOCAL]);
  378.   if (tb[IFA_ADDRESS]) 
  379.     broad = RTA_DATA (tb[IFA_ADDRESS]);
  380.   else
  381.     broad = NULL;
  382. }
  383.       else
  384. {
  385.   if (tb[IFA_ADDRESS])
  386.     addr = RTA_DATA (tb[IFA_ADDRESS]);
  387.   else
  388.     addr = NULL;
  389. }
  390.     }
  391.   else
  392.     {
  393.       if (tb[IFA_ADDRESS])
  394. addr = RTA_DATA (tb[IFA_ADDRESS]);
  395.       else
  396. addr = NULL;
  397.       if (tb[IFA_BROADCAST])
  398. broad = RTA_DATA(tb[IFA_BROADCAST]);
  399.       else
  400. broad = NULL;
  401.     }
  402.   /* Flags. */
  403.   if (ifa->ifa_flags & IFA_F_SECONDARY)
  404.     SET_FLAG (flags, ZEBRA_IFA_SECONDARY);
  405.   /* Label */
  406.   if (tb[IFA_LABEL])
  407.     label = (char *) RTA_DATA (tb[IFA_LABEL]);
  408.   if (ifp && label && strcmp (ifp->name, label) == 0)
  409.     label = NULL;
  410.   /* Register interface address to the interface. */
  411.   if (ifa->ifa_family == AF_INET)
  412.     {
  413.       if (h->nlmsg_type == RTM_NEWADDR) 
  414. connected_add_ipv4 (ifp, flags,
  415.     (struct in_addr *) addr, ifa->ifa_prefixlen, 
  416.     (struct in_addr *) broad, label);
  417.       else 
  418. connected_delete_ipv4 (ifp, flags,
  419.        (struct in_addr *) addr, ifa->ifa_prefixlen, 
  420.        (struct in_addr *) broad, label);
  421.     }
  422. #ifdef HAVE_IPV6
  423.   if (ifa->ifa_family == AF_INET6)
  424.     {
  425.       if (h->nlmsg_type == RTM_NEWADDR)
  426. connected_add_ipv6 (ifp, 
  427.     (struct in6_addr *) addr, ifa->ifa_prefixlen, 
  428.     (struct in6_addr *) broad);
  429.       else
  430. connected_delete_ipv6 (ifp, 
  431.        (struct in6_addr *) addr, ifa->ifa_prefixlen, 
  432.        (struct in6_addr *) broad);
  433.     }
  434. #endif /* HAVE_IPV6*/
  435.   return 0;
  436. }
  437. /* Looking up routing table by netlink interface. */
  438. int
  439. netlink_routing_table (struct sockaddr_nl *snl, struct nlmsghdr *h)
  440. {
  441.   int len;
  442.   struct rtmsg *rtm;
  443.   struct rtattr *tb [RTA_MAX + 1];
  444.   u_char flags = 0;
  445.   
  446.   char anyaddr[16] = {0};
  447.   int index;
  448.   int table;
  449.   void *dest;
  450.   void *gate;
  451.   rtm = NLMSG_DATA (h);
  452.   if (h->nlmsg_type != RTM_NEWROUTE)
  453.     return 0;
  454.   if (rtm->rtm_type != RTN_UNICAST)
  455.     return 0;
  456.   table = rtm->rtm_table;
  457. #if 0 /* we weed them out later in rib_weed_tables () */
  458.   if (table != RT_TABLE_MAIN && table != rtm_table_default)
  459.     return 0;
  460. #endif
  461.   len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct rtmsg));
  462.   if (len < 0)
  463.     return -1;
  464.   memset (tb, 0, sizeof tb);
  465.   netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
  466.   if (rtm->rtm_flags & RTM_F_CLONED)
  467.     return 0;
  468.   if (rtm->rtm_protocol == RTPROT_REDIRECT)
  469.     return 0;
  470.   if (rtm->rtm_protocol == RTPROT_KERNEL)
  471.     return 0;
  472.   if (rtm->rtm_src_len != 0)
  473.     return 0;
  474.   /* Route which inserted by Zebra. */
  475.   if (rtm->rtm_protocol == RTPROT_ZEBRA)
  476.     flags |= ZEBRA_FLAG_SELFROUTE;
  477.   
  478.   index = 0;
  479.   dest = NULL;
  480.   gate = NULL;
  481.   if (tb[RTA_OIF])
  482.     index = *(int *) RTA_DATA (tb[RTA_OIF]);
  483.   if (tb[RTA_DST])
  484.     dest = RTA_DATA (tb[RTA_DST]);
  485.   else
  486.     dest = anyaddr;
  487.   /* Multipath treatment is needed. */
  488.   if (tb[RTA_GATEWAY])
  489.     gate = RTA_DATA (tb[RTA_GATEWAY]);
  490.   if (rtm->rtm_family == AF_INET)
  491.     {
  492.       struct prefix_ipv4 p;
  493.       p.family = AF_INET;
  494.       memcpy (&p.prefix, dest, 4);
  495.       p.prefixlen = rtm->rtm_dst_len;
  496.       rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table, 0, 0);
  497.     }
  498. #ifdef HAVE_IPV6
  499.   if (rtm->rtm_family == AF_INET6)
  500.     {
  501.       struct prefix_ipv6 p;
  502.       p.family = AF_INET6;
  503.       memcpy (&p.prefix, dest, 16);
  504.       p.prefixlen = rtm->rtm_dst_len;
  505.       rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, flags, &p, gate, index, table);
  506.     }
  507. #endif /* HAVE_IPV6 */
  508.   return 0;
  509. }
  510. struct message rtproto_str [] = 
  511. {
  512.   {RTPROT_REDIRECT, "redirect"},
  513.   {RTPROT_KERNEL,   "kernel"},
  514.   {RTPROT_BOOT,     "boot"},
  515.   {RTPROT_STATIC,   "static"},
  516.   {RTPROT_GATED,    "GateD"},
  517.   {RTPROT_RA,       "router advertisement"},
  518.   {RTPROT_MRT,      "MRT"},
  519.   {RTPROT_ZEBRA,    "Zebra"},
  520. #ifdef RTPROT_BIRD
  521.   {RTPROT_BIRD,     "BIRD"},
  522. #endif /* RTPROT_BIRD */
  523.   {0,               NULL}
  524. };
  525. /* Routing information change from the kernel. */
  526. int
  527. netlink_route_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
  528. {
  529.   int len;
  530.   struct rtmsg *rtm;
  531.   struct rtattr *tb [RTA_MAX + 1];
  532.   
  533.   char anyaddr[16] = {0};
  534.   int index;
  535.   int table;
  536.   void *dest;
  537.   void *gate;
  538.   rtm = NLMSG_DATA (h);
  539.   if (! (h->nlmsg_type == RTM_NEWROUTE || h->nlmsg_type == RTM_DELROUTE))
  540.     {
  541.       /* If this is not route add/delete message print warning. */
  542.       zlog_warn ("Kernel message: %dn", h->nlmsg_type);
  543.       return 0;
  544.     }
  545.   /* Connected route. */
  546.   if (IS_ZEBRA_DEBUG_KERNEL)
  547.     zlog_info ("%s %s %s proto %s",
  548.        h->nlmsg_type == RTM_NEWROUTE ? "RTM_NEWROUTE" : "RTM_DELROUTE",
  549.        rtm->rtm_family == AF_INET ? "ipv4" : "ipv6",
  550.        rtm->rtm_type == RTN_UNICAST ? "unicast" : "multicast",
  551.        lookup (rtproto_str, rtm->rtm_protocol));
  552.   if (rtm->rtm_type != RTN_UNICAST)
  553.     {
  554.       return 0;
  555.     }
  556.   table = rtm->rtm_table;
  557.   if (table != RT_TABLE_MAIN && table != rtm_table_default)
  558.     {
  559.       return 0;
  560.     }
  561.   len = h->nlmsg_len - NLMSG_LENGTH(sizeof (struct rtmsg));
  562.   if (len < 0)
  563.     return -1;
  564.   memset (tb, 0, sizeof tb);
  565.   netlink_parse_rtattr (tb, RTA_MAX, RTM_RTA (rtm), len);
  566.   if (rtm->rtm_flags & RTM_F_CLONED)
  567.     return 0;
  568.   if (rtm->rtm_protocol == RTPROT_REDIRECT)
  569.     return 0;
  570.   if (rtm->rtm_protocol == RTPROT_KERNEL)
  571.     return 0;
  572.   if (rtm->rtm_protocol == RTPROT_ZEBRA && h->nlmsg_type == RTM_NEWROUTE)
  573.     return 0;
  574.   if (rtm->rtm_src_len != 0)
  575.     {
  576.       zlog_warn ("netlink_route_change(): no src len");
  577.       return 0;
  578.     }
  579.   
  580.   index = 0;
  581.   dest = NULL;
  582.   gate = NULL;
  583.   if (tb[RTA_OIF])
  584.     index = *(int *) RTA_DATA (tb[RTA_OIF]);
  585.   if (tb[RTA_DST])
  586.     dest = RTA_DATA (tb[RTA_DST]);
  587.   else
  588.     dest = anyaddr;
  589.   if (tb[RTA_GATEWAY])
  590.     gate = RTA_DATA (tb[RTA_GATEWAY]);
  591.   if (rtm->rtm_family == AF_INET)
  592.     {
  593.       struct prefix_ipv4 p;
  594.       p.family = AF_INET;
  595.       memcpy (&p.prefix, dest, 4);
  596.       p.prefixlen = rtm->rtm_dst_len;
  597.       if (IS_ZEBRA_DEBUG_KERNEL)
  598. {
  599.   if (h->nlmsg_type == RTM_NEWROUTE)
  600.     zlog_info ("RTM_NEWROUTE %s/%d",
  601.        inet_ntoa (p.prefix), p.prefixlen);
  602.   else
  603.     zlog_info ("RTM_DELROUTE %s/%d",
  604.        inet_ntoa (p.prefix), p.prefixlen);
  605. }
  606.       if (h->nlmsg_type == RTM_NEWROUTE)
  607. rib_add_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table, 0, 0);
  608.       else
  609. rib_delete_ipv4 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, table);
  610.     }
  611. #ifdef HAVE_IPV6
  612.   if (rtm->rtm_family == AF_INET6)
  613.     {
  614.       struct prefix_ipv6 p;
  615.       char buf[BUFSIZ];
  616.       p.family = AF_INET6;
  617.       memcpy (&p.prefix, dest, 16);
  618.       p.prefixlen = rtm->rtm_dst_len;
  619.       if (IS_ZEBRA_DEBUG_KERNEL)
  620. {
  621.   if (h->nlmsg_type == RTM_NEWROUTE)
  622.     zlog_info ("RTM_NEWROUTE %s/%d",
  623.        inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
  624.        p.prefixlen);
  625.   else
  626.     zlog_info ("RTM_DELROUTE %s/%d",
  627.        inet_ntop (AF_INET6, &p.prefix, buf, BUFSIZ),
  628.        p.prefixlen);
  629. }
  630.       if (h->nlmsg_type == RTM_NEWROUTE)
  631. rib_add_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
  632.       else
  633. rib_delete_ipv6 (ZEBRA_ROUTE_KERNEL, 0, &p, gate, index, 0);
  634.     }
  635. #endif /* HAVE_IPV6 */
  636.   return 0;
  637. }
  638. int
  639. netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
  640. {
  641.   int len;
  642.   struct ifinfomsg *ifi;
  643.   struct rtattr *tb [IFLA_MAX + 1];
  644.   struct interface *ifp;
  645.   char *name;
  646.   ifi = NLMSG_DATA (h);
  647.   if (! (h->nlmsg_type == RTM_NEWLINK || h->nlmsg_type == RTM_DELLINK))
  648.     {
  649.       /* If this is not link add/delete message so print warning. */
  650.       zlog_warn ("netlink_link_change: wrong kernel message %dn",
  651.  h->nlmsg_type);
  652.       return 0;
  653.     }
  654.   len = h->nlmsg_len - NLMSG_LENGTH (sizeof (struct ifinfomsg));
  655.   if (len < 0)
  656.     return -1;
  657.   /* Looking up interface name. */
  658.   memset (tb, 0, sizeof tb);
  659.   netlink_parse_rtattr (tb, IFLA_MAX, IFLA_RTA (ifi), len);
  660.   if (tb[IFLA_IFNAME] == NULL)
  661.     return -1;
  662.   name = (char *)RTA_DATA(tb[IFLA_IFNAME]);
  663.   /* Add interface. */
  664.   if (h->nlmsg_type == RTM_NEWLINK)
  665.     {
  666.       ifp = if_lookup_by_name (name);
  667.       if (ifp == NULL || ! CHECK_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE))
  668. {
  669.   if (ifp == NULL)
  670.     ifp = if_get_by_name (name);
  671.   ifp->ifindex = ifi->ifi_index;
  672.   ifp->flags = ifi->ifi_flags & 0x0000fffff;
  673.   ifp->mtu = *(int *)RTA_DATA (tb[IFLA_MTU]);
  674.   ifp->metric = 1;
  675.   /* If new link is added. */
  676.   if_add_update(ifp);
  677. }      
  678.       else
  679. {
  680.   /* Interface status change. */
  681.   ifp->ifindex = ifi->ifi_index;
  682.   ifp->mtu = *(int *)RTA_DATA (tb[IFLA_MTU]);
  683.   ifp->metric = 1;
  684.   if (if_is_up (ifp))
  685.     {
  686.       ifp->flags = ifi->ifi_flags & 0x0000fffff;
  687.       if (! if_is_up (ifp))
  688. if_down (ifp);
  689.     }
  690.   else
  691.     {
  692.       ifp->flags = ifi->ifi_flags & 0x0000fffff;
  693.       if (if_is_up (ifp))
  694. if_up (ifp);
  695.     }
  696. }
  697.     }
  698.   else
  699.     {
  700.       /* RTM_DELLINK. */
  701.       ifp = if_lookup_by_name (name);
  702.       if (ifp == NULL)
  703. {
  704.   zlog (NULL, LOG_WARNING, "interface %s is deleted but can't find",
  705.                 name);
  706.   return 0;
  707. }
  708.       
  709.       if_delete_update (ifp);
  710.     }
  711.   return 0;
  712. }
  713. int
  714. netlink_information_fetch (struct sockaddr_nl *snl, struct nlmsghdr *h)
  715. {
  716.   switch (h->nlmsg_type)
  717.     {
  718.     case RTM_NEWROUTE:
  719.       return netlink_route_change (snl, h);
  720.       break;
  721.     case RTM_DELROUTE:
  722.       return netlink_route_change (snl, h);
  723.       break;
  724.     case RTM_NEWLINK:
  725.       return netlink_link_change (snl, h);
  726.       break;
  727.     case RTM_DELLINK:
  728.       return netlink_link_change (snl, h);
  729.       break;
  730.     case RTM_NEWADDR:
  731.       return netlink_interface_addr (snl, h);
  732.       break;
  733.     case RTM_DELADDR:
  734.       return netlink_interface_addr (snl, h);
  735.       break;
  736.     default:
  737.       zlog_warn ("Unknown netlink nlmsg_type %dn", h->nlmsg_type);
  738.       break;
  739.     }
  740.   return 0;
  741. }
  742. /* Interface lookup by netlink socket. */
  743. int
  744. interface_lookup_netlink ()
  745. {
  746.   int ret;
  747.   /* Get interface information. */
  748.   ret = netlink_request (AF_PACKET, RTM_GETLINK, &netlink_cmd);
  749.   if (ret < 0)
  750.     return ret;
  751.   ret = netlink_parse_info (netlink_interface, &netlink_cmd);
  752.   if (ret < 0)
  753.     return ret;
  754.   /* Get IPv4 address of the interfaces. */
  755.   ret = netlink_request (AF_INET, RTM_GETADDR, &netlink_cmd);
  756.   if (ret < 0)
  757.     return ret;
  758.   ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
  759.   if (ret < 0)
  760.     return ret;
  761. #ifdef HAVE_IPV6
  762.   /* Get IPv6 address of the interfaces. */
  763.   ret = netlink_request (AF_INET6, RTM_GETADDR, &netlink_cmd);
  764.   if (ret < 0)
  765.     return ret;
  766.   ret = netlink_parse_info (netlink_interface_addr, &netlink_cmd);
  767.   if (ret < 0)
  768.     return ret;
  769. #endif /* HAVE_IPV6 */
  770.   return 0;
  771. }
  772. /* Routing table read function using netlink interface.  Only called
  773.    bootstrap time. */
  774. int
  775. netlink_route_read ()
  776. {
  777.   int ret;
  778.   /* Get IPv4 routing table. */
  779.   ret = netlink_request (AF_INET, RTM_GETROUTE, &netlink_cmd);
  780.   if (ret < 0)
  781.     return ret;
  782.   ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
  783.   if (ret < 0)
  784.     return ret;
  785. #ifdef HAVE_IPV6
  786.   /* Get IPv6 routing table. */
  787.   ret = netlink_request (AF_INET6, RTM_GETROUTE, &netlink_cmd);
  788.   if (ret < 0)
  789.     return ret;
  790.   ret = netlink_parse_info (netlink_routing_table, &netlink_cmd);
  791.   if (ret < 0)
  792.     return ret;
  793. #endif /* HAVE_IPV6 */
  794.   return 0;
  795. }
  796. /* Utility function  comes from iproute2. 
  797.    Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
  798. int
  799. addattr_l (struct nlmsghdr *n, int maxlen, int type, void *data, int alen)
  800. {
  801.   int len;
  802.   struct rtattr *rta;
  803.   len = RTA_LENGTH(alen);
  804.   if (NLMSG_ALIGN(n->nlmsg_len) + len > maxlen)
  805.     return -1;
  806.   rta = (struct rtattr*) (((char*)n) + NLMSG_ALIGN (n->nlmsg_len));
  807.   rta->rta_type = type;
  808.   rta->rta_len = len;
  809.   memcpy (RTA_DATA(rta), data, alen);
  810.   n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
  811.   return 0;
  812. }
  813. int
  814. rta_addattr_l (struct rtattr *rta, int maxlen, int type, void *data, int alen)
  815. {
  816.   int len;
  817.   struct rtattr *subrta;
  818.   len = RTA_LENGTH(alen);
  819.   if (RTA_ALIGN(rta->rta_len) + len > maxlen)
  820.     return -1;
  821.   subrta = (struct rtattr*) (((char*)rta) + RTA_ALIGN (rta->rta_len));
  822.   subrta->rta_type = type;
  823.   subrta->rta_len = len;
  824.   memcpy (RTA_DATA(subrta), data, alen);
  825.   rta->rta_len = NLMSG_ALIGN (rta->rta_len) + len;
  826.   return 0;
  827. }
  828. /* Utility function comes from iproute2. 
  829.    Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> */
  830. int
  831. addattr32 (struct nlmsghdr *n, int maxlen, int type, int data)
  832. {
  833.   int len;
  834.   struct rtattr *rta;
  835.   
  836.   len = RTA_LENGTH(4);
  837.   
  838.   if (NLMSG_ALIGN (n->nlmsg_len) + len > maxlen)
  839.     return -1;
  840.   rta = (struct rtattr*) (((char*)n) + NLMSG_ALIGN (n->nlmsg_len));
  841.   rta->rta_type = type;
  842.   rta->rta_len = len;
  843.   memcpy (RTA_DATA(rta), &data, 4);
  844.   n->nlmsg_len = NLMSG_ALIGN (n->nlmsg_len) + len;
  845.   return 0;
  846. }
  847. static int
  848. netlink_talk_filter (struct sockaddr_nl *snl, struct nlmsghdr *h)
  849. {
  850.   zlog_warn ("netlink_talk: ignoring message type 0x%04x", h->nlmsg_type);
  851.   return 0;
  852. }
  853. /* sendmsg() to netlink socket then recvmsg(). */
  854. int
  855. netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
  856. {
  857.   int status;
  858.   struct sockaddr_nl snl;
  859.   struct iovec iov = { (void*) n, n->nlmsg_len };
  860.   struct msghdr msg = {(void*) &snl, sizeof snl, &iov, 1, NULL, 0, 0};
  861.   int flags = 0;
  862.   
  863.   memset (&snl, 0, sizeof snl);
  864.   snl.nl_family = AF_NETLINK;
  865.   
  866.   n->nlmsg_seq = ++netlink_cmd.seq;
  867.   /* Request an acknowledgement by setting NLM_F_ACK */
  868.   n->nlmsg_flags |= NLM_F_ACK;
  869.   
  870.   if (IS_ZEBRA_DEBUG_KERNEL) 
  871.     zlog_info ("netlink_talk: %s type %s(%u), seq=%u", netlink_cmd.name,
  872.       lookup (nlmsg_str, n->nlmsg_type), n->nlmsg_type,
  873.       n->nlmsg_seq);
  874.   /* Send message to netlink interface. */
  875.   status = sendmsg (nl->sock, &msg, 0);
  876.   if (status < 0)
  877.     {
  878.       zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",
  879.     strerror (errno));
  880.       return -1;
  881.     }
  882.   
  883.   /* 
  884.    * Change socket flags for blocking I/O. 
  885.    * This ensures we wait for a reply in netlink_parse_info().
  886.    */
  887.   if((flags = fcntl(nl->sock, F_GETFL, 0)) < 0) 
  888.     {
  889.       zlog (NULL, LOG_ERR, "%s:%i F_GETFL error: %s", 
  890.               __FUNCTION__, __LINE__, strerror (errno));
  891.     }
  892.   flags &= ~O_NONBLOCK;
  893.   if(fcntl(nl->sock, F_SETFL, flags) < 0) 
  894.     {
  895.       zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s", 
  896.               __FUNCTION__, __LINE__, strerror (errno));
  897.     }
  898.   /* 
  899.    * Get reply from netlink socket. 
  900.    * The reply should either be an acknowlegement or an error.
  901.    */
  902.   status = netlink_parse_info (netlink_talk_filter, nl);
  903.   
  904.   /* Restore socket flags for nonblocking I/O */
  905.   flags |= O_NONBLOCK;
  906.   if(fcntl(nl->sock, F_SETFL, flags) < 0) 
  907.     {
  908.       zlog (NULL, LOG_ERR, "%s:%i F_SETFL error: %s", 
  909.               __FUNCTION__, __LINE__, strerror (errno));
  910.     }
  911.   
  912.   return status;
  913. }
  914. /* Routing table change via netlink interface. */
  915. int
  916. netlink_route (int cmd, int family, void *dest, int length, void *gate,
  917.        int index, int zebra_flags, int table)
  918. {
  919.   int ret;
  920.   int bytelen;
  921.   struct sockaddr_nl snl;
  922.   int discard;
  923.   struct 
  924.   {
  925.     struct nlmsghdr n;
  926.     struct rtmsg r;
  927.     char buf[1024];
  928.   } req;
  929.   memset (&req, 0, sizeof req);
  930.   bytelen = (family == AF_INET ? 4 : 16);
  931.   req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
  932.   req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
  933.   req.n.nlmsg_type = cmd;
  934.   req.r.rtm_family = family;
  935.   req.r.rtm_table = table;
  936.   req.r.rtm_dst_len = length;
  937.   if (zebra_flags & ZEBRA_FLAG_BLACKHOLE)
  938.     discard = 1;
  939.   else
  940.     discard = 0;
  941.   if (cmd == RTM_NEWROUTE) 
  942.     {
  943. #if 0
  944.       req.r.rtm_protocol = RTPROT_ZEBRA;
  945. #endif
  946.       req.r.rtm_scope = RT_SCOPE_UNIVERSE;
  947.       if (discard)
  948. req.r.rtm_type = RTN_BLACKHOLE;
  949.       else
  950. req.r.rtm_type = RTN_UNICAST;
  951.     }
  952.   if (dest)
  953.     addattr_l (&req.n, sizeof req, RTA_DST, dest, bytelen);
  954.   if (! discard)
  955.     {
  956.       if (gate)
  957. addattr_l (&req.n, sizeof req, RTA_GATEWAY, gate, bytelen);
  958.       if (index > 0)
  959. addattr32 (&req.n, sizeof req, RTA_OIF, index);
  960.     }
  961.   /* Destination netlink address. */
  962.   memset (&snl, 0, sizeof snl);
  963.   snl.nl_family = AF_NETLINK;
  964.   /* Talk to netlink socket. */
  965.   ret = netlink_talk (&req.n, &netlink);
  966.   if (ret < 0)
  967.     return -1;
  968.   return 0;
  969. }
  970. /* Routing table change via netlink interface. */
  971. int
  972. netlink_route_multipath (int cmd, struct prefix *p, struct rib *rib,
  973.  int family)
  974. {
  975.   int bytelen;
  976.   struct sockaddr_nl snl;
  977.   struct nexthop *nexthop = NULL;
  978.   int nexthop_num = 0;
  979.   struct nlsock *nl;
  980.   int discard;
  981.   struct 
  982.   {
  983.     struct nlmsghdr n;
  984.     struct rtmsg r;
  985.     char buf[1024];
  986.   } req;
  987.   memset (&req, 0, sizeof req);
  988.   bytelen = (family == AF_INET ? 4 : 16);
  989.   req.n.nlmsg_len = NLMSG_LENGTH (sizeof (struct rtmsg));
  990.   req.n.nlmsg_flags = NLM_F_CREATE | NLM_F_REQUEST;
  991.   req.n.nlmsg_type = cmd;
  992.   req.r.rtm_family = family;
  993.   req.r.rtm_table = rib->table;
  994.   req.r.rtm_dst_len = p->prefixlen;
  995. #ifdef RTM_F_EQUALIZE
  996.   req.r.rtm_flags |= RTM_F_EQUALIZE;
  997. #endif /* RTM_F_EQUALIZE */
  998.   if (rib->flags & ZEBRA_FLAG_BLACKHOLE)
  999.     discard = 1;
  1000.   else
  1001.     discard = 0;
  1002.   if (cmd == RTM_NEWROUTE) 
  1003.     {
  1004.       req.r.rtm_protocol = RTPROT_ZEBRA;
  1005.       req.r.rtm_scope = RT_SCOPE_UNIVERSE;
  1006.       if (discard)
  1007. req.r.rtm_type = RTN_BLACKHOLE;
  1008.       else
  1009. req.r.rtm_type = RTN_UNICAST;
  1010.     }
  1011.   addattr_l (&req.n, sizeof req, RTA_DST, &p->u.prefix, bytelen);
  1012.   /* Metric. */
  1013.   addattr32 (&req.n, sizeof req, RTA_PRIORITY, rib->metric);
  1014.   if (discard)
  1015.     {
  1016.       if (cmd == RTM_NEWROUTE)
  1017. for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  1018.   SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  1019.       goto skip;
  1020.     }
  1021.   /* Multipath case. */
  1022.   if (rib->nexthop_active_num == 1 || MULTIPATH_NUM == 1)
  1023.     {
  1024.       for (nexthop = rib->nexthop; nexthop; nexthop = nexthop->next)
  1025. {
  1026.   if ((cmd == RTM_NEWROUTE 
  1027.        && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1028.       || (cmd == RTM_DELROUTE
  1029.   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
  1030.     {
  1031.       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1032. {
  1033.   if (nexthop->rtype == NEXTHOP_TYPE_IPV4 
  1034.       || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
  1035.     addattr_l (&req.n, sizeof req, RTA_GATEWAY,
  1036.        &nexthop->rgate.ipv4, bytelen);
  1037. #ifdef HAVE_IPV6
  1038.   if (nexthop->rtype == NEXTHOP_TYPE_IPV6 
  1039.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX 
  1040.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
  1041.     addattr_l (&req.n, sizeof req, RTA_GATEWAY,
  1042.        &nexthop->rgate.ipv6, bytelen);
  1043. #endif /* HAVE_IPV6 */
  1044.   if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
  1045.       || nexthop->rtype == NEXTHOP_TYPE_IFNAME
  1046.       || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
  1047.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
  1048.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
  1049.     addattr32 (&req.n, sizeof req, RTA_OIF,
  1050.        nexthop->rifindex);
  1051. }
  1052.       else
  1053. {
  1054.   if (nexthop->type == NEXTHOP_TYPE_IPV4 
  1055.       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  1056.     addattr_l (&req.n, sizeof req, RTA_GATEWAY,
  1057.        &nexthop->gate.ipv4, bytelen);
  1058. #ifdef HAVE_IPV6
  1059.   if (nexthop->type == NEXTHOP_TYPE_IPV6 
  1060.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  1061.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  1062.     addattr_l (&req.n, sizeof req, RTA_GATEWAY,
  1063.        &nexthop->gate.ipv6, bytelen);
  1064. #endif /* HAVE_IPV6 */
  1065.   if (nexthop->type == NEXTHOP_TYPE_IFINDEX
  1066.       || nexthop->type == NEXTHOP_TYPE_IFNAME
  1067.       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
  1068.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX
  1069.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME)
  1070.     addattr32 (&req.n, sizeof req, RTA_OIF, nexthop->ifindex);
  1071. }
  1072.       if (cmd == RTM_NEWROUTE)
  1073. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  1074.       nexthop_num++;
  1075.       break;
  1076.     }
  1077. }
  1078.     }
  1079.   else
  1080.     {
  1081.       char buf[1024];
  1082.       struct rtattr *rta = (void *) buf;
  1083.       struct rtnexthop *rtnh;
  1084.       rta->rta_type = RTA_MULTIPATH;
  1085.       rta->rta_len = RTA_LENGTH(0);
  1086.       rtnh = RTA_DATA(rta);
  1087.       nexthop_num = 0;
  1088.       for (nexthop = rib->nexthop;
  1089.    nexthop && (MULTIPATH_NUM == 0 || nexthop_num < MULTIPATH_NUM);
  1090.    nexthop = nexthop->next)
  1091. {
  1092.   if ((cmd == RTM_NEWROUTE 
  1093.        && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_ACTIVE))
  1094.       || (cmd == RTM_DELROUTE
  1095.   && CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB)))
  1096.     {
  1097.       nexthop_num++;
  1098.       rtnh->rtnh_len = sizeof (*rtnh);
  1099.       rtnh->rtnh_flags = 0;
  1100.       rtnh->rtnh_hops = 0;
  1101.       rta->rta_len += rtnh->rtnh_len;
  1102.       if (CHECK_FLAG (nexthop->flags, NEXTHOP_FLAG_RECURSIVE))
  1103. {
  1104.   if (nexthop->rtype == NEXTHOP_TYPE_IPV4
  1105.       || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX)
  1106.     {
  1107.       rta_addattr_l (rta, 4096, RTA_GATEWAY,
  1108.      &nexthop->rgate.ipv4, bytelen);
  1109.       rtnh->rtnh_len += sizeof (struct rtattr) + 4;
  1110.     }
  1111. #ifdef HAVE_IPV6
  1112.   if (nexthop->rtype == NEXTHOP_TYPE_IPV6
  1113.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME
  1114.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX)
  1115.     rta_addattr_l (rta, 4096, RTA_GATEWAY,
  1116.    &nexthop->rgate.ipv6, bytelen);
  1117. #endif /* HAVE_IPV6 */
  1118.   /* ifindex */
  1119.   if (nexthop->rtype == NEXTHOP_TYPE_IFINDEX
  1120.       || nexthop->rtype == NEXTHOP_TYPE_IFNAME
  1121.       || nexthop->rtype == NEXTHOP_TYPE_IPV4_IFINDEX
  1122.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFINDEX
  1123.       || nexthop->rtype == NEXTHOP_TYPE_IPV6_IFNAME)
  1124.     rtnh->rtnh_ifindex = nexthop->rifindex;
  1125.   else
  1126.     rtnh->rtnh_ifindex = 0;
  1127. }
  1128.       else
  1129. {
  1130.   if (nexthop->type == NEXTHOP_TYPE_IPV4
  1131.       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX)
  1132.     {
  1133.       rta_addattr_l (rta, 4096, RTA_GATEWAY,
  1134.      &nexthop->gate.ipv4, bytelen);
  1135.       rtnh->rtnh_len += sizeof (struct rtattr) + 4;
  1136.     }
  1137. #ifdef HAVE_IPV6
  1138.   if (nexthop->type == NEXTHOP_TYPE_IPV6
  1139.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  1140.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  1141.     rta_addattr_l (rta, 4096, RTA_GATEWAY,
  1142.    &nexthop->gate.ipv6, bytelen);
  1143. #endif /* HAVE_IPV6 */
  1144.   /* ifindex */
  1145.   if (nexthop->type == NEXTHOP_TYPE_IFINDEX
  1146.       || nexthop->type == NEXTHOP_TYPE_IFNAME
  1147.       || nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX
  1148.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFNAME
  1149.       || nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX)
  1150.     rtnh->rtnh_ifindex = nexthop->ifindex;
  1151.   else
  1152.     rtnh->rtnh_ifindex = 0;
  1153. }
  1154.       rtnh = RTNH_NEXT(rtnh);
  1155.       if (cmd == RTM_NEWROUTE)
  1156. SET_FLAG (nexthop->flags, NEXTHOP_FLAG_FIB);
  1157.     }
  1158. }
  1159.       if (rta->rta_len > RTA_LENGTH (0))
  1160. addattr_l (&req.n, 1024, RTA_MULTIPATH, RTA_DATA(rta),
  1161.    RTA_PAYLOAD(rta));
  1162.     }
  1163.   /* If there is no useful nexthop then return. */
  1164.   if (nexthop_num == 0)
  1165.     {
  1166.       if (IS_ZEBRA_DEBUG_KERNEL)
  1167. zlog_info ("netlink_route_multipath(): No useful nexthop.");
  1168.       return 0;
  1169.     }
  1170.  skip:
  1171.   /* Destination netlink address. */
  1172.   memset (&snl, 0, sizeof snl);
  1173.   snl.nl_family = AF_NETLINK;
  1174.   if (family == AF_INET)
  1175.     nl = &netlink_cmd;
  1176.   else
  1177.     nl = &netlink;
  1178.   /* Talk to netlink socket. */
  1179.   return netlink_talk (&req.n, nl);
  1180. }
  1181. int
  1182. kernel_add_ipv4 (struct prefix *p, struct rib *rib)
  1183. {
  1184.   return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET);
  1185. }
  1186. int
  1187. kernel_delete_ipv4 (struct prefix *p, struct rib *rib)
  1188. {
  1189.   return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET);
  1190. }
  1191. #ifdef HAVE_IPV6
  1192. int
  1193. kernel_add_ipv6 (struct prefix *p, struct rib *rib)
  1194. {
  1195.   return netlink_route_multipath (RTM_NEWROUTE, p, rib, AF_INET6);
  1196. }
  1197. int
  1198. kernel_delete_ipv6 (struct prefix *p, struct rib *rib)
  1199. {
  1200.   return netlink_route_multipath (RTM_DELROUTE, p, rib, AF_INET6);
  1201. }
  1202. /* Delete IPv6 route from the kernel. */
  1203. int
  1204. kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
  1205. int index, int flags, int table)
  1206. {
  1207.   return netlink_route (RTM_DELROUTE, AF_INET6, &dest->prefix, dest->prefixlen,
  1208. gate, index, flags, table);
  1209. }
  1210. #endif /* HAVE_IPV6 */
  1211. /* Interface address modification. */
  1212. int
  1213. netlink_address (int cmd, int family, struct interface *ifp,
  1214.  struct connected *ifc)
  1215. {
  1216.   int bytelen;
  1217.   struct prefix *p;
  1218.   struct 
  1219.   {
  1220.     struct nlmsghdr n;
  1221.     struct ifaddrmsg ifa;
  1222.     char buf[1024];
  1223.   } req;
  1224.   p = ifc->address;
  1225.   memset (&req, 0, sizeof req);
  1226.   bytelen = (family == AF_INET ? 4 : 16);
  1227.   req.n.nlmsg_len = NLMSG_LENGTH (sizeof(struct ifaddrmsg));
  1228.   req.n.nlmsg_flags = NLM_F_REQUEST;
  1229.   req.n.nlmsg_type = cmd;
  1230.   req.ifa.ifa_family = family;
  1231.   req.ifa.ifa_index = ifp->ifindex;
  1232.   req.ifa.ifa_prefixlen = p->prefixlen;
  1233.   addattr_l (&req.n, sizeof req, IFA_LOCAL, &p->u.prefix, bytelen);
  1234.   if (family == AF_INET && cmd == RTM_NEWADDR)
  1235.     {
  1236.       if (if_is_broadcast (ifp) && ifc->destination)
  1237. {
  1238.   p = ifc->destination;
  1239.   addattr_l(&req.n, sizeof req, IFA_BROADCAST, &p->u.prefix, bytelen);
  1240. }
  1241.     }
  1242.   if (CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
  1243.     SET_FLAG (req.ifa.ifa_flags, IFA_F_SECONDARY);
  1244.     
  1245.   if (ifc->label)
  1246.     addattr_l (&req.n, sizeof req, IFA_LABEL, ifc->label,
  1247.        strlen (ifc->label) + 1);
  1248.   return netlink_talk (&req.n, &netlink_cmd);
  1249. }
  1250. int
  1251. kernel_address_add_ipv4 (struct interface *ifp, struct connected *ifc)
  1252. {
  1253.   return netlink_address (RTM_NEWADDR, AF_INET, ifp, ifc);
  1254. }
  1255. int
  1256. kernel_address_delete_ipv4 (struct interface *ifp, struct connected *ifc)
  1257. {
  1258.   return netlink_address (RTM_DELADDR, AF_INET, ifp, ifc);
  1259. }
  1260. #include "thread.h"
  1261. extern struct thread_master *master;
  1262. /* Kernel route reflection. */
  1263. int
  1264. kernel_read (struct thread *thread)
  1265. {
  1266.   int ret;
  1267.   int sock;
  1268.   sock = THREAD_FD (thread);
  1269.   ret = netlink_parse_info (netlink_information_fetch, &netlink);
  1270.   thread_add_read (master, kernel_read, NULL, netlink.sock);
  1271.   return 0;
  1272. }
  1273. /* Exported interface function.  This function simply calls
  1274.    netlink_socket (). */
  1275. void
  1276. kernel_init ()
  1277. {
  1278.   unsigned long groups;
  1279.   groups = RTMGRP_LINK|RTMGRP_IPV4_ROUTE|RTMGRP_IPV4_IFADDR;
  1280. #ifdef HAVE_IPV6
  1281.   groups |= RTMGRP_IPV6_ROUTE|RTMGRP_IPV6_IFADDR;
  1282. #endif /* HAVE_IPV6 */
  1283.   netlink_socket (&netlink, groups);
  1284.   netlink_socket (&netlink_cmd, 0);
  1285.   /* Register kernel socket. */
  1286.   if (netlink.sock > 0)
  1287.     thread_add_read (master, kernel_read, NULL, netlink.sock);
  1288. }